Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
authorptitSeb <sebastien.chev@gmail.com>
Tue, 24 Sep 2013 19:59:33 +0000 (21:59 +0200)
committerptitSeb <sebastien.chev@gmail.com>
Tue, 24 Sep 2013 19:59:33 +0000 (21:59 +0200)
128 files changed:
source/mupen64plus-video-arachnoid/.hg_archival.txt [new file with mode: 0644]
source/mupen64plus-video-arachnoid/.hgignore [new file with mode: 0644]
source/mupen64plus-video-arachnoid/.hgtags [new file with mode: 0644]
source/mupen64plus-video-arachnoid/COPYING [new file with mode: 0644]
source/mupen64plus-video-arachnoid/README [new file with mode: 0644]
source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln [new file with mode: 0755]
source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj [new file with mode: 0755]
source/mupen64plus-video-arachnoid/projects/unix/Makefile [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Assembler/assembler.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/DisplayListParser.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ExtensionChecker.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/FogManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/FogManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/GBI/GBI.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Memory.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/Memory.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/N64Games.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/OpenGL.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/OpenGLManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RDP/RDP.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSP.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RomDetector.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/RomDetector.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/UCodeDefs.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/VI.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/VI.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/Config.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/Config.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/ConfigMap.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/StringFunctions.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/config/StringValue.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/log/Logger.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/log/Logger.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/m64p.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/main.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/math/MathLib.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/math/Matrix4.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/eglport.c [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/renderer/eglport.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/TextureCache.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode3.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode8.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/utils/MemoryLeakDetector.h [new file with mode: 0755]
source/mupen64plus-video-arachnoid/src/video_api_export.ver [new file with mode: 0644]

diff --git a/source/mupen64plus-video-arachnoid/.hg_archival.txt b/source/mupen64plus-video-arachnoid/.hg_archival.txt
new file mode 100644 (file)
index 0000000..76878a8
--- /dev/null
@@ -0,0 +1,5 @@
+repo: 976896f303442924a04de6fb0725b98269a9bbe3
+node: d88e66b6a15a517db588fdb5eabf1ad4b7de0056
+branch: default
+latesttag: 2.0.0
+latesttagdistance: 1
diff --git a/source/mupen64plus-video-arachnoid/.hgignore b/source/mupen64plus-video-arachnoid/.hgignore
new file mode 100644 (file)
index 0000000..8f52e27
--- /dev/null
@@ -0,0 +1,4 @@
+syntax: regexp
+
+^projects/unix/_obj/
+^projects/unix/mupen64plus-video-arachnoid.so$
diff --git a/source/mupen64plus-video-arachnoid/.hgtags b/source/mupen64plus-video-arachnoid/.hgtags
new file mode 100644 (file)
index 0000000..609eac5
--- /dev/null
@@ -0,0 +1,3 @@
+7713c313dc69e551761636645e9ad94d2e3a93c6 1.99.4
+567e98c190507a3818bf851ecb2b5de600de7896 1.99.5
+2e14d1a541b7a6c2a09c4c6173370ca336f4c001 2.0.0
diff --git a/source/mupen64plus-video-arachnoid/COPYING b/source/mupen64plus-video-arachnoid/COPYING
new file mode 100644 (file)
index 0000000..d511905
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/source/mupen64plus-video-arachnoid/README b/source/mupen64plus-video-arachnoid/README
new file mode 100644 (file)
index 0000000..49333a7
--- /dev/null
@@ -0,0 +1,8 @@
+Arachnoid Graphics Plugin for Mupen64Plus
+http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+
+Derived from the Project64/1964 version of Arachnoid, available from:
+http://sourceforge.net/projects/arachnoid/
+
+To build, enter the projects/unix directory and type "make".
+To build a debugging version, use "make DEBUG=1" instead.
diff --git a/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln
new file mode 100755 (executable)
index 0000000..3cfc3cc
--- /dev/null
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsPlugin", "GraphicsPlugin.vcproj", "{6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Win32 = Debug|Win32
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Debug|Win32.ActiveCfg = Debug|Win32
+               {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Debug|Win32.Build.0 = Debug|Win32
+               {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Release|Win32.ActiveCfg = Release|Win32
+               {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Release|Win32.Build.0 = Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj
new file mode 100755 (executable)
index 0000000..e63d7dc
--- /dev/null
@@ -0,0 +1,922 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="GraphicsPlugin"
+       ProjectGUID="{6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}"
+       RootNamespace="GraphicsPlugin"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="131072"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)"
+                       IntermediateDirectory="obj/Debug"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                               CommandLine=""
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="../../../mupen64plus-core/src/api; ../../src; ../../src/hash; ../../src/ucodes; ../../src/gbi; ../../src/rdp; ../../src/utils; ../../src/log; ../../src/rsp; ../../src/framebuffer; ../../src/math; ../../src/renderer; ../../src/assembler; ../../src/texture; ../../src/config; ../../src/combiner;"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;GRAPHICSPLUGIN_EXPORTS"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="opengl32.lib"
+                               OutputFile="mupen64plus-video-arachnoid.dll"
+                               LinkIncremental="2"
+                               GenerateDebugInformation="true"
+                               ProgramDatabaseFile="$(OutDir)/GraphicsPlugin.pdb"
+                               SubSystem="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               ImportLibrary="$(OutDir)/GraphicsPlugin.lib"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                               CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)&quot;"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)"
+                       IntermediateDirectory="obj/Release"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                               CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)&quot;&#x0D;&#x0A;"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalIncludeDirectories="../../../mupen64plus-core/src/api; ../../src; ../../src/hash; ../../src/ucodes; ../../src/gbi; ../../src/rdp; ../../src/utils; ../../src/log; ../../src/rsp; ../../src/framebuffer; ../../src/math; ../../src/renderer; ../../src/assembler; ../../src/texture; ../../src/config; ../../src/combiner;"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;GRAPHICSPLUGIN_EXPORTS"
+                               RuntimeLibrary="0"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="opengl32.lib"
+                               OutputFile="mupen64plus-video-arachnoid.dll"
+                               LinkIncremental="1"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               RandomizedBaseAddress="1"
+                               DataExecutionPrevention="0"
+                               ImportLibrary="$(OutDir)/GraphicsPlugin.lib"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                               CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)&quot;"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source"
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\..\src\m64p.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\src\main.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories="src/log; src/utils;"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <Filter
+                               Name="Utils"
+                               >
+                               <Filter
+                                       Name="Memory Leak Detector"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\utils\MemoryLeakDetector.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="Log"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\log\Logger.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\log\Logger.h"
+                                               >
+                                       </File>
+                               </Filter>
+                       </Filter>
+                       <Filter
+                               Name="Config"
+                               >
+                               <File
+                                       RelativePath="..\..\src\config\Config.cpp"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\src\config\Config.h"
+                                       >
+                               </File>
+                               <Filter
+                                       Name="File"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\config\StringValue.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="Helper Functions"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\config\StringFunctions.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\config\StringFunctions.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="ConfigMap"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\config\ConfigMap.h"
+                                               >
+                                       </File>
+                               </Filter>
+                       </Filter>
+                       <Filter
+                               Name="GraphicsPlugin"
+                               >
+                               <File
+                                       RelativePath="..\..\src\GraphicsPlugin.cpp"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\src\GraphicsPlugin.h"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\src\osal_dynamiclib.h"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\..\src\osal_dynamiclib_win32.cpp"
+                                       >
+                               </File>
+                               <Filter
+                                       Name="OpenGL"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\OpenGL.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="OpenGL Manager"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\OpenGLManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\OpenGLManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="OpenGL Renderer"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\renderer\OpenGLRenderer.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\renderer\OpenGLRenderer.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="Frame Buffer"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\framebuffer\FrameBuffer.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\framebuffer\FrameBuffer.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="OpenGL 2D Renderer"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\renderer\OpenGL2DRenderer.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\renderer\OpenGL2DRenderer.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="Fog"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\FogManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\FogManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="OpenGL Extensions"
+                                               >
+                                               <Filter
+                                                       Name="MultiTexturing Extension"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\MultiTexturingExt.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\MultiTexturingExt.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="ExtensionChecker"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\ExtensionChecker.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\ExtensionChecker.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="Secondary Color Extension"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\SecondaryColorExt.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\SecondaryColorExt.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="Memory"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\Memory.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\Memory.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="Math"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\math\MathLib.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="Matrix"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\math\Matrix4.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\math\Matrix4.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="Texture"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\texture\CachedTexture.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\texture\CachedTexture.h"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\texture\TextureCache.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\texture\TextureCache.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="Image Format Selector"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\texture\ImageFormatSelector.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\texture\ImageFormatSelector.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="CRC"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\hash\CRCCalculator.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\hash\CRCCalculator.h"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\hash\CRCCalculator2.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\hash\CRCCalculator2.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="TextureLoader"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\texture\TextureLoader.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\texture\TextureLoader.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="DisplayListParser"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\DisplayListParser.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\DisplayListParser.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="VI - Video Interface"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\VI.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\VI.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="UCodes"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\UCodeDefs.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="UCode Selection"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCodeIdentificationData.h"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCodeSelector.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCodeSelector.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode0 - F3D"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode0.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode0.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode1 - F3DEX"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode1.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode1.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode2 - Golden Eye"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode2.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode2.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode3 - S2DEX2"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode3.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode3.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode4 - Wave Race 64"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode4.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode4.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode5 - F3DEX2"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode5.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode5.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode6 - Diddy Kong Racing"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode6.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode6.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode7 - Yoshi&apos;s Stroy"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode7.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode7.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode8 - S2DEX"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode8.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode8.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode9 - Perfect Dark"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode9.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode9.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode10 - Conker "
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode10.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\ucodes\UCode10.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode11"
+                                               >
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode12"
+                                               >
+                                       </Filter>
+                                       <Filter
+                                               Name="UCode13"
+                                               >
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="GBI - Graphic Binary Interface"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\Gbi\GBI.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\Gbi\GBI.h"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\Gbi\GBIDefs.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="RSP - Reality Signal Processor"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\Rsp\RSP.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\Rsp\RSP.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="RSP Matrix Manager"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPMatrixManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPMatrixManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="RSP Vertex Manager"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPVertexManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPVertexManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="RSP Light Manager"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPLightManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Rsp\RSPLightManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="Misc"
+                                       >
+                                       <Filter
+                                               Name="Assembler"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Assembler\assembler.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="Combiner"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\Combiner\CombinerStructs.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="Managers"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Combiner\AdvancedCombinerManager.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Combiner\AdvancedCombinerManager.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                                       <Filter
+                                               Name="Combiners"
+                                               >
+                                               <Filter
+                                                       Name="Base"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerBase.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerBase.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="Advanced"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\AdvancedTexEnvCombiner.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\AdvancedTexEnvCombiner.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="Simple"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\SimpleTexEnvCombiner.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\SimpleTexEnvCombiner.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="Dummy"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\DummyCombiner.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\DummyCombiner.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                       </Filter>
+                                       <Filter
+                                               Name="Helpers"
+                                               >
+                                               <Filter
+                                                       Name="Stage Merger"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerStageMerger.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerStageMerger.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                               <Filter
+                                                       Name="Stage Creator"
+                                                       >
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerStageCreator.cpp"
+                                                               >
+                                                       </File>
+                                                       <File
+                                                               RelativePath="..\..\src\Combiner\CombinerStageCreator.h"
+                                                               >
+                                                       </File>
+                                               </Filter>
+                                       </Filter>
+                                       <Filter
+                                               Name="Cache"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Combiner\CombinerCache.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Combiner\CombinerCache.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                               <Filter
+                                       Name="RomDetector"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\N64Games.h"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\RomDetector.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\RomDetector.h"
+                                               >
+                                       </File>
+                               </Filter>
+                               <Filter
+                                       Name="RDP - Reality Drawing Processor"
+                                       >
+                                       <File
+                                               RelativePath="..\..\src\Rdp\RDP.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\..\src\Rdp\RDP.h"
+                                               >
+                                       </File>
+                                       <Filter
+                                               Name="RDP Instructions"
+                                               >
+                                               <File
+                                                       RelativePath="..\..\src\Rdp\RDPInstructions.cpp"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Rdp\RDPInstructions.h"
+                                                       >
+                                               </File>
+                                               <File
+                                                       RelativePath="..\..\src\Rdp\RDPUCodeStructs.h"
+                                                       >
+                                               </File>
+                                       </Filter>
+                               </Filter>
+                       </Filter>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/source/mupen64plus-video-arachnoid/projects/unix/Makefile b/source/mupen64plus-video-arachnoid/projects/unix/Makefile
new file mode 100755 (executable)
index 0000000..a12ef44
--- /dev/null
@@ -0,0 +1,406 @@
+#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+# *   Arachnoid - Makefile                                                  *
+# *   http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/            *
+# *   Copyright (C) 2009 Richard42, Jon Ring                                *
+# *                                                                         *
+# *   This program is free software; you can redistribute it and/or modify  *
+# *   it under the terms of the GNU General Public License as published by  *
+# *   the Free Software Foundation; either version 2 of the License, or     *
+# *   (at your option) any later version.                                   *
+# *                                                                         *
+# *   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.,                                       *
+# *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+# Makefile for mupen64plus-video-arachnoid
+
+# detect operation system
+UNAME ?= $(shell uname -s)
+ifeq ("$(UNAME)","Linux")
+  OS = LINUX
+  SO_EXTENSION = so
+  SHARED = -shared
+endif
+ifeq ("$(UNAME)","linux")
+  OS = LINUX
+  SO_EXTENSION = so
+  SHARED = -shared
+endif
+ifneq ("$(filter GNU hurd,$(UNAME))","")
+  OS = LINUX
+  SO_EXTENSION = so
+  SHARED = -shared
+endif
+ifeq ("$(UNAME)","Darwin")
+  OS = OSX
+  LDLIBS += -liconv -lpng
+  SO_EXTENSION = dylib
+  SHARED = -bundle
+endif
+ifeq ("$(UNAME)","FreeBSD")
+  OS = FREEBSD
+  SO_EXTENSION = so
+  SHARED = -shared
+endif
+ifeq ("$(UNAME)","OpenBSD")
+  OS = FREEBSD
+  SO_EXTENSION = so
+  SHARED = -shared
+  $(warning OS type "$(UNAME)" not officially supported.')
+endif
+ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","")
+  OS = LINUX
+  SO_EXTENSION = so
+  SHARED = -shared
+endif
+ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW")
+  OS = MINGW
+  SO_EXTENSION = dll
+  SHARED = -shared
+  PIC = 0
+endif
+ifeq ("$(OS)","NONE")
+  $(error OS type "$(UNAME)" not supported.  Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
+
+# detect system architecture
+HOST_CPU ?= $(shell uname -m)
+NO_ASM ?= 1
+ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
+  CPU := X86
+  ifeq ("$(BITS)", "32")
+    ARCH_DETECTED := 64BITS_32
+  else
+    ARCH_DETECTED := 64BITS
+    PIC ?= 1
+  endif
+endif
+ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
+  CPU := X86
+  ARCH_DETECTED := 32BITS
+endif
+ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","")
+  CPU := PPC
+  ARCH_DETECTED := 32BITS
+  BIG_ENDIAN := 1
+  PIC ?= 1
+  $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
+  CPU := PPC
+  ARCH_DETECTED := 64BITS
+  BIG_ENDIAN := 1
+  PIC ?= 1
+  $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter arm%,$(HOST_CPU))","")
+  ifeq ("$(filter arm%b,$(HOST_CPU))","")
+    CPU := ARM
+    ARCH_DETECTED := 32BITS
+    PIC ?= 1
+    CFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a8 -fsigned-char -ffast-math -fpermissive
+    CFLAGS += -DHAVE_GLES
+    $(warning Architecture "$(HOST_CPU)" not officially supported.')
+  endif
+endif
+
+# base CFLAGS, LDLIBS, and LDFLAGS
+OPTFLAGS ?= -O3
+WARNFLAGS ?= -Wall
+CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src \
+                -I../../src/hash -I../../src/ucodes -I../../src/GBI -I../../src/RDP -I../../src/utils \
+                -I../../src/log -I../../src/RSP -I../../src/framebuffer -I../../src/math -I../../src/renderer \
+                -I../../src/Assembler -I../../src/texture -I../../src/config -I../../src/Combiner 
+CXXFLAGS += -fvisibility-inlines-hidden
+LDFLAGS += $(SHARED)
+
+# On OS X, add a few extra flags to elegantly support cross-compilation and backward
+# compatibility (and also the flags to link against OpenGL)
+ifeq ($(OS), OSX)
+  # Select the proper SDK
+  # Also, SDKs are stored in a different location since XCode 4.3
+  OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .)
+  OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .)
+  OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .)
+  OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`")
+  ifeq ($(OSX_XCODEGE43), 11)
+    OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
+  else
+    OSX_SYSROOT := /Developer/SDKs
+  endif
+
+  ifeq ($(CPU), X86)
+    ifeq ($(ARCH_DETECTED), 64BITS)
+      CFLAGS += -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+      LDFLAGS += -bundle
+    else
+      CFLAGS += -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+      LDFLAGS += -bundle
+    endif
+  endif
+else
+  # search for OpenGL libraries
+  ifeq ($(OS), OSX)
+    GL_LDLIBS = -framework OpenGL
+  endif
+  ifeq ($(OS), MINGW)
+    GL_LDLIBS = -lopengl32
+  endif
+
+  ifeq ($(origin GL_CFLAGS) $(origin GL_LDLIBS), undefined undefined)
+    ifeq ($(origin PKG_CONFIG), undefined)
+      PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+      ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
+        $(error $(PKG_CONFIG) not found)
+      endif
+    endif
+
+    ifeq ($(shell $(PKG_CONFIG) --modversion gl 2>/dev/null),)
+      $(error No OpenGL development libraries found!)
+    endif
+    #GL_CFLAGS += $(shell $(PKG_CONFIG) --cflags gl)
+    #GL_LDLIBS +=  $(shell $(PKG_CONFIG) --libs gl)
+    GL_CFLAGS += $(shell sdl-config --cflags)
+    GL_LDLIBS += $(shell sdl-config --libs)
+    GL_CFLAGS += -I/mnt/utmp/codeblocks/usr/include/GLES
+       GL_LDLIBS += -lGLES_CM -lEGL -lrt
+  endif
+  CFLAGS += $(GL_CFLAGS)
+  LDLIBS += $(GL_LDLIBS)
+
+  CFLAGS += -pthread
+endif
+ifeq ($(OS), LINUX)
+  LDLIBS += -ldl 
+endif
+ifeq ($(OS), FREEBSD)
+  LDLIBS += -lc
+endif
+
+
+# Since we are building a shared library, we must compile with -fPIC on some architectures
+# On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch
+ifeq ($(PIC), 1)
+  CFLAGS += -fPIC
+else
+  CFLAGS += -fno-PIC
+endif
+
+ifeq ($(BIG_ENDIAN), 1)
+  CFLAGS += -DM64P_BIG_ENDIAN
+endif
+
+# set mupen64plus core API header path
+ifneq ("$(APIDIR)","")
+  CFLAGS += "-I$(APIDIR)"
+else
+  TRYDIR = ../../../mupen64plus-core/src/api
+  ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+    CFLAGS += -I$(TRYDIR)
+  else
+    TRYDIR = /usr/local/include/mupen64plus
+    ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+      CFLAGS += -I$(TRYDIR)
+    else
+      TRYDIR = /usr/include/mupen64plus
+      ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+        CFLAGS += -I$(TRYDIR)
+      endif
+    endif
+  endif
+endif
+
+# set special flags per-system
+ifeq ($(OS), LINUX)
+  # only export api symbols
+  LDFLAGS += -Wl,-version-script,$(SRCDIR)/video_api_export.ver
+endif
+ifneq ($(OS), FREEBSD)
+  ifeq ($(CPU), X86)
+    # tweak flags for 32-bit build on 64-bit system
+    ifeq ($(ARCH_DETECTED), 64BITS_32)
+      CFLAGS += -m32
+      LDFLAGS += -Wl,-m,elf_i386
+    endif
+  endif
+else
+  ifeq ($(ARCH_DETECTED), 64BITS_32)
+    $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
+  endif
+endif
+
+# reduced compile output when running make without V=1
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+       Q_CC  = @echo '    CC  '$@;
+       Q_CXX = @echo '    CXX '$@;
+       Q_LD  = @echo '    LD  '$@;
+endif
+endif
+
+# set base program pointers and flags
+CC        = $(CROSS_COMPILE)gcc
+CXX       = $(CROSS_COMPILE)g++
+RM       ?= rm -f
+INSTALL  ?= install
+MKDIR ?= mkdir -p
+COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+COMPILE.cc = $(Q_CXX)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.o = $(Q_LD)$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+
+# set special flags for given Makefile parameters
+ifeq ($(DEBUG),1)
+  CFLAGS += -g
+  INSTALL_STRIP_FLAG ?= 
+else
+  INSTALL_STRIP_FLAG ?= -s
+endif
+
+# set installation options
+ifeq ($(PREFIX),)
+  PREFIX := /usr/local
+endif
+ifeq ($(SHAREDIR),)
+  SHAREDIR := $(PREFIX)/share/mupen64plus
+endif
+ifeq ($(LIBDIR),)
+  LIBDIR := $(PREFIX)/lib
+endif
+ifeq ($(PLUGINDIR),)
+  PLUGINDIR := $(LIBDIR)/mupen64plus
+endif
+
+
+SRCDIR = ../../src
+OBJDIR = _obj$(POSTFIX)
+
+# list of source files to compile
+SOURCE = \
+       $(SRCDIR)/main.cpp \
+       $(SRCDIR)/log/Logger.cpp \
+       $(SRCDIR)/config/Config.cpp \
+       $(SRCDIR)/config/StringFunctions.cpp \
+       $(SRCDIR)/GraphicsPlugin.cpp \
+       $(SRCDIR)/OpenGLManager.cpp \
+       $(SRCDIR)/renderer/OpenGLRenderer.cpp \
+       $(SRCDIR)/framebuffer/FrameBuffer.cpp \
+       $(SRCDIR)/FogManager.cpp \
+       $(SRCDIR)/MultiTexturingExt.cpp \
+       $(SRCDIR)/ExtensionChecker.cpp \
+       $(SRCDIR)/SecondaryColorExt.cpp \
+       $(SRCDIR)/Memory.cpp \
+       $(SRCDIR)/math/Matrix4.cpp \
+       $(SRCDIR)/texture/CachedTexture.cpp \
+       $(SRCDIR)/texture/TextureCache.cpp \
+       $(SRCDIR)/texture/ImageFormatSelector.cpp \
+       $(SRCDIR)/hash/CRCCalculator.cpp \
+       $(SRCDIR)/hash/CRCCalculator2.cpp \
+       $(SRCDIR)/texture/TextureLoader.cpp \
+       $(SRCDIR)/DisplayListParser.cpp \
+       $(SRCDIR)/VI.cpp \
+       $(SRCDIR)/ucodes/UCodeSelector.cpp \
+       $(SRCDIR)/ucodes/UCode0.cpp \
+       $(SRCDIR)/ucodes/UCode1.cpp \
+       $(SRCDIR)/ucodes/UCode2.cpp \
+       $(SRCDIR)/ucodes/UCode3.cpp \
+       $(SRCDIR)/ucodes/UCode4.cpp \
+       $(SRCDIR)/ucodes/UCode5.cpp \
+       $(SRCDIR)/ucodes/UCode6.cpp \
+       $(SRCDIR)/ucodes/UCode7.cpp \
+       $(SRCDIR)/ucodes/UCode8.cpp \
+       $(SRCDIR)/ucodes/UCode9.cpp \
+       $(SRCDIR)/ucodes/UCode10.cpp \
+       $(SRCDIR)/GBI/GBI.cpp \
+       $(SRCDIR)/RSP/RSP.cpp \
+       $(SRCDIR)/RSP/RSPMatrixManager.cpp \
+       $(SRCDIR)/RSP/RSPVertexManager.cpp \
+       $(SRCDIR)/RSP/RSPLightManager.cpp \
+       $(SRCDIR)/Combiner/AdvancedCombinerManager.cpp \
+       $(SRCDIR)/Combiner/CombinerBase.cpp \
+       $(SRCDIR)/Combiner/AdvancedTexEnvCombiner.cpp \
+       $(SRCDIR)/Combiner/SimpleTexEnvCombiner.cpp \
+       $(SRCDIR)/Combiner/DummyCombiner.cpp \
+       $(SRCDIR)/Combiner/CombinerStageMerger.cpp \
+       $(SRCDIR)/Combiner/CombinerStageCreator.cpp \
+       $(SRCDIR)/Combiner/CombinerCache.cpp \
+       $(SRCDIR)/RomDetector.cpp \
+       $(SRCDIR)/RDP/RDP.cpp \
+       $(SRCDIR)/RDP/RDPInstructions.cpp               \
+    $(SRCDIR)/renderer/eglport.cpp          \
+       $(SRCDIR)/renderer/OpenGL2DRenderer.cpp \
+
+ifeq ($(OS),MINGW)
+SOURCE += $(SRCDIR)/osal_dynamiclib_win32.cpp
+else
+SOURCE += $(SRCDIR)/osal_dynamiclib_unix.cpp
+endif
+
+
+# generate a list of object files build, make a temporary directory for them
+OBJECTS := $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SOURCE)))
+OBJDIRS = $(dir $(OBJECTS))
+$(shell $(MKDIR) $(OBJDIRS))
+
+# build targets
+
+TARGET = mupen64plus-video-arachnoid$(POSTFIX).$(SO_EXTENSION)
+targets:
+       @echo "Mupen64plus-video-arachnoid N64 Graphics plugin makefile. "
+       @echo "  Targets:"
+       @echo "    all           == Build Mupen64plus-video-arachnoid plugin"
+       @echo "    clean         == remove object files"
+       @echo "    rebuild       == clean and re-build all"
+       @echo "    install       == Install Mupen64Plus-video-arachnoid plugin"
+       @echo "    uninstall     == Uninstall Mupen64Plus-video-arachnoid plugin"
+       @echo "  Options:"
+       @echo "    BITS=32       == build 32-bit binaries on 64-bit machine"
+       @echo "    APIDIR=path   == path to find Mupen64Plus Core headers"
+       @echo "    OPTFLAGS=flag == compiler optimization (default: -O3 -flto)"
+       @echo "    WARNFLAGS=flag == compiler warning levels (default: -Wall)"
+       @echo "    PIC=(1|0)     == Force enable/disable of position independent code"
+       @echo "    POSTFIX=name  == String added to the name of the the build (default: '')"
+       @echo "  Install Options:"
+       @echo "    PREFIX=path   == install/uninstall prefix (default: /usr/local)"
+       @echo "    LIBDIR=path   == library prefix (default: PREFIX/lib)"
+       @echo "    PLUGINDIR=path == path to install plugin libraries (default: LIBDIR/mupen64plus)"
+       @echo "    DESTDIR=path  == path to prepend to all installation paths (only for packagers)"
+       @echo "  Debugging Options:"
+       @echo "    DEBUG=1       == add debugging symbols"
+       @echo "    V=1           == show verbose compiler output"
+
+all: $(TARGET)
+
+install: $(TARGET)
+       $(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
+       $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
+
+uninstall:
+       $(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
+
+
+clean:
+       $(RM) -r $(OBJDIR) $(TARGET)
+
+# build dependency files
+CFLAGS += -MD
+-include $(OBJECTS:.o=.d)
+
+CXXFLAGS += $(CFLAGS)
+
+# standard build rules
+$(OBJDIR)/%.o: $(SRCDIR)/%.c
+       $(COMPILE.c) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
+       $(COMPILE.cc) -o $@ $<
+
+$(TARGET): $(OBJECTS)
+       $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+.PHONY: all clean install uninstall targets
diff --git a/source/mupen64plus-video-arachnoid/src/Assembler/assembler.h b/source/mupen64plus-video-arachnoid/src/Assembler/assembler.h
new file mode 100755 (executable)
index 0000000..783eb2c
--- /dev/null
@@ -0,0 +1,384 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef ASSEMBLER_H_
+#define ASSEMBLER_H_
+
+#ifndef WIN32
+#include <cstring>
+#endif
+// Swap bytes from 80 37 12 40
+// to              40 12 37 80
+// dwLen must be a multiple of 4
+inline void swapRomHeaderBytes(void *v, unsigned int dwLen)
+{
+    int *b = (int*)v;
+    dwLen /= 4;
+    for (unsigned int i = 0; i < dwLen; ++i)
+    {
+        int tmp = b[i];
+        b[i] = ((tmp & 0xff000000) >> 24) | ((tmp & 0x00ff0000) >>  8) |               \
+               ((tmp & 0x0000ff00) <<  8) | ((tmp & 0x000000ff) << 24);
+    }
+}
+
+
+inline unsigned short swapword( unsigned short value )
+{
+    return (value >> 8) | (value << 8);
+}
+
+inline void UnswapCopy( void *src, void *dest, unsigned int numBytes )
+{
+#ifdef WIN32_ASM
+    __asm
+    {
+        mov        ecx, 0
+        mov        esi, dword ptr [src]
+        mov        edi, dword ptr [dest]
+
+        mov        ebx, esi
+        and        ebx, 3            // ebx = number of leading bytes
+
+        cmp        ebx, 0
+         jz        StartDWordLoop
+        neg        ebx
+        add        ebx, 4
+
+        cmp        ebx, [numBytes]
+        jle        NotGreater
+        mov        ebx, [numBytes]
+NotGreater:
+        mov        ecx, ebx
+        xor        esi, 3
+LeadingLoop:                // Copies leading bytes, in reverse order (un-swaps)
+        mov        al, byte ptr [esi]
+        mov        byte ptr [edi], al
+        sub        esi, 1
+        add        edi, 1
+        loop       LeadingLoop
+        add        esi, 5
+
+StartDWordLoop:
+        mov        ecx, dword ptr [numBytes]
+        sub        ecx, ebx        // Don't copy what's already been copied
+
+        mov        ebx, ecx
+        and        ebx, 3
+//        add        ecx, 3            // Round up to nearest dword
+        shr        ecx, 2
+
+        cmp        ecx, 0            // If there's nothing to do, don't do it
+        jle        StartTrailingLoop
+
+        // Copies from source to destination, bswap-ing first
+DWordLoop:
+        mov        eax, dword ptr [esi]
+        bswap      eax
+        mov        dword ptr [edi], eax
+        add        esi, 4
+        add        edi, 4
+        loop    DWordLoop
+StartTrailingLoop:
+        cmp        ebx, 0
+        jz         Done
+        mov        ecx, ebx
+        xor        esi, 3
+
+TrailingLoop:
+        mov        al, byte ptr [esi]
+        mov        byte ptr [edi], al
+        sub        esi, 1
+        add        edi, 1
+        loop       TrailingLoop
+Done:
+    }
+#else
+
+    long long beginOffset = (long long)src & 3;
+    char *readPtr = (char*)src - beginOffset;
+    char *writePtr = (char*)dest;
+    
+    int swapOffset = beginOffset;
+    for (unsigned int i = 0; i < numBytes; ++i)
+    {
+        *writePtr = readPtr[3 - swapOffset];
+        ++writePtr;
+        ++swapOffset;
+        if (swapOffset > 3)
+        {
+            swapOffset = 0;
+            readPtr += 4;
+        }
+    }
+
+#endif
+}
+
+inline void DWordInterleave( void *mem, unsigned int numDWords )
+{
+#ifdef WIN32_ASM
+    __asm {
+        mov        esi, dword ptr [mem]
+        mov        edi, dword ptr [mem]
+        add        edi, 4
+        mov        ecx, dword ptr [numDWords]
+DWordInterleaveLoop:
+        mov        eax, dword ptr [esi]
+        mov        ebx, dword ptr [edi]
+        mov        dword ptr [esi], ebx
+        mov        dword ptr [edi], eax
+        add        esi, 8
+        add        edi, 8
+        loop       DWordInterleaveLoop
+    }
+#else
+    int *m = (int*)mem;
+    for (unsigned int i = 0; i < numDWords; ++i)
+    {
+        int tmp = m[2 * i];
+        m[2 * i] = m[2 * i + 1];
+        m[2 * i + 1] = tmp;
+    }
+#endif
+}
+
+inline void QWordInterleave( void *mem, unsigned int numDWords )
+{
+#ifdef WIN32_ASM
+    __asm
+    {
+    // Interleave the line on the qword
+        mov        esi, dword ptr [mem]
+        mov        edi, dword ptr [mem]
+        add        edi, 8
+        mov        ecx, dword ptr [numDWords]
+        shr        ecx, 1
+QWordInterleaveLoop:
+        mov        eax, dword ptr [esi]
+        mov        ebx, dword ptr [edi]
+        mov        dword ptr [esi], ebx
+        mov        dword ptr [edi], eax
+        add        esi, 4
+        add        edi, 4
+        mov        eax, dword ptr [esi]
+        mov        ebx, dword ptr [edi]
+        mov        dword ptr [esi], ebx
+        mov        dword ptr [edi], eax
+        add        esi, 12
+        add        edi, 12
+        loop       QWordInterleaveLoop
+    }
+#else
+    long long *m = (long long*)mem;
+    for (unsigned int i = 0; i < numDWords / 2; ++i)
+    {
+        long long tmp = m[2 * i];
+        m[2 * i] = m[2 * i + 1];
+        m[2 * i + 1] = tmp;
+    }
+#endif
+}
+
+const unsigned char Five2Eight[32] =
+{
+      0, // 00000 = 00000000
+      8, // 00001 = 00001000
+     16, // 00010 = 00010000
+     25, // 00011 = 00011001
+     33, // 00100 = 00100001
+     41, // 00101 = 00101001
+     49, // 00110 = 00110001
+     58, // 00111 = 00111010
+     66, // 01000 = 01000010
+     74, // 01001 = 01001010
+     82, // 01010 = 01010010
+     90, // 01011 = 01011010
+     99, // 01100 = 01100011
+    107, // 01101 = 01101011
+    115, // 01110 = 01110011
+    123, // 01111 = 01111011
+    132, // 10000 = 10000100
+    140, // 10001 = 10001100
+    148, // 10010 = 10010100
+    156, // 10011 = 10011100
+    165, // 10100 = 10100101
+    173, // 10101 = 10101101
+    181, // 10110 = 10110101
+    189, // 10111 = 10111101
+    197, // 11000 = 11000101
+    206, // 11001 = 11001110
+    214, // 11010 = 11010110
+    222, // 11011 = 11011110
+    230, // 11100 = 11100110
+    239, // 11101 = 11101111
+    247, // 11110 = 11110111
+    255  // 11111 = 11111111
+};
+
+const unsigned char Four2Eight[16] = 
+{
+      0, // 0000 = 00000000
+     17, // 0001 = 00010001
+     34, // 0010 = 00100010
+     51, // 0011 = 00110011
+     68, // 0100 = 01000100
+     85, // 0101 = 01010101
+    102, // 0110 = 01100110
+    119, // 0111 = 01110111
+    136, // 1000 = 10001000
+    153, // 1001 = 10011001
+    170, // 1010 = 10101010
+    187, // 1011 = 10111011
+    204, // 1100 = 11001100
+    221, // 1101 = 11011101
+    238, // 1110 = 11101110
+    255  // 1111 = 11111111
+};
+
+const unsigned char Three2Four[8] = 
+{
+     0, // 000 = 0000
+     2, // 001 = 0010
+     4, // 010 = 0100
+     6, // 011 = 0110
+     9, // 100 = 1001
+    11, // 101 = 1011
+    13, // 110 = 1101
+    15, // 111 = 1111
+};
+
+const unsigned char Three2Eight[8] = 
+{
+      0, // 000 = 00000000
+     36, // 001 = 00100100
+     73, // 010 = 01001001
+    109, // 011 = 01101101
+    146, // 100 = 10010010
+    182, // 101 = 10110110
+    219, // 110 = 11011011
+    255, // 111 = 11111111
+};
+const unsigned char Two2Eight[4] = 
+{
+      0, // 00 = 00000000
+     85, // 01 = 01010101
+    170, // 10 = 10101010
+    255  // 11 = 11111111
+};
+
+const unsigned char One2Four[2] = 
+{
+     0, // 0 = 0000
+    15, // 1 = 1111
+};
+
+const unsigned char One2Eight[2] = 
+{
+      0, // 0 = 00000000
+    255, // 1 = 11111111
+};
+
+inline unsigned short RGBA8888_RGBA4444( unsigned int color )
+{
+    return ((color & 0xF0000000) >> 28) | ((color & 0x00F00000) >> 16) |
+           ((color & 0x0000F000) >>  4) | ((color & 0x000000F0) << 8);
+}
+
+inline unsigned int RGBA5551_RGBA8888( unsigned short color )
+{
+    int rgba;
+    char *p = (char*)&rgba;
+    color = (color >> 8) | (color << 8);
+    p[3] = One2Eight[color & 1];
+    p[2] = Five2Eight[color >> 1 & 0x1f];
+    p[1] = Five2Eight[color >> 6 & 0x1f];
+    p[0] = Five2Eight[color >> 11 & 0x1f];
+    return rgba;
+}
+
+// Just swaps the word
+inline unsigned short RGBA5551_RGBA5551( unsigned short color )
+{
+    return (color >> 8) | (color << 8);
+}
+
+inline unsigned int IA88_RGBA8888( unsigned short color )
+{
+    return (color & 0xFF) | ((color & 0xFF) << 8) | (color << 16);
+}
+
+inline unsigned short IA88_RGBA4444( unsigned short color )
+{
+    unsigned char b = color & 0xf0;
+    return (color >> 12) | b | (b << 4) | (b << 8);
+}
+
+inline unsigned short IA44_RGBA4444( unsigned char color )
+{
+    unsigned char b = color >> 4;
+    return color | (b << 8) | (b << 12);
+}
+
+inline unsigned int IA44_RGBA8888( unsigned char color )
+{
+    unsigned char b1 = color >> 4;
+    unsigned char b2 = color & 0x0f;
+    return b1 | (b1 << 4) | (b1 << 8) | (b1 << 12) | (b1 << 16) | (b1 << 20) | (b2 << 24) | (b2 << 28);
+}
+
+inline unsigned short IA31_RGBA4444( unsigned char color )
+{
+    unsigned char t = Three2Four[color >> 1];
+    return One2Four[color & 1] | (t << 4) | (t << 8) | (t << 12); 
+}
+
+inline unsigned int IA31_RGBA8888( unsigned char color )
+{
+    unsigned char t = Three2Eight[color >> 1];
+    return t | (t << 8) | (t << 16) | (One2Eight[color & 1] << 24);
+}
+
+inline unsigned short I8_RGBA4444( unsigned char color )
+{
+    color &= 0xf0;
+    return (color >> 4) | color | (color << 4) | (color << 8);
+}
+
+inline unsigned int I8_RGBA8888( unsigned char color )
+{
+    return color | (color << 8) | (color << 16) | (color << 24);
+}
+
+inline unsigned short I4_RGBA4444( unsigned char color )
+{
+    color &= 0x0f;
+    return color | (color << 4) | (color << 8) | (color << 12);
+}
+
+inline unsigned int I4_RGBA8888( unsigned char color )
+{
+    unsigned char b = Four2Eight[color];
+    return b | (b << 8) | (b << 16) | (b << 24);
+}
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp
new file mode 100755 (executable)
index 0000000..80e432e
--- /dev/null
@@ -0,0 +1,411 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "AdvancedCombinerManager.h"
+#include "CombinerStructs.h"
+#include "ExtensionChecker.h"
+#include "MultiTexturingExt.h"
+#include "AdvancedTexEnvCombiner.h"
+#include "SimpleTexEnvCombiner.h"
+#include "DummyCombiner.h"
+#include "CombinerStageMerger.h"
+#include "CombinerStageCreator.h"
+#include "RomDetector.h"
+#include "m64p.h"
+#include "OpenGL.h"
+
+static int saRGBExpanded[] = 
+{
+    COMBINED,            TEXEL0,              TEXEL1,              PRIMITIVE,        
+    SHADE,               ENVIRONMENT,         ONE,                 NOISE,
+    ZERO,                ZERO,                ZERO,                ZERO,
+    ZERO,                ZERO,                ZERO,                ZERO
+};
+
+static int sbRGBExpanded[] = 
+{
+    COMBINED,            TEXEL0,              TEXEL1,              PRIMITIVE,        
+    SHADE,               ENVIRONMENT,         CENTER,              K4,
+    ZERO,                ZERO,                ZERO,                ZERO,
+    ZERO,                ZERO,                ZERO,                ZERO
+};
+
+static int mRGBExpanded[] = 
+{
+    COMBINED,            TEXEL0,              TEXEL1,              PRIMITIVE,        
+    SHADE,               ENVIRONMENT,         SCALE,               COMBINED_ALPHA,
+    TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,     SHADE_ALPHA,
+    ENV_ALPHA,           LOD_FRACTION,        PRIM_LOD_FRAC,       K5,
+    ZERO,                ZERO,                ZERO,                ZERO,
+    ZERO,                ZERO,                ZERO,                ZERO,
+    ZERO,                ZERO,                ZERO,                ZERO,
+    ZERO,                ZERO,                ZERO,                ZERO
+};
+
+static int aRGBExpanded[] = 
+{
+    COMBINED,            TEXEL0,              TEXEL1,              PRIMITIVE,        
+    SHADE,               ENVIRONMENT,         ONE,                 ZERO
+};
+
+static int saAExpanded[] = 
+{
+    COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
+    SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
+};
+
+static int sbAExpanded[] = 
+{
+    COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
+    SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
+};
+
+static int mAExpanded[] = 
+{
+    LOD_FRACTION,        TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
+    SHADE_ALPHA,         ENV_ALPHA,           PRIM_LOD_FRAC,       ZERO,
+};
+
+static int aAExpanded[] = 
+{
+    COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
+    SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
+};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+AdvancedCombinerManager::AdvancedCombinerManager()
+{
+    currentTexEnv = 0;
+    m_combiner = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+AdvancedCombinerManager::~AdvancedCombinerManager()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Selects sutible combiner and initializes it
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::initialize()
+{
+    currentTexEnv = 0;
+
+    //Select Combiner
+    switch ( ROMDetector::getSingleton().getCombinerType() )
+    {
+        case CT_DUMMY:
+            m_combiner = new DummyCombiner();
+            break;
+
+        case CT_SIMPLE:
+            m_combiner = new SimpleTexEnvCombiner();
+            break;
+
+        case CT_ADVANCED:
+        default:
+            m_combiner = new AdvancedTexEnvCombiner();
+            break;
+    }
+
+    //init combiner
+    m_combiner->initialize();
+}
+
+//-----------------------------------------------------------------------------
+//! Dispose
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::dispose()
+{
+    if ( m_combiner ) { delete m_combiner; m_combiner = 0; }
+    m_combinerCache.dispose();
+}
+
+//-----------------------------------------------------------------------------
+//! Select Combine
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::selectCombine(unsigned int cycleType)
+{
+    //Hack for the Banjo-Tooie shadow 
+    if ( cycleType == G_CYC_1CYCLE && m_combineData.mux == 0x00ffe7ffffcf9fcfLL )
+    {
+        m_combineData.mux = 71943244815007743LL;
+        m_combiner->setBlendColor(0,0,0,0);
+        m_combiner->setPrimColor(0,0,0,0);
+        m_combiner->setEnvColor(0,0,0,0);
+        m_combiner->setFillColor(0,0,0,0);
+    }
+
+    CachedCombiner* old = m_combinerCache.findCachedCombiner(m_combineData.mux);
+
+    if ( old == 0 )
+    {
+        //Cound not find an old combiner
+        this->update(cycleType);         //Create a new combiner
+    }
+    else
+    {
+        currentTexEnv = old->compiled;
+    }
+
+    //Set Texture Enviroment
+    this->endTextureUpdate();
+}
+
+//-----------------------------------------------------------------------------
+//! Update Combine Colors
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::updateCombineColors()
+{
+    m_combiner->setTextureEnviromentColors( currentTexEnv );
+}
+
+//-----------------------------------------------------------------------------
+//! Update 
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::update(unsigned int cycleType)
+{
+    int numCycles;
+
+    Combiner colorCombiner;
+    Combiner alphaCombiner;
+
+    //Set number of cycles
+    if ( cycleType == G_CYC_2CYCLE )
+    {
+        numCycles = 2;
+        colorCombiner.numStages = 2;
+        alphaCombiner.numStages = 2;
+    }
+    else
+    {
+        numCycles = 1;
+        colorCombiner.numStages = 1;
+        alphaCombiner.numStages = 1;
+    }
+
+    CombineCycle colorCycle[2];
+    CombineCycle alphaCycle[2];
+
+    // Decode and expand the combine mode into a more general form
+    colorCycle[0].loadValue  = saRGBExpanded[m_combineData.saRGB0];
+    colorCycle[0].subValue   = sbRGBExpanded[m_combineData.sbRGB0];
+    colorCycle[0].multValue  = mRGBExpanded[m_combineData.mRGB0];
+    colorCycle[0].addValue   = aRGBExpanded[m_combineData.aRGB0];
+    colorCycle[1].loadValue  = saRGBExpanded[m_combineData.saRGB1];
+    colorCycle[1].subValue   = sbRGBExpanded[m_combineData.sbRGB1];
+    colorCycle[1].multValue  = mRGBExpanded[m_combineData.mRGB1];
+    colorCycle[1].addValue   = aRGBExpanded[m_combineData.aRGB1];
+
+    alphaCycle[0].loadValue  = saAExpanded[m_combineData.saA0];
+    alphaCycle[0].subValue   = sbAExpanded[m_combineData.sbA0];
+    alphaCycle[0].multValue  = mAExpanded[m_combineData.mA0];
+    alphaCycle[0].addValue   = aAExpanded[m_combineData.aA0];
+    alphaCycle[1].loadValue  = saAExpanded[m_combineData.saA1];
+    alphaCycle[1].subValue   = sbAExpanded[m_combineData.sbA1];
+    alphaCycle[1].multValue  = mAExpanded[m_combineData.mA1];
+    alphaCycle[1].addValue   = aAExpanded[m_combineData.aA1];
+
+    //For each cycle    
+    for (int i=0; i<numCycles; ++i)
+    {
+        //Set stages on color combiner
+        setStage(&colorCycle[i], &colorCombiner.stage[i]);
+
+        //Set stages on alpha combiner
+        setStage(&alphaCycle[i], &alphaCombiner.stage[i]);
+    }
+
+    if (numCycles == 2)
+    {
+        // Attempt to merge the two stages into one
+        mergeStages( &colorCombiner );
+        mergeStages( &alphaCombiner );
+    }
+
+    //Create New Enviroment
+    currentTexEnv = m_combiner->createNewTextureEnviroment(&colorCombiner, &alphaCombiner);
+
+    if ( !ROMDetector::getSingleton().getUseMultiTexture() )
+    {
+        currentTexEnv->usesT1 = false;
+    }
+
+    //Store combiner for reuse
+    m_combinerCache.newCompiledCombiner(m_combineData.mux, currentTexEnv);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Mux
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setMux(unsigned long long mux, unsigned int cycleType)
+{
+    m_combineData.mux = mux;    
+}
+
+//-----------------------------------------------------------------------------
+//! Set Mux
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType)
+{
+    m_combineData.muxs0 = muxs0;
+    m_combineData.muxs1 = muxs1;    
+}
+
+//-----------------------------------------------------------------------------
+//! Begin Texture Update
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::beginTextureUpdate()
+{
+    m_combiner->beginTextureUpdate();
+}
+
+//-----------------------------------------------------------------------------
+//! End Texture Update
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::endTextureUpdate()
+{
+    //Set Texture Enviroment
+    m_combiner->setTextureEnviroment(currentTexEnv);
+}
+
+//-----------------------------------------------------------------------------
+//* Get Combiner Color
+//! Get Combiner Color which will be assigned to vertices
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::getCombinerColor(float out[4])
+{
+    m_combiner->getCombinerColor(out, currentTexEnv->vertex.color, currentTexEnv->vertex.alpha);
+}
+
+//-----------------------------------------------------------------------------
+//* Get Secondary Combiner Color
+//! Get Secondary Combiner Color which will be assigned to vertices
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::getSecondaryCombinerColor(float out[4])
+{
+    if ( !ROMDetector::getSingleton().getUseSecondaryColor() )
+    {
+        return;    
+    }
+
+    //Get color
+    m_combiner->getCombinerColor(out, currentTexEnv->vertex.secondaryColor, ONE);
+}
+
+//-----------------------------------------------------------------------------
+//* Get Fill Color
+//! @return Fill Color as <r,g,b,a> (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+float* AdvancedCombinerManager::getFillColor()  
+{ 
+    return m_combiner->getFillColor();  
+}
+
+//-----------------------------------------------------------------------------
+//* Get Blend Color
+//! @return Blend Color as <r,g,b,a> (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+float* AdvancedCombinerManager::getBlendColor() 
+{ 
+    return m_combiner->getBlendColor(); 
+}
+
+//-----------------------------------------------------------------------------
+//* Get Prim Color
+//! @return Prim Color as <r,g,b,a> (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+float* AdvancedCombinerManager::getPrimColor()  
+{ 
+    return m_combiner->getPrimColor();  
+}
+
+//-----------------------------------------------------------------------------
+//! Set Fill Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setFillColor (float r, float g, float b, float a)
+{ 
+    m_combiner->setFillColor(r,g,b,a); 
+}
+
+//-----------------------------------------------------------------------------
+//! Set Blend Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setBlendColor(float r, float g, float b, float a) 
+{ 
+    m_combiner->setBlendColor(r,g,b,a); 
+}
+
+//-----------------------------------------------------------------------------
+//! Set Prim Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setPrimColor (float r, float g, float b, float a) 
+{ 
+    m_combiner->setPrimColor(r,g,b,a); 
+}
+
+//-----------------------------------------------------------------------------
+//! Set Environment Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setEnvColor  (float r, float g, float b, float a) 
+{ 
+    m_combiner->setEnvColor(r,g,b,a); 
+}
+
+//-----------------------------------------------------------------------------
+//* Set Prim LOD Min
+//! @param primLodMin
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin) 
+{ 
+    m_combiner->setPrimLodMin(primLodMin); 
+};
+
+//-----------------------------------------------------------------------------
+//* Set Prim LOD Frac
+//! @param primLodFrac
+//-----------------------------------------------------------------------------
+void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac) 
+{ 
+    m_combiner->setPrimLodFrac(primLodFrac); 
+};
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h
new file mode 100755 (executable)
index 0000000..49ed3c0
--- /dev/null
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef ADVANCED_COMBINER_MANAGER_H_
+#define ADVANCED_COMBINER_MANAGER_H_
+
+#include "GBIDefs.h"
+#include "CombinerStructs.h"
+#include "CombinerCache.h"
+
+//Forward declarations
+struct TexEnvCombiner;
+struct CombineCycle;
+struct CombinerStage;
+struct Combiner;
+class AdvancedTexEnvCombiner;
+class CombinerCache;
+class CombinerBase;
+
+//*****************************************************************************
+//! Advanced Texture Environment Combiner
+//! Class used to select sutible combiners and sending input to selected
+//! Combiners.
+//*****************************************************************************
+class AdvancedCombinerManager
+{
+public:
+    
+    //Constructor / Destructor
+    AdvancedCombinerManager();
+    ~AdvancedCombinerManager();
+
+    //Initialize / Dispose
+    void initialize();    
+    void dispose();
+
+    //Set Mux
+    void setMux(unsigned long long muxs, unsigned int cycleType);
+    void setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType);
+
+    //Select Combiner
+    void selectCombine(unsigned int cycleType);
+
+    //Update
+    void update(unsigned int cycleType);       
+    void updateCombineColors();                 
+
+    //Begin / End Texture update
+    void beginTextureUpdate();
+    void endTextureUpdate();
+
+    //Get Combiner Colors which will be assigned to vertices
+    void getCombinerColor(float out[4]);
+    void getSecondaryCombinerColor(float out[4]);
+
+    //Set / Get Colors
+    void setFillColor (float r, float g, float b, float a);
+    void setBlendColor(float r, float g, float b, float a);
+    void setPrimColor (float r, float g, float b, float a);
+    void setEnvColor  (float r, float g, float b, float a);
+    float* getFillColor();
+    float* getBlendColor();
+    float* getPrimColor();
+
+    //Set Prim LOD
+    void setPrimLodMin(unsigned int primLodMin);
+    void setPrimLodFrac(float primLodFrac);
+
+    //! @return True if combiner wish to use texture channel 0
+    bool getUsesTexture0() { return currentTexEnv->usesT0; }
+
+    //! @return True if combiner wish to use texture channel 1
+    bool getUsesTexture1() { return currentTexEnv->usesT1; }
+
+private:
+
+    //Private Members
+    CombineData     m_combineData;    //!< Combiner Input (How to combine colors andset up enviroment)
+    TexEnvCombiner* currentTexEnv;    //!< Texture Enviroment
+    CombinerBase*   m_combiner;       //!< Combiner
+    CombinerCache   m_combinerCache;  //!< Cache used to store old combiners for reuse
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp
new file mode 100755 (executable)
index 0000000..5d32a5d
--- /dev/null
@@ -0,0 +1,590 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include <algorithm>
+using std::max;
+#include "AdvancedTexEnvCombiner.h"
+#include "CombinerStructs.h"
+#include "MultiTexturingExt.h"    //glActiveTextureARB
+#include "ExtensionChecker.h"
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3
+    #define GL_ATI_texture_env_combine3
+    #define GL_MODULATE_ADD_ATI                             0x8744
+    #define GL_MODULATE_SIGNED_ADD_ATI                      0x8745
+    #define GL_MODULATE_SUBTRACT_ATI                        0x8746
+#endif //GL_ATI_texture_env_combine3 
+
+#ifndef GL_ATIX_texture_env_route
+#define GL_ATIX_texture_env_route 1
+    #define GL_SECONDARY_COLOR_ATIX                 0x8747
+    #define GL_TEXTURE_OUTPUT_RGB_ATIX              0x8748
+    #define GL_TEXTURE_OUTPUT_ALPHA_ATIX            0x8749
+#endif // GL_ATIX_texture_env_route 
+
+static TexEnvCombinerArg TexEnvArgs[] =
+{
+    // CMB
+    { GL_PREVIOUS_ARB,       GL_SRC_COLOR },
+    // T0
+    { GL_TEXTURE,            GL_SRC_COLOR },
+    // T1
+    { GL_TEXTURE,            GL_SRC_COLOR },
+    // PRIM
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // SHADE
+    { GL_PRIMARY_COLOR_ARB,  GL_SRC_COLOR },
+    // ENV
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // CENTER
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // SCALE
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // CMBALPHA
+    { GL_PREVIOUS_ARB,       GL_SRC_ALPHA },
+    // T0ALPHA
+    { GL_TEXTURE,            GL_SRC_ALPHA },
+    // T1ALPHA
+    { GL_TEXTURE,            GL_SRC_ALPHA },
+    // PRIMALPHA
+    { GL_CONSTANT_ARB,       GL_SRC_ALPHA },
+    // SHADEALPHA
+    { GL_PRIMARY_COLOR_ARB,  GL_SRC_ALPHA },
+    // ENVALPHA
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // LODFRAC
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // PRIMLODFRAC
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // NOISE
+    { GL_TEXTURE,            GL_SRC_COLOR },
+    // K4
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // K5
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // ONE
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR },
+    // ZERO
+    { GL_CONSTANT_ARB,       GL_SRC_COLOR }
+};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+AdvancedTexEnvCombiner::AdvancedTexEnvCombiner()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+AdvancedTexEnvCombiner::~AdvancedTexEnvCombiner()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Checks if extensions are supported
+//-----------------------------------------------------------------------------
+void AdvancedTexEnvCombiner::initialize()
+{
+#ifdef HAVE_GLES
+    ARB_texture_env_combine  = true;
+    ARB_texture_env_crossbar = true;
+#else
+    ARB_texture_env_combine  = isExtensionSupported( "GL_ARB_texture_env_combine" );
+    ARB_texture_env_crossbar = isExtensionSupported( "GL_ARB_texture_env_crossbar" );
+#endif
+    ATI_texture_env_combine3 = isExtensionSupported( "GL_ATI_texture_env_combine3" );
+    ATIX_texture_env_route   = isExtensionSupported( "GL_ATIX_texture_env_route" );
+    NV_texture_env_combine4  = isExtensionSupported( "GL_NV_texture_env_combine4" );;
+
+    if ( ARB_texture_env_crossbar || NV_texture_env_combine4 || ATIX_texture_env_route )
+    {
+        TexEnvArgs[TEXEL0].source       = GL_TEXTURE0_ARB;
+        TexEnvArgs[TEXEL0_ALPHA].source = GL_TEXTURE0_ARB;
+        TexEnvArgs[TEXEL1].source       = GL_TEXTURE1_ARB;
+        TexEnvArgs[TEXEL1_ALPHA].source = GL_TEXTURE1_ARB;
+    }
+
+    if ( ATI_texture_env_combine3 )
+    {
+        TexEnvArgs[ONE].source  = GL_ONE;
+        TexEnvArgs[ZERO].source = GL_ZERO;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Begin Texture Update
+//! Disables all textures
+//-----------------------------------------------------------------------------
+void AdvancedTexEnvCombiner::beginTextureUpdate()
+{
+    const int openGLMaxTextureUnits = 8;
+
+    //Disable all texture channels
+    for (int i = 0; i <openGLMaxTextureUnits; i++)
+    {
+        glActiveTextureARB(GL_TEXTURE0_ARB + i);
+        glDisable(GL_TEXTURE_2D );
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//* End Texture Update
+//! Enables selected textures in a texture environment
+//! @param texEnv Texture environment with textures to be enabled
+//-----------------------------------------------------------------------------
+void AdvancedTexEnvCombiner::endTextureUpdate(TexEnvCombiner* texEnv)
+{  
+    //Enable texturing
+    for (int i = 0; i <texEnv->usedUnits; i++)
+    {
+        glActiveTextureARB( GL_TEXTURE0_ARB + i );
+        glEnable( GL_TEXTURE_2D );
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Enviroment Colors
+//! Sets texture enviorment colors for all active textures
+//! @param texEnv Texture environment with textures that will be assigned colors
+//-----------------------------------------------------------------------------
+void AdvancedTexEnvCombiner::setTextureEnviromentColors(TexEnvCombiner* texEnv)
+{
+    float color[4];
+
+    int openGLMaxTextureUnits = 8;
+
+    for (int i = 0; i < openGLMaxTextureUnits; i++)
+    {
+        this->getCombinerColor( color, texEnv->color[i].constant, texEnv->alpha[i].constant );
+
+        glActiveTextureARB(GL_TEXTURE0_ARB + i);
+        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &color[0]);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Enviroment
+//! Sets texture environment for all active textures
+//! @param texEnv Texture environment with input data which will be 
+//!               sent to OpenGL using function "glTexEnvi" using ARB extensions
+//-----------------------------------------------------------------------------
+void AdvancedTexEnvCombiner::setTextureEnviroment(TexEnvCombiner* texEnv)
+{
+    const int openGLMaxTextureUnits = 8;
+
+    for (int i=0; i<openGLMaxTextureUnits; ++i)
+    {
+        glActiveTextureARB(GL_TEXTURE0_ARB + i);
+
+        if ( (i < texEnv->usedUnits ) || (i < 2 && texEnv->usesT1) )
+        {
+            glEnable( GL_TEXTURE_2D );
+            glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,   GL_COMBINE_ARB );
+            glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB,    texEnv->color[i].combine );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB,    texEnv->color[i].arg0.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB,   texEnv->color[i].arg0.operand );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB,    texEnv->color[i].arg1.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB,   texEnv->color[i].arg1.operand );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB,    texEnv->color[i].arg2.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB,   texEnv->color[i].arg2.operand );
+            glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB,  texEnv->alpha[i].combine );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB,  texEnv->alpha[i].arg0.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, texEnv->alpha[i].arg0.operand );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB,  texEnv->alpha[i].arg1.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, texEnv->alpha[i].arg1.operand );
+            glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB,  texEnv->alpha[i].arg2.source );
+            glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, texEnv->alpha[i].arg2.operand );
+        }
+        else
+        {
+            glDisable(GL_TEXTURE_2D);
+        }            
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Create New Texture Enviornment
+//! Allocates a new texture enviroment
+//! @param[in] colorCombiner How to combine and get a color
+//! @param[in] alphaCombiner How to combine and get an alpha value
+//! @return The texture enviroment that was created
+//-----------------------------------------------------------------------------
+TexEnvCombiner* AdvancedTexEnvCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner)
+{
+    TexEnvCombiner* envCombiner = new TexEnvCombiner();
+
+    int curUnit;
+
+    const int openGLMaxTextureUnits = 8;
+
+    //For each texture unit
+    for (int i = 0; i < openGLMaxTextureUnits; i++)
+    {
+        envCombiner->color[i].combine = GL_REPLACE;
+        envCombiner->alpha[i].combine = GL_REPLACE;
+
+        SetColorCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_COLOR );
+        SetColorCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_COLOR );
+        SetColorCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_COLOR );
+        envCombiner->color[i].constant = COMBINED;
+        envCombiner->color[i].outputTexture = GL_TEXTURE0_ARB + i;
+
+        SetAlphaCombinerValues( i, arg0, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
+        SetAlphaCombinerValues( i, arg1, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
+        SetAlphaCombinerValues( i, arg2, GL_PREVIOUS_ARB, GL_SRC_ALPHA );
+        envCombiner->alpha[i].constant = COMBINED;
+        envCombiner->alpha[i].outputTexture = GL_TEXTURE0_ARB + i;
+    }
+
+    envCombiner->usesT0 = false;
+    envCombiner->usesT1 = false;
+
+    envCombiner->vertex.color = COMBINED;
+    envCombiner->vertex.secondaryColor = COMBINED;
+    envCombiner->vertex.alpha = COMBINED;
+
+    curUnit = 0;
+
+    for (int i=0; i<alphaCombiner->numStages; i++)
+    {
+        for (int j = 0; j < alphaCombiner->stage[i].numOps; j++)
+        {
+            float sb = 0.0f;
+
+            if (alphaCombiner->stage[i].op[j].param1 == PRIMITIVE_ALPHA)
+                sb = m_primColor[3];
+            else if (alphaCombiner->stage[i].op[j].param1 == ENV_ALPHA)
+                sb = m_envColor[3];
+            else if (alphaCombiner->stage[i].op[j].param1 == ONE)
+                sb = 1.0f;
+
+            if (((alphaCombiner->stage[i].numOps - j) >= 3) &&
+                (alphaCombiner->stage[i].op[j].op == SUB) &&
+                (alphaCombiner->stage[i].op[j+1].op == MUL) &&
+                (alphaCombiner->stage[i].op[j+2].op == ADD) &&
+                (sb > 0.5f) && 
+                (ARB_texture_env_combine))
+            {
+                envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
+                envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
+
+                if (alphaCombiner->stage[i].op[j].param1 == ONE)
+                {
+                    SetAlphaCombinerValues( curUnit, arg0, envCombiner->alpha[curUnit].arg0.source, GL_ONE_MINUS_SRC_ALPHA );
+                }
+                else
+                {
+                    envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
+                    SetAlphaCombinerValues( curUnit, arg1, envCombiner->alpha[curUnit].arg0.source, GL_SRC_ALPHA );
+                    SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
+
+                    curUnit++;
+                }
+
+                j++;
+
+                envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
+                envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
+
+                envCombiner->alpha[curUnit].combine = GL_MODULATE;
+                SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+
+                curUnit++;
+                j++;
+
+                envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
+                envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
+
+                envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
+                SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
+
+                curUnit++;
+            }
+            else
+            {
+                envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA;
+                envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA;
+
+                switch (alphaCombiner->stage[i].op[j].op)
+                {
+                    case LOAD:
+                        if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
+                            (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
+                            curUnit++;
+
+                        envCombiner->alpha[curUnit].combine = GL_REPLACE;
+
+                        SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
+                        break;
+                    case SUB:
+                        if (!ARB_texture_env_combine)
+                            break;
+
+                        if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
+                            (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
+                            curUnit++;
+
+                        if ((j > 0) && (alphaCombiner->stage[i].op[j-1].op == LOAD) && (alphaCombiner->stage[i].op[j-1].param1 == ONE))
+                        {
+                            SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
+                            envCombiner->alpha[curUnit].arg0.operand = GL_ONE_MINUS_SRC_ALPHA;
+                        }
+                        else if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
+                        {
+                            curUnit--;
+                            SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
+                            envCombiner->alpha[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
+                            SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+                            curUnit++;
+                        }
+                        else
+                        {
+                            envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB;
+                            SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+                            curUnit++;
+                        }
+                        break;
+                    case MUL:
+                        if (!( ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
+                            curUnit++;
+
+                        envCombiner->alpha[curUnit].combine = GL_MODULATE;
+
+                        SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+                        curUnit++;
+                        break;
+                    case ADD:
+                        if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) &&
+                            (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0))
+                            curUnit++;
+
+                        if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE))
+                        {
+                            curUnit--;
+                            SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand );
+                            envCombiner->alpha[curUnit].combine = GL_MODULATE_ADD_ATI;
+                            SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+                        }
+                        else
+                        {
+                            envCombiner->alpha[curUnit].combine = GL_ADD;
+                            SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 );
+                        }
+                        curUnit++;
+                        break;
+                    case INTERPOLATE:
+                        envCombiner->usesT0 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL0_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA);
+                        envCombiner->usesT1 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL1_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA);
+
+                        envCombiner->alpha[curUnit].combine = GL_INTERPOLATE_ARB;
+
+                        SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 );
+                        SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param2 );
+                        SetAlphaCombinerArg( curUnit, arg2, alphaCombiner->stage[i].op[j].param3 );
+
+                        curUnit++;
+                        break;
+                }
+            }
+        }
+    }
+
+    envCombiner->usedUnits = max( curUnit, 1 );
+
+    curUnit = 0;
+    for (int i = 0; i < colorCombiner->numStages; i++)
+    {
+        for (int j = 0; j < colorCombiner->stage[i].numOps; j++)
+        {
+            float sb = 0.0f;
+
+            if (colorCombiner->stage[i].op[j].param1 == PRIMITIVE)
+                sb = (m_primColor[0] + m_primColor[2] + m_primColor[1]) / 3.0f;
+            else if (colorCombiner->stage[i].op[j].param1 == ENVIRONMENT)
+                sb = (m_envColor[0] + m_envColor[2] + m_envColor[1]) / 3.0f;
+
+            // This helps with problems caused by not using signed values between texture units
+            if (((colorCombiner->stage[i].numOps - j) >= 3) &&
+                (colorCombiner->stage[i].op[j].op == SUB) &&
+                (colorCombiner->stage[i].op[j+1].op == MUL) &&
+                (colorCombiner->stage[i].op[j+2].op == ADD) &&
+                (sb > 0.5f) && 
+                (ARB_texture_env_combine))
+            {
+                envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
+                envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
+
+                envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
+                SetColorCombinerValues( curUnit, arg1, envCombiner->color[curUnit].arg0.source, envCombiner->color[curUnit].arg0.operand );
+                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+
+                curUnit++;
+                j++;
+
+                envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
+                envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
+
+                envCombiner->color[curUnit].combine = GL_MODULATE;
+                SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+
+                curUnit++;
+                j++;
+
+                envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
+                envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
+
+                envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
+                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+
+                curUnit++;
+            }
+            else
+            {
+                envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA));
+                envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA));
+
+                switch (colorCombiner->stage[i].op[j].op)
+                {
+                    case LOAD:
+                        if (!( ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
+                            curUnit++;
+
+                        envCombiner->color[curUnit].combine = GL_REPLACE;
+
+                        SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+                        break;
+                    case SUB:
+                        if (!ARB_texture_env_combine)
+                            break;
+
+                        if (!(ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
+                            curUnit++;
+
+                        if ((j > 0) && (colorCombiner->stage[i].op[j-1].op == LOAD) && (colorCombiner->stage[i].op[j-1].param1 == ONE))
+                        {
+                            SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+                            envCombiner->color[curUnit].arg0.operand = GL_ONE_MINUS_SRC_COLOR;
+                        }
+                        else if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
+                        {
+                            curUnit--;
+                            SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
+                            envCombiner->color[curUnit].combine = GL_MODULATE_SUBTRACT_ATI;
+                            SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+                            curUnit++;
+                        }
+                        else
+                        {
+                            envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB;
+                            SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+                            curUnit++;
+                        }
+                        break;
+                    case MUL:
+                        if (!( ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
+                            curUnit++;
+
+                        envCombiner->color[curUnit].combine = GL_MODULATE;
+
+                        SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+                        curUnit++;
+                        break;
+                    case ADD:
+                        if (!( ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0))
+                            curUnit++;
+
+                        // ATI_texture_env_combine3 adds GL_MODULATE_ADD_ATI; saves texture units
+                        if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE))
+                        {
+                            curUnit--;
+                            SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand );
+                            envCombiner->color[curUnit].combine = GL_MODULATE_ADD_ATI;
+                            SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+                        }
+                        else
+                        {
+                            envCombiner->color[curUnit].combine = GL_ADD;
+                            SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 );
+                        }
+                        curUnit++;
+                        break;
+                    case INTERPOLATE:
+                        envCombiner->usesT0 |= (colorCombiner->stage[i].op[j].param2 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA);
+                        envCombiner->usesT1 |= (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA);
+
+                        if (!( ARB_texture_env_crossbar ||  NV_texture_env_combine4) &&
+                            ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA)) && (curUnit == 0))
+                        {
+                            if (colorCombiner->stage[i].op[j].param1 == TEXEL0)
+                            {
+                                envCombiner->color[curUnit].combine = GL_REPLACE;
+                                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+                                colorCombiner->stage[i].op[j].param1 = COMBINED;
+                            }
+                            if (colorCombiner->stage[i].op[j].param2 == TEXEL0)
+                            {
+                                envCombiner->color[curUnit].combine = GL_REPLACE;
+                                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param2 )
+
+                                colorCombiner->stage[i].op[j].param2 = COMBINED;
+                            }
+                            if (colorCombiner->stage[i].op[j].param3 == TEXEL0)
+                            {
+                                envCombiner->color[curUnit].combine = GL_REPLACE;
+                                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 );
+                                colorCombiner->stage[i].op[j].param3 = COMBINED;
+                            }
+                            if (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA)
+                            {
+                                envCombiner->color[curUnit].combine = GL_REPLACE;
+                                SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 );
+                                colorCombiner->stage[i].op[j].param3 = COMBINED_ALPHA;
+                            }
+
+                            curUnit++;
+                        }
+
+                        envCombiner->color[curUnit].combine = GL_INTERPOLATE_ARB;
+
+                        SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 );
+                        SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param2 );
+                        SetColorCombinerArg( curUnit, arg2, colorCombiner->stage[i].op[j].param3 );
+
+                        curUnit++;
+                        break;
+                }
+            }
+        }
+    }
+
+    envCombiner->usedUnits = max( (unsigned short)curUnit, envCombiner->usedUnits );
+    return envCombiner;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h
new file mode 100755 (executable)
index 0000000..eac08d5
--- /dev/null
@@ -0,0 +1,166 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef ADVANCED_TEX_ENV_COMBINER_H_
+#define ADVANCED_TEX_ENV_COMBINER_H_
+
+#include "CombinerBase.h"
+#include "CombinerStructs.h"
+
+struct TexEnvCombiner;
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine  1
+#ifndef HAVE_GLES
+    #define GL_COMBINE_ARB        0x8570
+    #define GL_COMBINE_RGB_ARB    0x8571
+    #define GL_COMBINE_ALPHA_ARB  0x8572
+    #define GL_SOURCE0_RGB_ARB    0x8580
+    #define GL_SOURCE1_RGB_ARB    0x8581
+    #define GL_SOURCE2_RGB_ARB    0x8582
+    #define GL_SOURCE0_ALPHA_ARB  0x8588
+    #define GL_SOURCE1_ALPHA_ARB  0x8589
+    #define GL_SOURCE2_ALPHA_ARB  0x858A
+    #define GL_OPERAND0_RGB_ARB   0x8590
+    #define GL_OPERAND1_RGB_ARB   0x8591
+    #define GL_OPERAND2_RGB_ARB   0x8592
+    #define GL_OPERAND0_ALPHA_ARB 0x8598
+    #define GL_OPERAND1_ALPHA_ARB 0x8599
+    #define GL_OPERAND2_ALPHA_ARB 0x859A
+    #define GL_RGB_SCALE_ARB      0x8573
+    #define GL_ADD_SIGNED_ARB     0x8574
+    #define GL_INTERPOLATE_ARB    0x8575
+    #define GL_CONSTANT_ARB       0x8576
+    #define GL_PRIMARY_COLOR_ARB  0x8577
+    #define GL_PREVIOUS_ARB       0x8578
+    #define GL_SUBTRACT_ARB       0x84E7
+#endif
+#endif
+#define SetColorCombinerValues( n, a, s, o ) \
+    envCombiner->color[n].a.source = s; \
+    envCombiner->color[n].a.operand = o
+
+#define SetAlphaCombinerValues( n, a, s, o ) \
+    envCombiner->alpha[n].a.source = s; \
+    envCombiner->alpha[n].a.operand = o
+
+#define SetAlphaCombinerArg( n, a, i ) \
+    if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \
+    { \
+        if ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i)) \
+        { \
+            envCombiner->alpha[n].constant = i; \
+            envCombiner->alpha[n].a.source = GL_CONSTANT_ARB; \
+            envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
+        } \
+        else if ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i)) \
+        { \
+            envCombiner->vertex.alpha = i; \
+            envCombiner->alpha[n].a.source = GL_PRIMARY_COLOR_ARB; \
+            envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
+        } \
+    } \
+    else \
+    { \
+        envCombiner->alpha[n].a.source = TexEnvArgs[i].source; \
+        envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \
+    }
+
+#define SetColorCombinerArg( n, a, i ) \
+ if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \
+    { \
+        if ((i > 5) && ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i))) \
+        { \
+            envCombiner->alpha[n].constant = i; \
+            envCombiner->color[n].a.source = GL_CONSTANT_ARB; \
+            envCombiner->color[n].a.operand = GL_SRC_ALPHA; \
+        } \
+        else if ((i > 5) && ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i))) \
+        { \
+            envCombiner->vertex.alpha = i; \
+            envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \
+            envCombiner->color[n].a.operand = GL_SRC_ALPHA; \
+        } \
+        else if ((envCombiner->color[n].constant == COMBINED) || (envCombiner->color[n].constant == i)) \
+        { \
+            envCombiner->color[n].constant = i; \
+            envCombiner->color[n].a.source = GL_CONSTANT_ARB; \
+            envCombiner->color[n].a.operand = GL_SRC_COLOR; \
+        } \
+        else if ( ATIX_texture_env_route && ((envCombiner->vertex.secondaryColor == COMBINED) || (envCombiner->vertex.secondaryColor == i))) \
+        { \
+            envCombiner->vertex.secondaryColor = i; \
+            envCombiner->color[n].a.source = GL_SECONDARY_COLOR_ATIX; \
+            envCombiner->color[n].a.operand = GL_SRC_COLOR; \
+        } \
+        else if ((envCombiner->vertex.color == COMBINED) || (envCombiner->vertex.color == i))\
+        { \
+            envCombiner->vertex.color = i; \
+            envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \
+            envCombiner->color[n].a.operand = GL_SRC_COLOR; \
+        } \
+    } \
+    else \
+    { \
+        envCombiner->color[n].a.source = TexEnvArgs[i].source; \
+        envCombiner->color[n].a.operand = TexEnvArgs[i].operand; \
+    }
+
+//*****************************************************************************
+//! Advanced Texture Environment Combiner
+//! Class used to combine colors by setting texture enviroment using OpenGL
+//*****************************************************************************
+class AdvancedTexEnvCombiner : public CombinerBase
+{
+public:
+
+    //Constructor / Destructor
+    AdvancedTexEnvCombiner();
+    ~AdvancedTexEnvCombiner();
+
+    //Initialize
+    void initialize();
+
+    //Begin / End Texture Update
+    void beginTextureUpdate();
+    void endTextureUpdate(TexEnvCombiner* texEnv);   
+
+    //Sets texture enviorment colors
+    void setTextureEnviromentColors(TexEnvCombiner* texEnv);
+
+    //Create New Texture Environment
+    TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner);
+
+    //Sets texture enviorment
+    void setTextureEnviroment(TexEnvCombiner* texEnv);
+
+private:
+
+    //Extensions
+    bool ARB_texture_env_combine;
+    bool ARB_texture_env_crossbar;
+    bool ATI_texture_env_combine3;
+    bool ATIX_texture_env_route;
+    bool NV_texture_env_combine4;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp
new file mode 100755 (executable)
index 0000000..c968949
--- /dev/null
@@ -0,0 +1,183 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "CombinerBase.h"
+#include "CombinerStructs.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+CombinerBase::CombinerBase()
+{
+    m_fillColor[0] = m_blendColor[0] = m_primColor[0] = m_envColor[0] = 0;
+    m_fillColor[1] = m_blendColor[1] = m_primColor[1] = m_envColor[1] = 0;
+    m_fillColor[2] = m_blendColor[2] = m_primColor[2] = m_envColor[2] = 0;
+    m_fillColor[3] = m_blendColor[3] = m_primColor[3] = m_envColor[3] = 1;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+CombinerBase::~CombinerBase()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Set Fill Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void CombinerBase::setFillColor (float r, float g, float b, float a)
+{
+    m_fillColor[0] = r;
+    m_fillColor[1] = g;
+    m_fillColor[2] = b;
+    m_fillColor[3] = a;
+}
+
+//-----------------------------------------------------------------------------
+//! Set Blend Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void CombinerBase::setBlendColor(float r, float g, float b, float a)
+{
+    m_blendColor[0] = r;
+    m_blendColor[1] = g;
+    m_blendColor[2] = b;
+    m_blendColor[3] = a;
+}
+
+//-----------------------------------------------------------------------------
+//! Set Prim Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void CombinerBase::setPrimColor (float r, float g, float b, float a)
+{
+    m_primColor[0] = r;
+    m_primColor[1] = g;
+    m_primColor[2] = b;
+    m_primColor[3] = a;
+}
+
+//-----------------------------------------------------------------------------
+//! Set Enviroment Color
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void CombinerBase::setEnvColor(float r, float g, float b, float a)
+{
+    m_envColor[0] = r;
+    m_envColor[1] = g;
+    m_envColor[2] = b;
+    m_envColor[3] = a;
+}
+
+//-----------------------------------------------------------------------------
+//! Get Combiner Color
+//! @param[in] colorSource From which colorsource to retrive color values
+//!    \arg \c PRIMITIVE Get color from primative color
+//!    \arg \c ENVIRONMENT Get color from environment color
+//!    \arg \c PRIMITIVE_ALPHA Get color from primatives alpha value
+//!    \arg \c ENV_ALPHA Get color from environment colors alpha value
+//!    \arg \c PRIM_LOD_FRAC Get color from primative-LOD-frac value
+//!    \arg \c ONE Get white color
+//!    \arg \c ZERO Get black color
+//! @param[in] alphaSource From which alphasource to retrive alpha value
+//!    \arg \c PRIMITIVE_ALPHA Get alpha value from primitive colors alpha value
+//!    \arg \c ENV_ALPHA Get alpha value from environment colors alpha value
+//!    \arg \c PRIM_LOD_FRAC Get alpha value from primative-LOD-frac value
+//!    \arg \c ONE Set alpha value to 1.0
+//!    \arg \c ZERO Set alpha value to 0.0
+//! @param[out] out The combiner color with color and alpha value
+//-----------------------------------------------------------------------------
+void CombinerBase::getCombinerColor(float out[4], short colorSrc, short alphaSrc)
+{
+    //Set color values
+    switch ( colorSrc ) 
+    { 
+        case PRIMITIVE: 
+            out[0] = m_primColor[0]; 
+            out[1] = m_primColor[1]; 
+            out[2] = m_primColor[2]; 
+            break; 
+        case ENVIRONMENT: 
+            out[0] = m_envColor[0]; 
+            out[1] = m_envColor[1]; 
+            out[2] = m_envColor[2]; 
+            break; 
+        case PRIMITIVE_ALPHA: 
+            out[0] = m_primColor[3]; 
+            out[1] = m_primColor[3]; 
+            out[2] = m_primColor[3]; 
+            break; 
+        case ENV_ALPHA: 
+            out[0] = m_envColor[3]; 
+            out[1] = m_envColor[3]; 
+            out[2] = m_envColor[3]; 
+            break; 
+        case PRIM_LOD_FRAC: 
+            out[0] = m_primLodFrac; 
+            out[1] = m_primLodFrac; 
+            out[2] = m_primLodFrac; 
+            break; 
+        case ONE: 
+            out[0] = 1.0f; 
+            out[1] = 1.0f; 
+            out[2] = 1.0f; 
+            break; 
+        case ZERO: 
+            out[0] = 0.0f; 
+            out[1] = 0.0f; 
+            out[2] = 0.0f; 
+            break; 
+    } 
+
+    //Set alpha value
+    switch ( alphaSrc ) 
+    { 
+        case PRIMITIVE_ALPHA: 
+            out[3] = m_primColor[3]; 
+            break; 
+        case ENV_ALPHA: 
+            out[3] = m_envColor[3]; 
+            break; 
+        case PRIM_LOD_FRAC: 
+            out[3] = m_primLodFrac; 
+            break; 
+        case ONE: 
+            out[3] = 1.0f; 
+            break; 
+        case ZERO: 
+            out[3] = 0.0f; 
+            break; 
+    } 
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h
new file mode 100755 (executable)
index 0000000..a6b4451
--- /dev/null
@@ -0,0 +1,129 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMBINER_BASE_H_
+#define COMBINER_BASE_H_
+
+#include "CombinerStructs.h"
+
+//Forward declarations
+struct TexEnvCombiner;
+
+//*****************************************************************************
+//* CombinerBase
+//! Base class and interface for combiners
+//! @see AdvancedTexEnvCombiner
+//! @see SimpleTexEnvCombiner
+//! @see DummyCombiner
+//*****************************************************************************
+class CombinerBase
+{
+public:
+
+    //Constructor / Destructor
+    CombinerBase();
+    ~CombinerBase();
+
+    //Set colors
+    void setFillColor(float r, float g, float b, float a);
+    void setBlendColor(float r, float g, float b, float a);
+    void setPrimColor(float r, float g, float b, float a);
+    void setEnvColor(float r, float g, float b, float a);
+
+    //Set prim LOD
+    void setPrimLodMin(unsigned int primLodMin) { m_primLodMin = primLodMin; };
+    void setPrimLodFrac(float primLodFrac) { m_primLodFrac = primLodFrac; };
+
+public:
+
+    //Get Colors
+    //----------
+
+    //! Get Blend Color
+    //! @retval float* Returns blend color as <r,g,b,a> channels (0.0-1.0)
+    float* getBlendColor() { return m_blendColor; };
+
+    //! Get Fill Color
+    //! @retval float* Returns fill color as <r,g,b,a> channels (0.0-1.0)
+    float* getFillColor()  { return m_fillColor;  };
+
+    //! Get Prim Color
+    //! @retval float* Returns prim color as <r,g,b,a> channels (0.0-1.0)
+    float* getPrimColor()  { return m_primColor;  };
+
+    //! Get Environment Color
+    //! @retval float* Returns environment color as <r,g,b,a> channels (0.0-1.0)
+    float* getEnvColor()   { return m_envColor;   };
+
+    //Get Combiner color    
+    void getCombinerColor(float out[4], short colorSource, short alphaSource);
+
+public:
+
+    //Interface
+    //---------
+
+    //* Initialize
+    //! Used to initialize combiner
+    virtual void            initialize() = 0;
+
+    //* Begin Texture Environment
+    //! Called before texture channels are updated in the RDP
+    virtual void            beginTextureUpdate() = 0;
+
+    //* End Texture Environment
+    //! Called before texture channels are updated in the RDP
+    //! @param[in] texEnv Texture environment with textures channels to be enabled
+    virtual void            endTextureUpdate(TexEnvCombiner* texEnv) = 0;   
+
+    //* Set Texture Environment Colors
+    //! Used to send combiner color to graphics API
+    virtual void            setTextureEnviromentColors(TexEnvCombiner* texEnv) = 0;
+
+    //* Set Texture Environment Environment
+    //! Used to enable textureing and set texture enviromnent for graphics API
+    //! @param[in] texEnv Texture environment with input data to graphics API 
+    virtual void            setTextureEnviroment(TexEnvCombiner* texEnv) = 0;
+
+    //* Create New Texture Enviornment
+    //! Allocates a new texture enviroment
+    //! @param[in] colorCombiner How to combine and get a color
+    //! @param[in] alphaCombiner How to combine and get an alpha value
+    //! @return The texture enviroment that was created
+    virtual TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner) = 0;
+
+protected:
+
+    CombineData m_combineData;    
+
+    //Colors
+    float m_fillColor[4] ; //!< <r,g,b,a> 
+    float m_blendColor[4]; //!< <r,g,b,a>
+    float m_primColor[4];  //!< <r,g,b,a>
+    float m_envColor[4];   //!< <r,g,b,a>
+
+    //Prim
+    unsigned int m_primLodMin;
+    float m_primLodFrac;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp
new file mode 100755 (executable)
index 0000000..3456182
--- /dev/null
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "CombinerCache.h"
+
+//-----------------------------------------------------------------------------
+//* New Compiled Combiner
+//! Function used to add decoded mux values and the result of them to the list.
+//-----------------------------------------------------------------------------
+void CombinerCache::newCompiledCombiner(unsigned long long mux, TexEnvCombiner* compiled)
+{
+    //Create new Combiner
+    CachedCombiner* newCombiner = new CachedCombiner();
+    newCombiner->mux      = mux;
+    newCombiner->compiled = compiled;
+
+    //Add Combiner to list
+    m_cachedCombiners.push_back(newCombiner);
+}
+
+//-----------------------------------------------------------------------------
+//* New Compiled Combiner
+//! Function used to retrive decoded mux values and the result of them to the list.
+//-----------------------------------------------------------------------------
+CachedCombiner* CombinerCache::findCachedCombiner(unsigned long long mux)
+{
+    for (CombinerList::iterator it = m_cachedCombiners.begin(); it!=m_cachedCombiners.end(); ++it)
+    {
+        if ( (*it)->mux == mux )
+        {
+            return (*it); //Found old combiner!!
+        }
+    }
+
+    return 0; //Could not find it
+}
+
+//-----------------------------------------------------------------------------
+//* Dispose
+//! Destroys all values in list.
+//-----------------------------------------------------------------------------
+void CombinerCache::dispose()
+{
+    for (CombinerList::iterator it = m_cachedCombiners.begin(); it!=m_cachedCombiners.end(); ++it)
+    {
+        delete (*it)->compiled;
+        delete (*it);
+    }
+
+    m_cachedCombiners.clear();
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h
new file mode 100755 (executable)
index 0000000..f63157e
--- /dev/null
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMBINER_CACHE_H_
+#define COMBINER_CACHE_H_
+
+#include "CombinerStructs.h"
+#include <list>
+
+//*****************************************************************************
+//* Cached Combiner
+//! Struct used to store decoded mux values and the result of them
+//*****************************************************************************
+struct CachedCombiner
+{
+    unsigned long long mux;               //Decoded value defining how to combine colors
+    TexEnvCombiner* compiled;
+};
+
+//*****************************************************************************
+//* Combiner Cache
+//! Class used to store and retrive decoded mux values and the result of them.
+//*****************************************************************************
+class CombinerCache
+{
+public:
+
+    //Add/Store decoded mux value and the result
+    void newCompiledCombiner(unsigned long long mux, TexEnvCombiner* compiled);
+
+    //Try to find decoded mux value, (return 0 if not found)
+    CachedCombiner* findCachedCombiner(unsigned long long mux);
+
+    //Destroy
+    void dispose();
+
+private:
+
+    typedef std::list<CachedCombiner*> CombinerList;  //!< Type used to store combiled texture combiners
+    CombinerList m_cachedCombiners;                   //!< List of cached combiners
+
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp
new file mode 100755 (executable)
index 0000000..acb458f
--- /dev/null
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+//*****************************************************************************
+// 
+// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64. 
+// http://gln64.emulation64.com/
+//
+//*****************************************************************************
+
+#include "CombinerStageCreator.h"
+
+//-----------------------------------------------------------------------------
+//* Set Stage
+//! Function used to set combiner stage, tries to simplify and optimize as 
+//! much as possible.
+//! From glN64
+//! @param[in] combineCycle Values to be added/subracted/multiplied and interpolated.
+//! @param[out] stageOut Simplified combine cycle with combiner formula.
+//-----------------------------------------------------------------------------
+void setStage(CombineCycle* combineCycle, CombinerStage* stageOut)
+{
+    // Load the first operand
+    stageOut->op[0].op = LOAD;
+    stageOut->op[0].param1 = combineCycle->loadValue;
+    stageOut->numOps = 1;
+
+    // If we're just subtracting zero, skip it
+    if (combineCycle->subValue != ZERO)
+    {
+        if (combineCycle->subValue == stageOut->op[0].param1)
+            stageOut->op[0].param1 = ZERO;
+        else
+        {
+            //Subract operation
+            stageOut->op[1].op = SUB;
+            stageOut->op[1].param1 = combineCycle->subValue;
+            stageOut->numOps++;
+        }
+    }
+
+    //Multiply operation
+    if ((stageOut->numOps > 1) || (stageOut->op[0].param1 != ZERO))
+    {
+        if (combineCycle->multValue == ZERO)
+        {
+            stageOut->numOps = 1;
+            stageOut->op[0].op = LOAD;
+            stageOut->op[0].param1 = ZERO;
+        }
+        else
+        {
+            if ( stageOut->numOps == 1 && stageOut->op[0].param1 == ONE )
+            {
+                //LOAD
+                stageOut->op[0].param1 = combineCycle->multValue;
+            }
+            else
+            {
+                //MULT
+                stageOut->op[stageOut->numOps].op = MUL;
+                stageOut->op[stageOut->numOps].param1 = combineCycle->multValue;
+                stageOut->numOps++;
+            }
+        }
+    }
+
+    //Don't bother adding zero
+    if (combineCycle->addValue != ZERO)
+    {
+            // If all we have so far is zero, then load this instead
+        if ((stageOut->numOps == 1) && (stageOut->op[0].param1 == ZERO))
+        {
+            stageOut->op[0].param1 = combineCycle->addValue;
+        }
+        else
+        {
+            stageOut->op[stageOut->numOps].op = ADD;
+            stageOut->op[stageOut->numOps].param1 = combineCycle->addValue;
+            stageOut->numOps++;
+        }
+    }
+
+    // Handle interpolation
+    if ((stageOut->numOps == 4) && (stageOut->op[1].param1 == stageOut->op[3].param1))
+    {
+        stageOut->numOps = 1;
+        stageOut->op[0].op = INTERPOLATE;
+        stageOut->op[0].param2 = stageOut->op[1].param1;
+        stageOut->op[0].param3 = stageOut->op[2].param1;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h
new file mode 100755 (executable)
index 0000000..c2e44aa
--- /dev/null
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMBINER_STAGE_CREATOR_H_
+#define COMBINER_STAGE_CREATOR_H_
+
+#include "CombinerStructs.h"
+
+//Function used to set combiner stage
+void setStage(CombineCycle* combineCycle, CombinerStage* stageOut);
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp
new file mode 100755 (executable)
index 0000000..74156e4
--- /dev/null
@@ -0,0 +1,115 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+//*****************************************************************************
+// 
+// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64.
+// http://gln64.emulation64.com/
+//
+//*****************************************************************************
+
+#include "CombinerStructs.h"
+
+//-----------------------------------------------------------------------------
+//* Merge Stages
+//! Try two merge to stages into one
+//! From glN64
+//-----------------------------------------------------------------------------
+void mergeStages(Combiner* c)
+{
+
+    // If all we have is a load in the first stage we can just replace
+    // each occurance of COMBINED in the second stage with it
+    if ((c->stage[0].numOps == 1) && (c->stage[0].op[0].op == LOAD))
+    {
+        int combined = c->stage[0].op[0].param1;
+
+        for (int i = 0; i < c->stage[1].numOps; i++)
+        {
+            c->stage[0].op[i].op = c->stage[1].op[i].op;
+            c->stage[0].op[i].param1 = (c->stage[1].op[i].param1 == COMBINED) ? combined : c->stage[1].op[i].param1;
+            c->stage[0].op[i].param2 = (c->stage[1].op[i].param2 == COMBINED) ? combined : c->stage[1].op[i].param2;
+            c->stage[0].op[i].param3 = (c->stage[1].op[i].param3 == COMBINED) ? combined : c->stage[1].op[i].param3;
+        }
+
+        c->stage[0].numOps = c->stage[1].numOps;
+        c->numStages = 1;
+    }
+    // We can't do any merging on an interpolation
+    else if (c->stage[1].op[0].op != INTERPOLATE)
+    {
+        int numCombined = 0;
+
+        // See how many times the first stage is used in the second one
+        for (int i = 0; i < c->stage[1].numOps; i++)
+            if (c->stage[1].op[i].param1 == COMBINED)
+                numCombined++;
+
+        // If it's not used, just replace the first stage with the second
+        if (numCombined == 0)
+        {
+            for (int i = 0; i < c->stage[1].numOps; i++)
+            {
+                c->stage[0].op[i].op = c->stage[1].op[i].op;
+                c->stage[0].op[i].param1 = c->stage[1].op[i].param1;
+                c->stage[0].op[i].param2 = c->stage[1].op[i].param2;
+                c->stage[0].op[i].param3 = c->stage[1].op[i].param3;
+            }
+            c->stage[0].numOps = c->stage[1].numOps;
+
+            c->numStages = 1;
+        }
+        // If it's only used once
+        else if (numCombined == 1)
+        {
+            // It's only used in the load, so stack on the ops from stage 2 on stage 1
+            if (c->stage[1].op[0].param1 == COMBINED)
+            {
+                for (int i = 1; i < c->stage[1].numOps; i++)
+                {
+                    c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[i].op;
+                    c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[i].param1;
+                    c->stage[0].numOps++;
+                }
+
+                c->numStages = 1;
+            }
+            // Otherwise, if it's used in the second op, and that op isn't SUB
+            // we can switch the parameters so it works out to tack the ops onto stage 1
+            else if ((c->stage[1].op[1].param1 == COMBINED) && (c->stage[1].op[1].op != SUB))
+            {
+                c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[1].op;
+                c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[0].param1;
+                c->stage[0].numOps++;
+
+                // If there's another op, tack it onto stage 1 too
+                if (c->stage[1].numOps > 2)
+                {
+                    c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[2].op;
+                    c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[2].param1;
+                    c->stage[0].numOps++;
+                }
+
+                c->numStages = 1;
+            }
+        }
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h
new file mode 100755 (executable)
index 0000000..829412e
--- /dev/null
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMBINER_STAGE_MERGER_H_
+#define COMBINER_STAGE_MERGER_H_
+
+struct Combiner;
+
+//Tries to merge the two stages in combiner
+void mergeStages(Combiner* c);
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h
new file mode 100755 (executable)
index 0000000..ae0f68c
--- /dev/null
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef COMBINER_STRUCTS_H_
+#define COMBINER_STRUCTS_H_
+
+#include "m64p.h"
+#include "OpenGL.h"
+
+// Internal combiner commands
+#define LOAD        0
+#define SUB            1
+#define MUL            2
+#define ADD            3
+#define INTERPOLATE 4
+
+// Internal generalized combiner inputs
+
+#define COMBINED        0
+#define TEXEL0          1
+#define TEXEL1          2
+#define PRIMITIVE       3
+#define SHADE           4
+#define ENVIRONMENT     5
+#define CENTER          6
+#define SCALE           7
+#define COMBINED_ALPHA  8
+#define TEXEL0_ALPHA    9
+#define TEXEL1_ALPHA    10
+#define PRIMITIVE_ALPHA 11
+#define SHADE_ALPHA     12
+#define ENV_ALPHA       13
+#define LOD_FRACTION    14
+#define PRIM_LOD_FRAC   15
+#define NOISE           16
+#define K4              17
+#define K5              18
+#define ONE             19
+#define ZERO            20
+
+//* Combiner data
+//! Defines how mux-values are coded.
+//TODO: check this size against GCC when i'm awake
+struct CombineData
+{
+    union
+    {
+        struct
+        {
+            // muxs1
+            unsigned    aA1     : 3;
+            unsigned    sbA1    : 3;
+            unsigned    aRGB1   : 3;
+            unsigned    aA0     : 3;
+            unsigned    sbA0    : 3;
+            unsigned    aRGB0   : 3;
+            unsigned    mA1     : 3;
+            unsigned    saA1    : 3;
+            unsigned    sbRGB1  : 4;
+            unsigned    sbRGB0  : 4;
+
+            // muxs0
+            unsigned    mRGB1   : 5;
+            unsigned    saRGB1  : 4;
+            unsigned    mA0     : 3;
+            unsigned    saA0    : 3;
+            unsigned    mRGB0   : 5;
+            unsigned    saRGB0  : 4;
+        };
+
+        struct
+        {
+            unsigned int    muxs1, muxs0;
+        };
+
+        unsigned long long    mux;
+    };
+};
+
+//! Combiner operation
+struct CombinerOp
+{
+    int op;
+    int param1;
+    int param2;
+    int param3;
+};
+
+//! Combiner Stage with combiner operations
+struct CombinerStage
+{
+    int numOps;
+    CombinerOp op[6];
+};
+
+//! Combiner with combiner stages
+struct Combiner
+{
+    int numStages;
+    CombinerStage stage[2];
+};
+
+//! Combiner cycle
+struct CombineCycle
+{
+    int loadValue;  //!< Load
+    int addValue;   //!< Addition
+    int subValue;   //!< Subract
+    int multValue;  //!< Multiplication
+};
+
+
+//*****************************************************************************
+//! Texture Environment Combiner Argument
+//! Difines a color source and mathimatical operation to be performed
+//*****************************************************************************
+struct TexEnvCombinerArg
+{
+    GLenum source;
+    GLenum operand;
+};
+
+//*****************************************************************************
+//! Texture Environment Combiner Stage
+//*****************************************************************************
+struct TexEnvCombinerStage
+{
+    unsigned short constant;
+    bool used;
+    GLenum combine;
+    TexEnvCombinerArg arg0, arg1, arg2;
+    unsigned short outputTexture;
+};
+
+//*****************************************************************************
+//* Texture Environment Combiner 
+//! Stores information how graphics API should combine colors and set 
+//! Texture environment.
+//*****************************************************************************
+struct TexEnvCombiner
+{
+    bool usesT0, usesT1, usesNoise;
+
+    GLint mode;
+
+    unsigned short usedUnits;
+    
+    struct
+    {
+        unsigned short color, secondaryColor, alpha;
+    } vertex;
+
+    TexEnvCombinerStage color[8];
+    TexEnvCombinerStage alpha[8];
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp
new file mode 100755 (executable)
index 0000000..29ff59d
--- /dev/null
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "DummyCombiner.h"
+#include "CombinerStructs.h"
+#include "ExtensionChecker.h"
+#include "MultiTexturingExt.h"
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Checks if multitexturing is supported
+//-----------------------------------------------------------------------------
+void DummyCombiner::initialize() 
+{ 
+    ARB_multitexture = isExtensionSupported("GL_ARB_multitexture"); 
+}
+
+//-----------------------------------------------------------------------------
+//* Create New Texture Enviroment
+//! Allocates a new texture enviroment
+//! @param[in] colorCombiner How to combine and get a color
+//! @param[in] alphaCombiner How to combine and get an alpha value
+//! @return The texture enviroment that was created
+//-----------------------------------------------------------------------------
+TexEnvCombiner* DummyCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner)
+{
+    TexEnvCombiner* texEnv = new TexEnvCombiner();    
+    texEnv->usesT0 = false;
+    texEnv->usesT1 = false;
+    texEnv->mode = GL_REPLACE;
+    texEnv->vertex.color = COMBINED;
+    texEnv->vertex.alpha = COMBINED;    
+
+    //For each stage in alpha combiner
+    for (int i = 0; i < alphaCombiner->numStages; i++)
+    {
+        //For each operation in stage
+        for (int j = 0; j < alphaCombiner->stage[i].numOps; j++)
+        {
+            CombinerOp* op = &colorCombiner->stage[i].op[j];
+
+            if ( op->param1 == TEXEL0 )
+            {
+                texEnv->usesT0 = true;
+            }
+        }
+    }
+    return texEnv; 
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Enviroment
+//! Sets OpenGL (enables texturing)
+//-----------------------------------------------------------------------------
+void DummyCombiner::setTextureEnviroment(TexEnvCombiner* texEnv)
+{
+    //Enable Texturing
+    if ( ARB_multitexture )
+        glActiveTextureARB( GL_TEXTURE0_ARB );
+
+    if ( texEnv->usesT0 )
+        glEnable( GL_TEXTURE_2D );
+    else
+        glDisable( GL_TEXTURE_2D );
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h
new file mode 100755 (executable)
index 0000000..3bf5ee0
--- /dev/null
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef DUMMY_COMBINER_H_
+#define DUMMY_COMBINER_H_
+
+//Include
+#include "CombinerBase.h"   //baseclass for combiners
+
+//Forward declarations
+struct TexEnvCombiner;
+struct Combiner;
+
+//*****************************************************************************
+//* Dummy Combiner
+//! Very simple combiner that does as little as possible 
+//*****************************************************************************
+class DummyCombiner : public CombinerBase
+{
+public:
+
+    //Constructor / Destructor
+    DummyCombiner() {}
+    ~DummyCombiner() {}
+
+    //Initialize
+    void initialize();
+
+    //Begin / End Texture Update
+    void beginTextureUpdate() {}
+    void endTextureUpdate(TexEnvCombiner* texEnv) {}   
+
+    //Sets texture enviorment colors
+    void setTextureEnviromentColors(TexEnvCombiner* texEnv) {}
+
+    //Create New Texture Environment
+    TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner);
+
+    //Sets texture enviorment
+    void setTextureEnviroment(TexEnvCombiner* texEnv);
+
+private:
+    
+    bool ARB_multitexture;   //!< Extension supported?
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp
new file mode 100755 (executable)
index 0000000..c5d5c4e
--- /dev/null
@@ -0,0 +1,251 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "SimpleTexEnvCombiner.h"
+#include "CombinerStructs.h"
+#include "MultiTexturingExt.h"
+#include "ExtensionChecker.h"
+#include "m64p.h"
+#include "OpenGL.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+SimpleTexEnvCombiner::SimpleTexEnvCombiner()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+SimpleTexEnvCombiner::~SimpleTexEnvCombiner()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Checks if multitexturing is supported 
+//-----------------------------------------------------------------------------
+void SimpleTexEnvCombiner::initialize()
+{
+    ARB_multitexture = isExtensionSupported("GL_ARB_multitexture");
+}
+
+//-----------------------------------------------------------------------------
+//* Begin Texture Update
+//! Called before texture channels are updated on the RDP
+//-----------------------------------------------------------------------------
+void SimpleTexEnvCombiner::beginTextureUpdate()
+{
+    //Ignore?
+}
+
+//-----------------------------------------------------------------------------
+//* End Texture Update
+//! Called after texture channels are updated on the RDP
+//! @param[in] texEnv Texture Environment
+//-----------------------------------------------------------------------------
+void SimpleTexEnvCombiner::endTextureUpdate(TexEnvCombiner* texEnv)
+{  
+    //Ignore
+}
+
+//-----------------------------------------------------------------------------
+//! Set Texture Envirorment Colors
+//! @param[in] texEnv Texture Environment
+//-----------------------------------------------------------------------------
+void SimpleTexEnvCombiner::setTextureEnviromentColors(TexEnvCombiner* texEnv)
+{
+    //Ignore
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Environment
+//! Enables texturing and sets texture environment in OpenGL
+//! @param[in] texEnv Texture Environment
+//-----------------------------------------------------------------------------
+void SimpleTexEnvCombiner::setTextureEnviroment(TexEnvCombiner* texEnv)
+{
+    if ( ARB_multitexture )
+        glActiveTextureARB( GL_TEXTURE0_ARB );
+
+    if (texEnv->usesT0 || texEnv->usesT1)
+        glEnable( GL_TEXTURE_2D );
+    else
+        glDisable( GL_TEXTURE_2D );
+
+    //Set Mode
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv->mode);
+}
+
+//-----------------------------------------------------------------------------
+//* Create New Texture Enviornment
+//! Allocates a new texture enviroment
+//! @param[in] colorCombiner How to combine and get a color
+//! @param[in] alphaCombiner How to combine and get an alpha value
+//! @return The texture enviroment that was created
+//-----------------------------------------------------------------------------
+TexEnvCombiner* SimpleTexEnvCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner)
+{
+    TexEnvCombiner* texEnv = new TexEnvCombiner();
+
+    bool m_usesTexture0 = false;
+    bool m_usesTexture1 = false;
+    int mode = GL_REPLACE;
+    unsigned short m_color = COMBINED;
+    unsigned short m_alpha = COMBINED;    
+
+    //For each stage in alpha combiner
+    for (int i = 0; i < alphaCombiner->numStages; i++)
+    {
+        //For each operation in stage
+        for (int j = 0; j < alphaCombiner->stage[i].numOps; j++)
+        {
+            CombinerOp* op = &alphaCombiner->stage[i].op[j];
+
+            //Apply operation
+            switch ( alphaCombiner->stage[i].op[j].op )
+            {
+                case LOAD:
+                    if ( op->param1 != TEXEL0_ALPHA &&  op->param1 != TEXEL1_ALPHA  )
+                    {
+                        m_alpha = op->param1;
+                        m_usesTexture0 = false;
+                        m_usesTexture1 = false;
+                    }
+                    else
+                    {
+                        mode = GL_REPLACE;
+                        m_usesTexture0 = op->param1 == TEXEL0_ALPHA;
+                        m_usesTexture1 = op->param1 == TEXEL1_ALPHA;
+                    }
+                    break;
+                case MUL: {
+                        CombinerOp* prevOp = &alphaCombiner->stage[i].op[j-1];
+
+                        if (((op->param1 == TEXEL0_ALPHA) || (op->param1 == TEXEL1_ALPHA)) &&
+                            ((prevOp->param1 != TEXEL0_ALPHA) || (prevOp->param1 != TEXEL1_ALPHA)))
+                        {
+                            mode = GL_MODULATE;
+                        }
+                        else if ( ( op->param1 != TEXEL0_ALPHA || op->param1 != TEXEL1_ALPHA) &&
+                                (prevOp->param1 == TEXEL0_ALPHA || prevOp->param1 == TEXEL1_ALPHA) )
+                        {
+                            m_alpha = op->param1;
+                            mode = GL_MODULATE;
+                        }
+                    }
+                    break;
+            }
+        }
+    }
+
+
+    //For each stage in colorCombiner
+    for (int i = 0; i < colorCombiner->numStages; i++)
+    {
+        for (int j = 0; j < colorCombiner->stage[i].numOps; j++)
+        {
+            CombinerOp* op = &colorCombiner->stage[i].op[j];
+
+            switch ( colorCombiner->stage[i].op[j].op )
+            {
+                case LOAD:
+                    if (op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA)
+                    {
+                        if ( mode == GL_MODULATE )
+                            m_color = ONE;
+
+                        m_usesTexture0 = true;
+                        m_usesTexture1 = false;
+                    }
+                    else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA )
+                    {
+                        if ( mode == GL_MODULATE )
+                            m_color = ONE;
+
+                        m_usesTexture0 = false;
+                        m_usesTexture1 = true;
+                    }
+                    else
+                    {
+                        m_color = op->param1;
+                        m_usesTexture0 = m_usesTexture1 = false;
+                    }
+                    break;
+                case MUL:
+                    if ( op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA )
+                    {
+                        if (!m_usesTexture0 && !m_usesTexture1)
+                        {
+                            mode = GL_MODULATE;
+                            m_usesTexture0 = true;
+                            m_usesTexture1 = false;
+                        }
+                    }
+                    else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA )
+                    {
+                        if (!m_usesTexture0 && !m_usesTexture1)
+                        {
+                            mode = GL_MODULATE;
+                            m_usesTexture0 = false;
+                            m_usesTexture1 = true;
+                        }
+                    }
+                    else if ( m_usesTexture0 || m_usesTexture1 )
+                    {
+                        mode = GL_MODULATE;
+                        m_color = op->param1;
+                    }
+                    break;
+                case INTERPOLATE:
+                    if ((op->param1 == TEXEL0) &&
+                        ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) &&
+                         (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) &&
+                         (op->param3 == TEXEL0_ALPHA))
+                    {
+                        mode = GL_DECAL;
+                        m_color = op->param2;
+                        m_usesTexture0 = true;
+                        m_usesTexture1 = false;
+                    }
+                    else if ((op->param1 == TEXEL0) &&
+                        ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) &&
+                         (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) &&
+                         (op->param3 == TEXEL0_ALPHA))
+                    {
+                        mode = GL_DECAL;
+                        m_color = op->param2;
+                        m_usesTexture0 = false;
+                        m_usesTexture1 = true;
+                    }
+                    break;
+            }
+        }
+    }
+
+    texEnv->usesT0         = m_usesTexture0;
+    texEnv->usesT1         = m_usesTexture1;
+    texEnv->mode           = mode;
+    texEnv->vertex.color   = m_color;
+    texEnv->vertex.alpha   = m_alpha;     
+    return texEnv;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h
new file mode 100755 (executable)
index 0000000..765c9f8
--- /dev/null
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef SIMPLE_TEX_ENV_COMBINER_H_
+#define SIMPLE_TEX_ENV_COMBINER_H_
+
+#include "GBIDefs.h"
+#include "CombinerStructs.h"
+#include "CombinerBase.h"
+
+//Forward declarations
+struct CombineCycle;
+struct CombinerStage;
+struct Combiner;
+
+//*****************************************************************************
+//! Simple Texture Environment Combiner
+//! Uses glTexEnvi to set texture environment i OpenGL.
+//*****************************************************************************
+class SimpleTexEnvCombiner : public CombinerBase
+{
+public:
+    
+    //Constructor / Destructor
+    SimpleTexEnvCombiner();
+    ~SimpleTexEnvCombiner();
+
+    //Initialize
+    void initialize();
+
+    //Begin / End Texture Update
+    void beginTextureUpdate();
+    void endTextureUpdate(TexEnvCombiner* texEnv);   
+
+    //Sets texture enviorment colors
+    void setTextureEnviromentColors(TexEnvCombiner* texEnv);
+
+    //Create New Texture Environment
+    TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner);
+
+    //Sets texture enviorment
+    void setTextureEnviroment(TexEnvCombiner* texEnv);
+
+private:
+
+    bool ARB_multitexture;   //!< Multitexture Extension supported?
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp b/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp
new file mode 100755 (executable)
index 0000000..90aec28
--- /dev/null
@@ -0,0 +1,219 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "DisplayListParser.h"
+#include "Memory.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "OpenGLRenderer.h"
+#include "GBIDefs.h"
+
+//-----------------------------------------------------------------------------
+//* Task
+//! Definition of tasks that needs to be performed  by the RSP
+//! Used to process the dlist by the RSP (Reality Signal Processor)
+//! Placed in DMEM at adress 0x04000fc0
+//-----------------------------------------------------------------------------
+typedef struct 
+{
+    unsigned int type;
+    unsigned int flags;
+    unsigned int ucode_boot;
+    unsigned int ucode_boot_size;
+    unsigned int ucode;
+    unsigned int ucode_size;
+    unsigned int ucode_data;
+    unsigned int ucode_data_size;
+    unsigned int dram_stack;
+    unsigned int dram_stack_size;
+    unsigned int output_buff;
+    unsigned int output_buff_size;
+    unsigned int data_ptr;
+    unsigned int data_size;
+    unsigned int yield_data_ptr;
+    unsigned int yield_data_size;
+} Task_t;
+
+typedef union {
+    Task_t t;
+    unsigned long long force_structure_alignment;
+} Task;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+DisplayListParser::DisplayListParser()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+DisplayListParser::~DisplayListParser()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+bool DisplayListParser::initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory)
+{
+    //Save pointers
+    m_rsp    = rsp;
+    m_rdp    = rdp;
+    m_gbi    = gbi;
+    m_memory = memory;
+
+    //Reset display list
+    m_DListStackPointer = 0;
+    for (int i=0; i<MAX_DL_STACK_SIZE; ++i)
+    {
+        m_DlistStack[i].pc = 0;
+        m_DlistStack[i].countdown = MAX_DL_COUNT;
+    }
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Process Display List
+//! Parses the display list
+//-----------------------------------------------------------------------------
+void DisplayListParser::processDisplayList()
+{
+    Task* task = (Task*)( m_memory->getDMEM(TASK_ADDRESS_RELATIVE_DMEM));
+
+
+    //Select UCode
+    m_gbi->selectUCode(task->t.ucode, task->t.ucode_data, task->t.ucode_size, task->t.ucode_data_size);
+
+    //Parse DList
+    m_DListStackPointer = 0;
+    m_DlistStack[m_DListStackPointer].pc = (unsigned int)task->t.data_ptr;
+    m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
+
+    // The main loop
+    while( m_DListStackPointer >= 0 )
+    {
+        //Cast memory pointer
+        //uint32* RDRAMu32            = (unsigned int*)graphicsInfo.RDRAM;
+        unsigned int* RDRAMu32 = m_memory->getRDRAMint32();            
+
+        //Get ucode argument from memory (vertices, textures, matrices...)
+        MicrocodeArgument* ucodeArg = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)];
+
+        //Increment program counter
+        m_DlistStack[m_DListStackPointer].pc += 8;
+
+        //Call function to execute command
+        m_gbi->m_cmds[(ucodeArg->cmd)](ucodeArg);
+
+        //Get next command        
+        MicrocodeArgument* ucodeNext =  (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)];
+        
+        //If this was a rendering command
+        if ( ucodeArg->cmd == GBI::G_TRI1 ||  
+             ucodeArg->cmd == GBI::G_TRI2 || 
+             ucodeArg->cmd == GBI::G_TRI4 || 
+             ucodeArg->cmd == GBI::G_QUAD || 
+             ucodeArg->cmd == GBI::G_DMA_TRI ) 
+        {
+            //If next is not a rendering command
+            if (  ucodeNext->cmd != GBI::G_TRI1 &&  
+                  ucodeNext->cmd != GBI::G_TRI2 && 
+                  ucodeNext->cmd != GBI::G_TRI4 && 
+                  ucodeNext->cmd != GBI::G_QUAD && 
+                  ucodeNext->cmd != GBI::G_DMA_TRI ) 
+            {
+                OpenGLRenderer::getSingleton().render();
+            }
+        }
+
+        //??
+        if ( m_DListStackPointer >= 0 && --m_DlistStack[m_DListStackPointer].countdown < 0 )
+        {
+            m_DListStackPointer--;
+        }
+    }
+
+    //Trigger interupts
+    m_rdp->triggerInterrupt();
+    m_rsp->triggerInterrupt();
+}
+
+//-----------------------------------------------------------------------------
+//! Get next word
+//-----------------------------------------------------------------------------
+unsigned int DisplayListParser::getNextWord()
+{
+    unsigned int word = *(unsigned int*)m_memory->getRDRAM( this->getPC() + 4 );
+    this->increasePC(8);
+    return word;
+}
+
+//-----------------------------------------------------------------------------
+//!< @param segmentAddress Used to retrive RDRAM address witch is used to set program counter
+//-----------------------------------------------------------------------------
+void DisplayListParser::displayList(unsigned int segmentAddress)
+{
+    unsigned int address = m_memory->getRDRAMAddress(segmentAddress);
+
+    if ( (address + 8) > m_memory->getRDRAMSize() ) {
+        return;
+    }  
+
+    if ( m_DListStackPointer < (MAX_DL_STACK_SIZE - 1))
+    {
+        m_DListStackPointer++;
+        m_DlistStack[m_DListStackPointer].pc = address;
+        m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Branch Display List
+//-----------------------------------------------------------------------------
+void DisplayListParser::branchDisplayList(unsigned int dl)
+{
+    unsigned int address = m_memory->getRDRAMAddress( dl );
+
+    if ( (address + 8) > m_memory->getRDRAMSize() ) {
+        return;
+    }  
+
+    m_DlistStack[m_DListStackPointer].pc = address;
+    m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT;
+}
+
+//-----------------------------------------------------------------------------
+//! DMA Display List
+//-----------------------------------------------------------------------------
+void DisplayListParser::DMADisplayList( unsigned int w0, unsigned int w1 )
+{
+    //unsigned int dwAddr = (w1);//RSPSegmentAddr((gfx->words.w1));
+    unsigned int dwAddr = m_memory->getRDRAMAddress(w1);//RSPSegmentAddr((gfx->words.w1));
+
+    {
+        m_DListStackPointer++;
+        m_DlistStack[m_DListStackPointer].pc = dwAddr;
+        m_DlistStack[m_DListStackPointer].countdown = (((w0)>>16)&0xFF);
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/DisplayListParser.h b/source/mupen64plus-video-arachnoid/src/DisplayListParser.h
new file mode 100755 (executable)
index 0000000..0a7412d
--- /dev/null
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef DISPLAYLIST_PARSER_H_
+#define DISPLAYLIST_PARSER_H_
+
+//Forward declaration
+class Memory;
+class RSP;
+class RDP;
+class GBI;
+
+#define MAX_DL_COUNT               100000        //!< Maximum display list count
+#define TASK_ADDRESS_RELATIVE_DMEM 0x0FC0
+//-----------------------------------------------------------------------------
+//! The display list PC stack.
+//-----------------------------------------------------------------------------
+typedef struct 
+{
+    unsigned int pc;
+    int countdown;
+} DListStack;
+
+//*****************************************************************************
+//* DisplayListParser
+//! Class for parsing and managing the displaylist
+//*****************************************************************************
+class DisplayListParser
+{
+public:
+    //Constructor / Destructor
+    DisplayListParser();
+    ~DisplayListParser();
+
+    //Initialize
+    bool initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory);
+
+    //Process/Parse the display list
+    void processDisplayList();
+
+    //Display list funcitons
+    void branchDisplayList(unsigned int dl);    
+    void displayList(unsigned int segmentAddress);
+    void DMADisplayList( unsigned int w0, unsigned int w1 );
+    //! End display list
+    void endDisplayList() { --m_DListStackPointer; }
+
+    //! Get Program Counter
+    unsigned int getPC()        { return m_DlistStack[m_DListStackPointer].pc;       }
+
+    //! Set Program Counter
+    void setPC(unsigned int pc) { m_DlistStack[m_DListStackPointer].pc = pc;         }
+
+    //! Increase Program Counter
+    void increasePC(int increment)  { m_DlistStack[m_DListStackPointer].pc += increment; }
+
+    //Get Next Word
+    unsigned int getNextWord();
+
+    //! Get Current Display List
+    DListStack& getCurrentDlist() { return m_DlistStack[m_DListStackPointer]; }
+
+private:
+
+    //Pointers
+    RSP*    m_rsp;     //! Pointer to Reality Signal Processor
+    RDP*    m_rdp;     //! Pointer to Reality Drawing Processor
+    GBI*    m_gbi;     //! Pointer to Graphics Binary Interface
+    Memory* m_memory;  //! Pointer to Memory
+    
+    //Stack used for processing the Display List
+    int m_DListStackPointer;                      //!< Current size of Display List stack 
+    static const int MAX_DL_STACK_SIZE = 32;      //!< Maximum size of Display List stack 
+    DListStack m_DlistStack[MAX_DL_STACK_SIZE];   //!< Stack used for processing the Display List
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp
new file mode 100755 (executable)
index 0000000..af1363e
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "m64p.h"
+#include "OpenGL.h"
+#include "ExtensionChecker.h"
+
+//-----------------------------------------------------------------------------
+//! Is Extension Supported
+//-----------------------------------------------------------------------------
+bool isExtensionSupported( const char *extension )
+{
+    const GLubyte *extensions = NULL;
+    const GLubyte *start;
+    GLubyte *where, *terminator;
+
+    where = (GLubyte *) strchr(extension, ' ');
+    if (where || *extension == '\0')
+        return false;
+
+    extensions = glGetString(GL_EXTENSIONS);
+
+    start = extensions;
+    for (;;)
+    {
+        where = (GLubyte *) strstr((const char *) start, extension);
+        if (!where)
+            break;
+
+        terminator = where + strlen(extension);
+        if (where == start || *(where - 1) == ' ')
+            if (*terminator == ' ' || *terminator == '\0')
+                return true;
+
+        start = terminator;
+    }
+
+    return false;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ExtensionChecker.h b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.h
new file mode 100755 (executable)
index 0000000..3623066
--- /dev/null
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef EXTENSION_CHECKER_H
+#define EXTENSION_CHECKER_H_
+
+bool isExtensionSupported( const char *extension );
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/FogManager.cpp b/source/mupen64plus-video-arachnoid/src/FogManager.cpp
new file mode 100755 (executable)
index 0000000..0625d3b
--- /dev/null
@@ -0,0 +1,199 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "FogManager.h"
+#include "ExtensionChecker.h"
+#include "m64p.h"
+#include "OpenGL.h"
+
+#ifndef GL_GLEXT_VERSION
+    //-----------------------------------------------------------------------------
+    // EXT_fog_coord functions
+    //-----------------------------------------------------------------------------
+    #ifndef GL_EXT_fog_coord
+    #define GL_EXT_fog_coord 1
+        #if defined(GL_GLEXT_PROTOTYPES) && !defined(HAVE_GLES)
+            extern void APIENTRY glFogCoordfEXT (GLfloat);
+            extern void APIENTRY glFogCoordfvEXT (const GLfloat *);
+            extern void APIENTRY glFogCoorddEXT (GLdouble);
+            extern void APIENTRY glFogCoorddvEXT (const GLdouble *);
+            extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *);
+        #endif 
+
+        typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+        typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+        typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+        typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+        typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+
+        #define GL_FOG_COORDINATE_SOURCE_EXT      0x8450
+        #define GL_FOG_COORDINATE_EXT             0x8451
+        #define GL_FOG_COORDINATE_ARRAY_EXT       0x8457
+    #endif
+
+    PFNGLFOGCOORDFEXTPROC glFogCoordfEXT;
+    PFNGLFOGCOORDFVEXTPROC glFogCoordfvEXT;
+    PFNGLFOGCOORDDEXTPROC glFogCoorddEXT;
+    PFNGLFOGCOORDDVEXTPROC glFogCoorddvEXT;
+    PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointerEXT;
+#endif
+
+#ifdef HAVE_GLES
+#define glFogi glFogf
+#endif
+
+//-----------------------------------------------------------------------------
+//! Static Variables
+//-----------------------------------------------------------------------------
+bool FogManager::m_fogExtensionsSupported = false;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+FogManager::FogManager()
+{
+    m_multiplier = 0;
+    m_offset     = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+FogManager::~FogManager()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Initializes fog extensions 
+//-----------------------------------------------------------------------------
+void FogManager::initialize()
+{
+    m_multiplier = 0;
+    m_offset     = 0;
+
+    //Initialize extensions
+    static bool fogExtensionInitialized = false;
+    if ( !fogExtensionInitialized )
+    {
+#ifndef HAVE_GLES
+        m_fogExtensionsSupported = isExtensionSupported("GL_EXT_fog_coord");
+        if ( m_fogExtensionsSupported )
+        {
+#ifndef GL_GLEXT_VERSION
+            glFogCoordfEXT       = (PFNGLFOGCOORDFEXTPROC)wglGetProcAddress( "glFogCoordfEXT" );
+            glFogCoordfvEXT      = (PFNGLFOGCOORDFVEXTPROC)wglGetProcAddress( "glFogCoordfvEXT" );
+            glFogCoorddEXT       = (PFNGLFOGCOORDDEXTPROC)wglGetProcAddress( "glFogCoorddEXT" );
+            glFogCoorddvEXT      = (PFNGLFOGCOORDDVEXTPROC)wglGetProcAddress( "glFogCoorddvEXT" );
+            glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)wglGetProcAddress( "glFogCoordPointerEXT" );
+#endif
+            fogExtensionInitialized  = true;
+        }        
+#endif
+    }
+
+#ifndef HAVE_GLES
+    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+//! Dispose
+//-----------------------------------------------------------------------------
+void FogManager::dispose()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* SetFogCoordPointer
+//! Function used to set vertex based fog
+//! @param[in] type Specifies the datatype of each fog coordinate in the array.
+//! @param[in] stride Specifies the byte offset between consecutive fog coordinates 
+//! @param[in] pointer    Specifies a pointer to the first component of the first fog coordinate in the array
+//! http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glFogCoordPointerEXT.htm
+//-----------------------------------------------------------------------------
+void FogManager::setFogCoordPointer(unsigned int type, int stride, const void* pointer)
+{
+    if ( m_fogExtensionsSupported )
+    {
+        glFogCoordPointerEXT(type, stride, pointer);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Enable Fog Coord Array
+//! Function used to enable vertex based fog
+//! @see disableFogCoordArray()
+//-----------------------------------------------------------------------------
+void FogManager::enableFogCoordArray()
+{
+    if ( m_fogExtensionsSupported )
+    {
+        glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Disable Fog Coord Array
+//! Function used to disable vertex based fog
+//! @see enableFogCoordArray()
+//-----------------------------------------------------------------------------
+void FogManager::disableFogCoordArray()
+{
+    if ( m_fogExtensionsSupported )
+    {
+        glDisableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Linear Fog
+//! Function used to set linear fog using a linear fog equation
+//! Equation for linear fog is:
+//!     <KBD> fog = (end - z) / (end - start) </KBD>
+//! where  z is the distance in  eye coordinates from the origin to the fragment being fogged
+//! @param start Specifies start (near) distance used in the linear  fog equation.  
+//!            The initial near distance is 0.
+//! @param end Specifies end (the far) distance used in the linear fog equation.  
+//!            The initial far  distance  is 1.
+//! http://www.hmug.org/man/3/glFogi.php
+//-----------------------------------------------------------------------------
+void FogManager::setLinearFog(float start, float end)
+{
+    glFogi(GL_FOG_MODE, GL_LINEAR);
+    glFogf(GL_FOG_START, start);
+    glFogf(GL_FOG_END, end);
+}
+
+//-----------------------------------------------------------------------------
+//* Set Fog Color
+//! @param r The red component of the fog color
+//! @param g The green component of the fog color
+//! @param b The blue component of the fog color
+//! @param a The alpha component of the fog color
+//-----------------------------------------------------------------------------
+void FogManager::setFogColor(float r, float g, float b, float a)
+{
+    float fogColor[4] = { r,g,b,a };
+    glFogfv(GL_FOG_COLOR, fogColor );
+}
diff --git a/source/mupen64plus-video-arachnoid/src/FogManager.h b/source/mupen64plus-video-arachnoid/src/FogManager.h
new file mode 100755 (executable)
index 0000000..9669d2f
--- /dev/null
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef FOG_MANAGER_H_
+#define FOG_MANAGER_H_
+
+//*****************************************************************************
+//* Fog Manager
+//! Class for setting fog using OpenGL
+//! @details This manager has support for vertex based using OpenGL Extensions
+//*****************************************************************************
+class FogManager
+{
+public:
+
+    //Constructor / Destructor
+    FogManager();
+    ~FogManager();
+
+    //Initialize / Dispose
+    void initialize();
+    void dispose();
+
+    //Set Fog settings
+    void setLinearFog(float start=0, float end=255);
+    void setFogColor(float r, float g, float b, float a);
+
+    //Extensions (for vertex based fog)
+    void setFogCoordPointer(unsigned int type, int stride, const void* pointer);
+    void enableFogCoordArray();
+    void disableFogCoordArray();
+
+    //Get/Set N64 Settings 
+    void setFogSettings(float multiplier, float offset) { m_multiplier = multiplier; m_offset = offset; }
+    float getMultiplier()                               { return m_multiplier;                          }
+    float getOffset()                                   { return m_offset;                              }
+
+public:
+
+    //! Is fog extension supported?
+    static bool fogExtensionsSupported() { return m_fogExtensionsSupported; }
+
+private:
+
+    static bool m_fogExtensionsSupported;  //!< Is fog extension supported
+    float m_multiplier;                    //!< Fog multiplier
+    float m_offset;                        //!< Fog offset
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp b/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp
new file mode 100755 (executable)
index 0000000..8a99ee4
--- /dev/null
@@ -0,0 +1,247 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "GBI.h"
+#include "GBIDefs.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "UCodeSelector.h"
+#include "UCodeIdentificationData.h"
+#include "OpenGLManager.h"
+#include "Logger.h"
+#include "m64p.h"
+
+//-----------------------------------------------------------------------------
+//! Static Variables
+//-----------------------------------------------------------------------------
+unsigned int GBI::G_MOVEMEM, GBI::G_MOVEWORD;
+unsigned int GBI::G_RDPHALF_1, GBI::G_RDPHALF_2, GBI::G_RDPHALF_CONT;
+unsigned int GBI::G_SPNOOP;
+unsigned int GBI::G_SETOTHERMODE_H, GBI::G_SETOTHERMODE_L;
+unsigned int GBI::G_DL, GBI::G_ENDDL, GBI::G_CULLDL, GBI::G_BRANCH_Z;
+unsigned int GBI::G_LOAD_UCODE;
+
+unsigned int GBI::G_MTX, GBI::G_POPMTX;
+unsigned int GBI::G_GEOMETRYMODE, GBI::G_SETGEOMETRYMODE, GBI::G_CLEARGEOMETRYMODE;
+unsigned int GBI::G_TEXTURE;
+unsigned int GBI::G_DMA_IO, GBI::G_DMA_DL, GBI::G_DMA_TRI, GBI::G_DMA_MTX, GBI::G_DMA_VTX, GBI::G_DMA_OFFSETS;
+unsigned int GBI::G_SPECIAL_1, GBI::G_SPECIAL_2, GBI::G_SPECIAL_3;
+unsigned int GBI::G_VTX, GBI::G_MODIFYVTX, GBI::G_VTXCOLORBASE;
+unsigned int GBI::G_TRI1, GBI::G_TRI2, GBI::G_TRI4;
+unsigned int GBI::G_QUAD, GBI::G_LINE3D;
+unsigned int GBI::G_RESERVED0, GBI::G_RESERVED1, GBI::G_RESERVED2, GBI::G_RESERVED3;
+unsigned int GBI::G_SPRITE2D_BASE;
+unsigned int GBI::G_BG_1CYC, GBI::G_BG_COPY;
+unsigned int GBI::G_OBJ_RECTANGLE, GBI::G_OBJ_SPRITE, GBI::G_OBJ_MOVEMEM;
+unsigned int GBI::G_SELECT_DL, GBI::G_OBJ_RENDERMODE, GBI::G_OBJ_RECTANGLE_R;
+unsigned int GBI::G_OBJ_LOADTXTR, GBI::G_OBJ_LDTX_SPRITE, GBI::G_OBJ_LDTX_RECT, GBI::G_OBJ_LDTX_RECT_R;
+unsigned int GBI::G_RDPHALF_0;
+
+unsigned int GBI::G_MTX_STACKSIZE;
+unsigned int GBI::G_MTX_MODELVIEW;
+unsigned int GBI::G_MTX_PROJECTION;
+unsigned int GBI::G_MTX_MUL;
+unsigned int GBI::G_MTX_LOAD;
+unsigned int GBI::G_MTX_NOPUSH;
+unsigned int GBI::G_MTX_PUSH;
+
+unsigned int GBI::G_TEXTURE_ENABLE;
+unsigned int GBI::G_SHADING_SMOOTH;
+unsigned int GBI::G_CULL_FRONT;
+unsigned int GBI::G_CULL_BACK;
+unsigned int GBI::G_CULL_BOTH;
+unsigned int GBI::G_CLIPPING;
+
+unsigned int GBI::G_MV_VIEWPORT;
+
+unsigned int GBI::G_MWO_aLIGHT_1, GBI::G_MWO_bLIGHT_1;
+unsigned int GBI::G_MWO_aLIGHT_2, GBI::G_MWO_bLIGHT_2;
+unsigned int GBI::G_MWO_aLIGHT_3, GBI::G_MWO_bLIGHT_3;
+unsigned int GBI::G_MWO_aLIGHT_4, GBI::G_MWO_bLIGHT_4;
+unsigned int GBI::G_MWO_aLIGHT_5, GBI::G_MWO_bLIGHT_5;
+unsigned int GBI::G_MWO_aLIGHT_6, GBI::G_MWO_bLIGHT_6;
+unsigned int GBI::G_MWO_aLIGHT_7, GBI::G_MWO_bLIGHT_7;
+unsigned int GBI::G_MWO_aLIGHT_8, GBI::G_MWO_bLIGHT_8;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+GBI::GBI()
+{
+    m_ucodeSelector = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+GBI::~GBI()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool GBI::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
+{
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+
+    //Reset Binary Interface
+    for(int i=0; i<256; ++i)
+    {
+        m_cmds[i] = (GBIFunc)GBI::unknownInstruction;
+    }
+
+    //Add RDP Instructions
+    m_rdpInsructions.initialize(m_rdp, dlp);
+
+    m_cmds[G_SETCIMG]            = (GBIFunc)RDPInstructions::RDP_SetCImg;
+    m_cmds[G_SETZIMG]            = (GBIFunc)RDPInstructions::RDP_SetZImg;
+    m_cmds[G_SETTIMG]            = (GBIFunc)RDPInstructions::RDP_SetTImg;
+    m_cmds[G_SETTILE]            = (GBIFunc)RDPInstructions::RDP_SetTile;
+    m_cmds[G_LOADTILE]           = (GBIFunc)RDPInstructions::RDP_LoadTile;
+    m_cmds[G_LOADBLOCK]          = (GBIFunc)RDPInstructions::RDP_LoadBlock;
+    m_cmds[G_SETTILESIZE]        = (GBIFunc)RDPInstructions::RDP_SetTileSize;
+    m_cmds[G_LOADTLUT]           = (GBIFunc)RDPInstructions::RDP_LoadTLUT;
+    m_cmds[G_FILLRECT]           = (GBIFunc)RDPInstructions::RDP_FillRect;
+    m_cmds[G_TEXRECTFLIP]        = (GBIFunc)RDPInstructions::RDP_TexRectFlip;
+    m_cmds[G_TEXRECT]            = (GBIFunc)RDPInstructions::RDP_TexRect;
+    m_cmds[G_SETENVCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetEnvColor;
+    m_cmds[G_SETPRIMCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetPrimColor;
+    m_cmds[G_SETBLENDCOLOR]      = (GBIFunc)RDPInstructions::RDP_SetBlendColor;
+    m_cmds[G_SETFOGCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetFogColor;
+    m_cmds[G_SETFILLCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetFillColor;
+    m_cmds[G_SETCOMBINE]         = (GBIFunc)RDPInstructions::RDP_SetCombine;
+    m_cmds[G_RDPSETOTHERMODE]    = (GBIFunc)RDPInstructions::RDP_SetOtherMode;
+    m_cmds[G_SETPRIMDEPTH]       = (GBIFunc)RDPInstructions::RDP_SetPrimDepth;
+    m_cmds[G_SETSCISSOR]         = (GBIFunc)RDPInstructions::RDP_SetScissor;
+    m_cmds[G_SETCONVERT]         = (GBIFunc)RDPInstructions::RDP_SetConvert;
+    m_cmds[G_SETKEYR]            = (GBIFunc)RDPInstructions::RDP_SetKeyR;
+    m_cmds[G_SETKEYGB]           = (GBIFunc)RDPInstructions::RDP_SetKeyGB;
+    m_cmds[G_NOOP]               = (GBIFunc)RDPInstructions::RDP_NoOp;
+    m_cmds[G_RDPFULLSYNC]        = (GBIFunc)RDPInstructions::RDP_FullSync;
+    m_cmds[G_RDPTILESYNC]        = (GBIFunc)RDPInstructions::RDP_TileSync;
+    m_cmds[G_RDPPIPESYNC]        = (GBIFunc)RDPInstructions::RDP_PipeSync;
+    m_cmds[G_RDPLOADSYNC]        = (GBIFunc)RDPInstructions::RDP_LoadSync;
+
+    m_ucodeSelector = new UCodeSelector();
+    if ( !m_ucodeSelector->initialize(memory) ) {
+        return false;
+    }
+
+    //Initilize Ucode
+
+    m_ucode0.initialize(m_rsp, m_rdp, memory, dlp);        //F3D
+    m_ucode1.initialize(this, m_rsp, m_rdp, memory);       //F3DEX
+    m_ucode2.initialize(this, m_rsp, m_rdp, memory, dlp);  //Golden Eye
+    m_ucode4.initialize(this, m_rsp);                      //Wave Race 64
+    m_ucode5.initialize(this, m_rsp, m_rdp, memory, dlp);  //F3DEX2
+    m_ucode6.initialize(this, m_rsp, m_rdp, memory, dlp);  //Diddy Kong Racing
+    m_ucode7.initialize(m_rsp);
+    m_ucode9.initialize(m_rsp);                            //Perfect Dark
+    m_ucode10.initialize(this, m_rsp, m_rdp, memory, dlp);
+
+    m_previusUCodeStart = -1;
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Dispose
+//-----------------------------------------------------------------------------
+void GBI::dispose()
+{
+    if ( m_ucodeSelector ) { delete m_ucodeSelector; m_ucodeSelector = 0; }
+
+    m_previusUCodeStart = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Select UCode
+//-----------------------------------------------------------------------------
+void GBI::selectUCode( unsigned int ucStart, 
+                    unsigned int ucDStart, 
+                    unsigned int ucSize, 
+                    unsigned int ucDSize)
+{
+    if ( m_previusUCodeStart == ucStart )
+    {
+        return; //Already have correct ucode no need to find one
+    }
+    m_previusUCodeStart = ucStart;
+
+    //Identify ucode
+    unsigned int ucode = m_ucodeSelector->checkUCode(ucStart, ucDStart, ucSize, ucDSize);
+
+    //Unsupported ucodes
+    if ( ucode >= 6 || ucode == 3 )
+    {
+        //MessageBox(0, 
+        //    "This graphics plugin does not support this game, please try another.", 
+        //    "Arachnoid Graphics Plugin", 
+        //    MB_OK|MB_SETFOREGROUND );
+    }
+
+    //if ( ucode == 5 )
+    //{
+    //    OpenGLManager::getSingleton().setForceDisableCulling(true);  //Do not support Face Culling?
+    //}
+
+    //Set Ucode
+    switch ( ucode )
+    {
+        case 0   : m_ucode0.initializeGBI(this); break;  //F3D    - Super Mario 64
+        case 1   : m_ucode1.initializeGBI();     break;  //F3DEX  - Mario Kart, Star Fox 64, Bomberman 64, ...
+        case 2   : m_ucode2.initializeGBI();     break;  //       - Golden Eye
+        case 3   :                                       //S2DEX  - Chou Snobow Kids, V-Rally Edition 99, Zelda Majoras Mask
+        case 4   : m_ucode4.initializeGBI();     break;  //       - Wave Racer 64
+        case 5   : m_ucode5.initializeGBI();     break;  //F3DEX2 - Donkey Kong 64, Fighter's Destiny 2, Mario Golf 64, F-Zero X, Paper Mario, ...
+        case 6   : m_ucode6.initializeGBI();     break;  //       - Diddy Kong Racing
+        case 7   : m_ucode7.initializeGBI(this); break;  //       - Yoshi's Story
+        case 8   :                                       //       - Puzzle Master 64
+        case 9   : m_ucode9.initializeGBI(this); break;  //       - Perfect Dark
+        case 10  : m_ucode10.initializeGBI();            //       - Conker The Bad Fur Day
+        case 11  : m_ucode6.initializeGBI();     break;  //       - Jet Force Gemini
+        case 12  : m_ucode1.initializeGBI();     break;  //       - 1080
+        default  : 
+            //m_ucode5.initializeGBI(this); break;  //F3DEX2
+            //m_ucode1.initializeGBI(this); 
+            m_ucode0.initializeGBI(this); 
+            break;
+    }
+
+}
+
+//-----------------------------------------------------------------------------
+//! Unknown Instruction
+//! This function will be called when the GBI can't find the correct function
+//! to call.
+//-----------------------------------------------------------------------------
+void GBI::unknownInstruction(MicrocodeArgument* arg)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("GBI - Unknown Function", M64MSG_WARNING);
+        warned = true;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBI.h b/source/mupen64plus-video-arachnoid/src/GBI/GBI.h
new file mode 100755 (executable)
index 0000000..f6cc898
--- /dev/null
@@ -0,0 +1,162 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef GRAPHIC_BINARY_INTERFACE_H_
+#define GRAPHIC_BINARY_INTERFACE_H_
+
+
+#include "UCodeDefs.h"
+#include "UCode0.h"     //Super Mario 64
+#include "UCode1.h"     //Games like Mario Kart 64, Starfox 64
+#include "UCode2.h"     //Golden Eye
+#include "UCode4.h"     //Wave Race 64
+#include "UCode5.h"     //Newer Games
+#include "UCode6.h"     //Diddy Kong Racing
+#include "UCode7.h"     //Yoshi's Story
+#include "UCode9.h"     //Perfect Dark
+#include "UCode10.h"    //Conker Bad Fur Day
+#include "RDPInstructions.h"
+
+class RSP;
+class RDP;
+class Memory;
+class UCodeSelector;
+
+// Allows easier setting of GBI commands
+#define GBI_SetGBI( command, value, target, function ) \
+    command = value; \
+    target[command] = function
+
+// Useful macros for decoding GBI command's parameters
+#define _SHIFTL( v, s, w )    (((unsigned int)v & ((0x01 << w) - 1)) << s)
+#define _SHIFTR( v, s, w )    (((unsigned int)v >> s) & ((0x01 << w) - 1))
+
+
+//-----------------------------------------------------------------------------
+//* GBI Func
+//! Definition for GBI function pointers
+//-----------------------------------------------------------------------------
+typedef void (*GBIFunc)( MicrocodeArgument* );
+
+//-----------------------------------------------------------------------------
+//* GBI
+//! Defines the Graphical Binary Interface meaning how the graphic 
+//! processors should operate.
+//-----------------------------------------------------------------------------
+class GBI
+{
+public:
+    //Constructor / Deconstructor
+    GBI();
+    ~GBI();
+
+    bool initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp);  
+    void dispose();
+    void selectUCode( unsigned int ucStart, 
+                      unsigned int ucDStart, 
+                      unsigned int ucSize, 
+                      unsigned int ucDSize);
+
+    //Dummy instruction
+    static void unknownInstruction(MicrocodeArgument* arg);
+
+    static unsigned int G_MOVEMEM, G_MOVEWORD;
+    static unsigned int G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
+    static unsigned int G_SPNOOP;
+    static unsigned int G_SETOTHERMODE_H, G_SETOTHERMODE_L;
+    static unsigned int G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z;
+    static unsigned int G_LOAD_UCODE;
+
+    static unsigned int G_MTX, G_POPMTX;
+    static unsigned int G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE;
+    static unsigned int G_TEXTURE;
+    static unsigned int G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_OFFSETS;
+    static unsigned int G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3;
+    static unsigned int G_VTX, G_MODIFYVTX, G_VTXCOLORBASE;
+    static unsigned int G_TRI1, G_TRI2, G_TRI4;
+    static unsigned int G_QUAD, G_LINE3D;
+    static unsigned int G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3;
+    static unsigned int G_SPRITE2D_BASE;
+    static unsigned int G_BG_1CYC, G_BG_COPY;
+    static unsigned int G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM;
+    static unsigned int G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R;
+    static unsigned int G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
+    static unsigned int G_RDPHALF_0;
+
+    static unsigned int G_MTX_STACKSIZE;
+    static unsigned int G_MTX_MODELVIEW;
+    static unsigned int G_MTX_PROJECTION;
+    static unsigned int G_MTX_MUL;
+    static unsigned int G_MTX_LOAD;
+    static unsigned int G_MTX_NOPUSH;
+    static unsigned int G_MTX_PUSH;
+
+    static unsigned int G_TEXTURE_ENABLE;
+    static unsigned int G_SHADING_SMOOTH;
+    static unsigned int G_CULL_FRONT;
+    static unsigned int G_CULL_BACK;
+    static unsigned int G_CULL_BOTH;
+    static unsigned int G_CLIPPING;
+
+    static unsigned int G_MV_VIEWPORT;
+
+    static unsigned int G_MWO_aLIGHT_1, G_MWO_bLIGHT_1;
+    static unsigned int G_MWO_aLIGHT_2, G_MWO_bLIGHT_2;
+    static unsigned int G_MWO_aLIGHT_3, G_MWO_bLIGHT_3;
+    static unsigned int G_MWO_aLIGHT_4, G_MWO_bLIGHT_4;
+    static unsigned int G_MWO_aLIGHT_5, G_MWO_bLIGHT_5;
+    static unsigned int G_MWO_aLIGHT_6, G_MWO_bLIGHT_6;
+    static unsigned int G_MWO_aLIGHT_7, G_MWO_bLIGHT_7;
+    static unsigned int G_MWO_aLIGHT_8, G_MWO_bLIGHT_8;
+
+public:
+
+    //Function pointer list 
+    GBIFunc m_cmds[256];  //! Function pointers to diffrent GBI instructions
+
+    //Pointers
+    RSP* m_rsp;           //!< Pointer to Reality Signal Processor 
+    RDP* m_rdp;           //!< Pointer to Reality Drawing Processor 
+    Memory* m_memory;     //!< Pointer to Memory manager (handles RDRAM, Texture Memory...)
+
+    //RDP Instruction
+    RDPInstructions m_rdpInsructions;
+
+    //UCode selector
+    UCodeSelector* m_ucodeSelector;    //!< Selects apropriete ucode depending on rom.
+
+    //UCodes
+    UCode0 m_ucode0;    //!< UCode for F3D    (Super Mario 64)
+    UCode1 m_ucode1;    //!< UCode for F3DEX  (Mario Kart 64, Star Fox 64, Fighter's Destiny...)
+    UCode2 m_ucode2;    //!< UCode for Golden Eye
+    UCode4 m_ucode4;    //!< UCode for Wave Racer 64 
+    UCode5 m_ucode5;    //!< UCode for F3DEX2
+    UCode6 m_ucode6;    //!< UCode for Diddy Kong Racing
+    UCode7 m_ucode7;    //!< UCode for Yoshi's Story
+    UCode9 m_ucode9;    //!< UCode for Perfect Dark
+    UCode10 m_ucode10;  //!< UCode for Conker Bad Fur Day
+
+    //Previus ucode
+    unsigned int m_previusUCodeStart;
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h b/source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h
new file mode 100755 (executable)
index 0000000..1d9fe9a
--- /dev/null
@@ -0,0 +1,323 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef GBI_DEFINITIONS_H_
+#define GBI_DEFINITIONS_H_
+
+#include "GBI.h"
+
+
+//TODO Write comments for each group
+
+#define G_NOOP                    0x00
+
+// These GBI commands are common to all ucodes
+
+#define    G_SETCIMG                0xFF    /*  -1 */
+#define    G_SETZIMG                0xFE    /*  -2 */
+#define    G_SETTIMG                0xFD    /*  -3 */
+#define    G_SETCOMBINE             0xFC    /*  -4 */
+#define    G_SETENVCOLOR            0xFB    /*  -5 */
+#define    G_SETPRIMCOLOR           0xFA    /*  -6 */
+#define    G_SETBLENDCOLOR          0xF9    /*  -7 */
+#define    G_SETFOGCOLOR            0xF8    /*  -8 */
+#define    G_SETFILLCOLOR           0xF7    /*  -9 */
+#define    G_FILLRECT               0xF6    /* -10 */
+#define    G_SETTILE                0xF5    /* -11 */
+#define    G_LOADTILE               0xF4    /* -12 */
+#define    G_LOADBLOCK              0xF3    /* -13 */
+#define    G_SETTILESIZE            0xF2    /* -14 */
+#define    G_LOADTLUT               0xF0    /* -16 */
+#define    G_RDPSETOTHERMODE        0xEF    /* -17 */
+#define    G_SETPRIMDEPTH           0xEE    /* -18 */
+#define    G_SETSCISSOR             0xED    /* -19 */
+#define    G_SETCONVERT             0xEC    /* -20 */
+#define    G_SETKEYR                0xEB    /* -21 */
+#define    G_SETKEYGB               0xEA    /* -22 */
+#define    G_RDPFULLSYNC            0xE9    /* -23 */
+#define    G_RDPTILESYNC            0xE8    /* -24 */
+#define    G_RDPPIPESYNC            0xE7    /* -25 */
+#define    G_RDPLOADSYNC            0xE6    /* -26 */
+#define G_TEXRECTFLIP               0xE5    /* -27 */
+#define G_TEXRECT                   0xE4    /* -28 */
+
+#define G_TRI_FILL                  0xC8    /* fill triangle:            11001000 */
+#define G_TRI_SHADE                 0xCC    /* shade triangle:           11001100 */
+#define G_TRI_TXTR                  0xCA    /* texture triangle:         11001010 */
+#define G_TRI_SHADE_TXTR            0xCE    /* shade, texture triangle:  11001110 */
+#define G_TRI_FILL_ZBUFF            0xC9    /* fill, zbuff triangle:     11001001 */
+#define G_TRI_SHADE_ZBUFF           0xCD    /* shade, zbuff triangle:    11001101 */
+#define G_TRI_TXTR_ZBUFF            0xCB    /* texture, zbuff triangle:  11001011 */
+#define G_TRI_SHADE_TXTR_ZBUFF      0xCF    /* shade, txtr, zbuff trngl: 11001111 */
+
+#define G_MV_MMTX           2    
+#define G_MV_PMTX           6
+#define G_MV_LIGHT          10
+#define G_MV_POINT          12
+#define G_MV_MATRIX         14
+
+#define G_MW_MATRIX         0x00
+#define G_MW_NUMLIGHT       0x02
+#define G_MW_CLIP           0x04
+#define G_MW_SEGMENT        0x06
+#define G_MW_FOG            0x08
+#define G_MW_LIGHTCOL       0x0A
+#define G_MW_FORCEMTX       0x0C
+#define G_MW_POINTS         0x0C
+#define    G_MW_PERSPNORM   0x0E
+
+#define G_MWO_POINT_RGBA        0x10
+#define G_MWO_POINT_ST          0x14
+#define G_MWO_POINT_XYSCREEN    0x18
+#define G_MWO_POINT_ZSCREEN     0x1C
+
+//Move Memory Defines
+#define G_MV_LOOKATY       0x82
+#define G_MV_LOOKATX       0x84
+#define G_MV_L0            0x86
+#define G_MV_L1            0x88
+#define G_MV_L2            0x8a
+#define G_MV_L3            0x8c
+#define G_MV_L4            0x8e
+#define G_MV_L5            0x90
+#define G_MV_L6            0x92
+#define G_MV_L7            0x94
+#define G_MV_TXTATT        0x96
+#define G_MV_MATRIX_1      0x9E
+#define G_MV_MATRIX_2      0x98
+#define G_MV_MATRIX_3      0x9A
+#define G_MV_MATRIX_4      0x9C
+
+
+
+// Image formats
+#define G_IM_FMT_RGBA   0
+#define G_IM_FMT_YUV    1
+#define G_IM_FMT_CI     2
+#define G_IM_FMT_IA     3
+#define G_IM_FMT_I      4
+
+// Image sizes
+#define G_IM_SIZ_4b     0
+#define G_IM_SIZ_8b     1
+#define G_IM_SIZ_16b    2
+#define G_IM_SIZ_32b    3
+#define G_IM_SIZ_DD     5
+
+#define G_TX_MIRROR     0x1
+#define G_TX_CLAMP      0x2
+
+
+
+//
+#define G_DL_PUSH      0x00
+#define G_DL_NOPUSH    0x01
+
+enum TextureMode
+{
+    TM_NORMAL      = 0,
+    TM_TEXRECT     = 1,
+    TM_BGIMAGE     = 2,
+    TM_FRAMEBUFFER = 3,
+};
+
+
+enum LoadType
+{
+    LOADTYPE_BLOCK = 0,
+    LOADTYPE_TILE  = 1,
+};
+
+/*
+ * G_SETOTHERMODE_L sft: shift count
+ */
+#define    G_MDSFT_ALPHACOMPARE     0
+#define    G_MDSFT_ZSRCSEL          2
+#define    G_MDSFT_RENDERMODE       3
+#define    G_MDSFT_BLENDER          16
+
+/*
+ * G_SETOTHERMODE_H sft: shift count
+ */
+#define    G_MDSFT_BLENDMASK        0    /* unsupported */
+#define    G_MDSFT_ALPHADITHER      4
+#define    G_MDSFT_RGBDITHER        6
+
+#define    G_MDSFT_COMBKEY          8
+#define    G_MDSFT_TEXTCONV         9
+#define    G_MDSFT_TEXTFILT        12
+#define    G_MDSFT_TEXTLUT         14
+#define    G_MDSFT_TEXTLOD         16
+#define    G_MDSFT_TEXTDETAIL      17
+#define    G_MDSFT_TEXTPERSP       19
+#define    G_MDSFT_CYCLETYPE       20
+#define    G_MDSFT_COLORDITHER     22    /* unsupported in HW 2.0 */
+#define    G_MDSFT_PIPELINE        23
+
+/* G_SETOTHERMODE_H gPipelineMode */
+#define    G_PM_1PRIMITIVE            1
+#define    G_PM_NPRIMITIVE            0
+
+//G_SETOTHERMODE_H gSetCycleType 
+enum G_CYCLE_TYPE {
+    G_CYC_1CYCLE = 0,
+    G_CYC_2CYCLE = 1,
+    G_CYC_COPY   = 2,
+    G_CYC_FILL   = 3,  
+};
+
+/* G_SETOTHERMODE_H gSetTexturePersp */
+#define G_TP_NONE                0
+#define G_TP_PERSP               1
+
+/* G_SETOTHERMODE_H gSetTextureDetail */
+#define G_TD_CLAMP               0
+#define G_TD_SHARPEN             1
+#define G_TD_DETAIL              2
+
+/* G_SETOTHERMODE_H gSetTextureLOD */
+#define G_TL_TILE                0
+#define G_TL_LOD                 1
+
+/* G_SETOTHERMODE_H gSetTextureLUT */
+#define G_TT_NONE                0
+#define G_TT_RGBA16              2
+#define G_TT_IA16                3
+
+/* G_SETOTHERMODE_H gSetTextureFilter */
+#define G_TF_POINT               0
+#define G_TF_AVERAGE             3
+#define G_TF_BILERP              2
+
+/* G_SETOTHERMODE_H gSetTextureConvert */
+#define G_TC_CONV                0
+#define G_TC_FILTCONV            5
+#define G_TC_FILT                6
+
+/* G_SETOTHERMODE_H gSetCombineKey */
+#define G_CK_NONE                0
+#define G_CK_KEY                 1
+
+/* G_SETOTHERMODE_H gSetColorDither */
+#define    G_CD_MAGICSQ          0
+#define    G_CD_BAYER            1
+#define    G_CD_NOISE            2
+
+#define    G_CD_DISABLE          3
+#define    G_CD_ENABLE           G_CD_NOISE    /* HW 1.0 compatibility mode */
+
+/* G_SETOTHERMODE_H gSetAlphaDither */
+#define    G_AD_PATTERN          0
+#define    G_AD_NOTPATTERN       1
+#define    G_AD_NOISE            2
+#define    G_AD_DISABLE          3
+
+/* G_SETOTHERMODE_L gSetAlphaCompare */
+#define    G_AC_NONE             0
+#define    G_AC_THRESHOLD        1
+#define    G_AC_DITHER           3
+
+/* G_SETOTHERMODE_L gSetDepthSource */
+#define    G_ZS_PIXEL            0
+#define    G_ZS_PRIM             1
+
+/* G_SETOTHERMODE_L gSetRenderMode */
+#define    AA_EN                 1
+#define    Z_CMP                 1
+#define    Z_UPD                 1
+#define    IM_RD                 1
+#define    CLR_ON_CVG            1
+#define    CVG_DST_CLAMP         0
+#define    CVG_DST_WRAP          1
+#define    CVG_DST_FULL          2
+#define    CVG_DST_SAVE          3
+#define    ZMODE_OPA             0
+#define    ZMODE_INTER           1
+#define    ZMODE_XLU             2
+#define    ZMODE_DEC             3
+#define    CVG_X_ALPHA           1
+#define    ALPHA_CVG_SEL         1
+#define    FORCE_BL              1
+#define    TEX_EDGE              0 // not used
+
+#define    G_SC_NON_INTERLACE    0
+#define    G_SC_EVEN_INTERLACE   2
+#define    G_SC_ODD_INTERLACE    3
+
+
+#define GBI_InitFlags( ucode ) \
+    GBI::G_MTX_STACKSIZE        = ucode##_MTX_STACKSIZE; \
+    GBI::G_MTX_MODELVIEW        = ucode##_MTX_MODELVIEW; \
+    GBI::G_MTX_PROJECTION       = ucode##_MTX_PROJECTION; \
+    GBI::G_MTX_MUL              = ucode##_MTX_MUL; \
+    GBI::G_MTX_LOAD             = ucode##_MTX_LOAD; \
+    GBI::G_MTX_NOPUSH           = ucode##_MTX_NOPUSH; \
+    GBI::G_MTX_PUSH             = ucode##_MTX_PUSH; \
+\
+    GBI::G_TEXTURE_ENABLE       = ucode##_TEXTURE_ENABLE; \
+    GBI::G_SHADING_SMOOTH       = ucode##_SHADING_SMOOTH; \
+    GBI::G_CULL_FRONT           = ucode##_CULL_FRONT; \
+    GBI::G_CULL_BACK            = ucode##_CULL_BACK; \
+    GBI::G_CULL_BOTH            = ucode##_CULL_BOTH; \
+    GBI::G_CLIPPING             = ucode##_CLIPPING; \
+\
+    GBI::G_MV_VIEWPORT          = ucode##_MV_VIEWPORT; \
+    /* \
+    GBI::G_MWO_aLIGHT_1        = ucode##_MWO_aLIGHT_1; \
+    GBI::G_MWO_bLIGHT_1        = ucode##_MWO_bLIGHT_1; \
+    GBI::G_MWO_aLIGHT_2        = ucode##_MWO_aLIGHT_2; \
+    GBI::G_MWO_bLIGHT_2        = ucode##_MWO_bLIGHT_2; \
+    GBI::G_MWO_aLIGHT_3        = ucode##_MWO_aLIGHT_3; \
+    GBI::G_MWO_bLIGHT_3        = ucode##_MWO_bLIGHT_3; \
+    GBI::G_MWO_aLIGHT_4        = ucode##_MWO_aLIGHT_4; \
+    GBI::G_MWO_bLIGHT_4        = ucode##_MWO_bLIGHT_4; \
+    GBI::G_MWO_aLIGHT_5        = ucode##_MWO_aLIGHT_5; \
+    GBI::G_MWO_bLIGHT_5        = ucode##_MWO_bLIGHT_5; \
+    GBI::G_MWO_aLIGHT_6        = ucode##_MWO_aLIGHT_6; \
+    GBI::G_MWO_bLIGHT_6        = ucode##_MWO_bLIGHT_6; \
+    GBI::G_MWO_aLIGHT_7        = ucode##_MWO_aLIGHT_7; \
+    GBI::G_MWO_bLIGHT_7        = ucode##_MWO_bLIGHT_7; \
+    GBI::G_MWO_aLIGHT_8        = ucode##_MWO_aLIGHT_8; \
+    GBI::G_MWO_bLIGHT_8        = ucode##_MWO_bLIGHT_8; \
+    */
+
+
+// Fixed point conversion factors
+#define FIXED2FLOATRECIP1    0.5f
+#define FIXED2FLOATRECIP2    0.25f
+#define FIXED2FLOATRECIP3    0.125f
+#define FIXED2FLOATRECIP4    0.0625f
+#define FIXED2FLOATRECIP5    0.03125f
+#define FIXED2FLOATRECIP6    0.015625f
+#define FIXED2FLOATRECIP7    0.0078125f
+#define FIXED2FLOATRECIP8    0.00390625f
+#define FIXED2FLOATRECIP9    0.001953125f
+#define FIXED2FLOATRECIP10   0.0009765625f
+#define FIXED2FLOATRECIP11   0.00048828125f
+#define FIXED2FLOATRECIP12   0.00024414063f
+#define FIXED2FLOATRECIP13   0.00012207031f
+#define FIXED2FLOATRECIP14   6.1035156e-05f
+#define FIXED2FLOATRECIP15   3.0517578e-05f
+#define FIXED2FLOATRECIP16   1.5258789e-05f
+
+#define _FIXED2FLOAT( v, b ) ((float)v * FIXED2FLOATRECIP##b)
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp
new file mode 100755 (executable)
index 0000000..38da3d5
--- /dev/null
@@ -0,0 +1,495 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "GraphicsPlugin.h"
+#include "VI.h"                  //Video interface
+#include "Memory.h"              //Access to memory (RDRAM, Texture Memory)
+#include "OpenGLRenderer.h"      //Renderer
+#include "FrameBuffer.h"         //Framebuffer
+#include "DisplayListParser.h"   //Displaylist parser
+#include "FogManager.h"          //Fog 
+#include "RSP.h"                 //Reality Signal Processor
+#include "RDP.h"                 //Reality Drawing Processor
+#include "GBI.h"                 //Graphics Binary Interface 
+#include "ConfigMap.h"           //Configuration
+#include "Logger.h"              //Debug logger
+#include "RomDetector.h"
+#include <ctime>
+#ifdef HAVE_GLES
+#include "eglport.h"
+#include <SDL.h>
+#include <SDL_opengles.h>
+#endif
+
+//FrameBuffer framebuffer01;
+//FrameBuffer framebuffer02;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+GraphicsPlugin::GraphicsPlugin() 
+: m_openGLMgr( OpenGLManager::getSingleton() )
+{
+    m_vi = 0;
+    m_initialized = false;
+    m_updateConfig = false;
+    m_fogManager = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+GraphicsPlugin::~GraphicsPlugin()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+// Initialize
+//-----------------------------------------------------------------------------
+bool GraphicsPlugin::initialize(GFX_INFO* graphicsInfo)
+{
+    //Initialize video output
+    if (CoreVideo_Init() != M64ERR_SUCCESS)
+    {
+        Logger::getSingleton().printMsg("Could not initialize video.", M64MSG_ERROR);
+        return false;
+    }
+
+    //Save pointer to graphics info
+    m_graphicsInfo = graphicsInfo;
+
+    m_numDListProcessed = 0;
+
+    //Detect what rom it is
+    m_romDetector = &ROMDetector::getSingleton();        
+    m_romDetector->initialize( m_graphicsInfo->HEADER );
+#ifdef HAVE_GLES
+       SDL_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, SDL_FULLSCREEN);
+    SDL_ShowCursor(SDL_DISABLE);
+       EGL_Open(m_config->fullscreenWidth, m_config->fullscreenHeight);
+#else
+    if (m_config->multiSampling > 0)
+    {
+        CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1);
+        if (m_config->multiSampling <= 2)
+            CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2);
+        else if (m_config->multiSampling <= 4)
+            CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4);
+        else if (m_config->multiSampling <= 8)
+            CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8);
+        else
+            CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16);
+    }
+
+    if (CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1) != M64ERR_SUCCESS ||
+        CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32) != M64ERR_SUCCESS ||
+        CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 24)  != M64ERR_SUCCESS)
+    {
+        Logger::getSingleton().printMsg("Could not set video attributes.", M64MSG_ERROR);
+        return false;
+    }
+
+    if (CoreVideo_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, 
+        m_config->startFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, (m64p_video_flags) 0) != M64ERR_SUCCESS)
+    {
+        Logger::getSingleton().printMsg("Could not set video mode.", M64MSG_ERROR);
+        return false;
+    }
+
+    CoreVideo_SetCaption("Arachnoid");
+#endif
+    //Initialize Video Interface
+    m_vi = new VI();
+    m_vi->calcSize(m_graphicsInfo);
+
+    //Initialize Memory
+    m_memory = new Memory();
+    if ( !m_memory->initialize(m_graphicsInfo->RDRAM, m_graphicsInfo->DMEM) ) 
+    {
+        return false;
+    }
+    
+    m_displayListParser = new DisplayListParser();
+    m_displayListParser->initialize(&m_rsp, &m_rdp, &m_gbi, m_memory);
+
+    //Init OpenGL
+    if ( !m_openGLMgr.initialize(m_config->startFullscreen, m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate, true, false) ) 
+    {
+        Logger::getSingleton().printMsg("Unable to initialize OpenGL", M64MSG_ERROR);
+        return false;
+    }
+
+    
+    m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
+
+    //Initialize Fog Manager
+    m_fogManager = new FogManager();
+    m_fogManager->initialize();
+
+
+
+    //Initialize Texture Cache
+    //! @todo Not "hardcode" TextureBitDepth.
+    m_textureCache.initialize(&m_rsp, &m_rdp, m_memory, 16);
+    m_textureCache.setMipmap( m_config->mipmapping );
+
+    //Initialize OpenGL Renderer
+    if ( !OpenGLRenderer::getSingleton().initialize(&m_rsp, &m_rdp, &m_textureCache, m_vi, m_fogManager) ) 
+    {
+        Logger::getSingleton().printMsg("Unable to initialize OpenGL Renderer", M64MSG_ERROR);
+        return false;
+    }
+
+    //Initialize Processors
+    m_rdp.initialize(m_graphicsInfo, &m_rsp, m_memory, &m_gbi, &m_textureCache, m_vi, m_displayListParser, m_fogManager);
+    m_rsp.initialize(m_graphicsInfo, &m_rdp, m_memory, m_vi, m_displayListParser, m_fogManager);
+    m_gbi.initialize(&m_rsp, &m_rdp, m_memory, m_displayListParser);    
+        
+
+    //Set Background color
+    m_openGLMgr.setClearColor(0.0f, 0.0f, 0.0f);
+    m_openGLMgr.setLighting(false);
+    glDisable(GL_LIGHTING);
+    m_openGLMgr.setCullMode(false, true);
+    m_openGLMgr.setWireFrame(m_config->wireframe);   
+
+    //Initialize framebuffer
+    //framebuffer01.initialize(width, height);
+   // framebuffer02.initialize(width, height);
+
+    m_initialized = true;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Dispose
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::dispose()
+{    
+    //Dispose of Textures
+    m_textureCache.dispose();
+
+    //Dispose of member objects
+    if ( m_vi )                { delete m_vi;                m_vi = 0;                }
+    if ( m_memory )            { delete m_memory;            m_memory = 0;            }
+    if ( m_displayListParser ) { delete m_displayListParser; m_displayListParser = 0; }
+    if ( m_fogManager )        { delete m_fogManager;        m_fogManager = 0;        }
+    
+    m_gbi.dispose();
+    m_rdp.dispose();
+    m_rsp.dispose();
+    
+    //Dispose of OpenGL
+    //framebuffer01.dispose();
+   // framebuffer02.dispose();
+    m_openGLMgr.dispose();
+
+    if (m_initialized)
+#ifdef HAVE_GLES
+       {
+               EGL_Close();
+               SDL_Quit();             // *SEB* *TODO* Close Subsystem only?
+       }
+#else
+        CoreVideo_Quit();
+#endif
+
+    m_initialized = false;
+}
+
+void renderMotionBlur()
+{
+    ///glPushMatrix();
+
+        glDisable(GL_DEPTH_TEST);            
+        glBlendFunc(GL_SRC_ALPHA,GL_ONE);    
+        glEnable(GL_BLEND);
+        glColor4f(1, 1, 1, 0.9f);  //Alpha blending
+        
+//        framebuffer01.render2();
+
+        glColor4f(1, 1, 1, 1.0f);  //Alpha blending
+        glEnable(GL_DEPTH_TEST);                        
+        glDisable(GL_BLEND);
+
+    //glPopMatrix();
+}
+
+bool animate(int frameRate)
+{
+    static clock_t lastTime;
+    clock_t currentTime = clock() * 1000 / CLOCKS_PER_SEC;
+    clock_t elapsedTime = currentTime - lastTime;
+    if (elapsedTime > ((clock_t)1000 / frameRate))
+    {
+        lastTime = currentTime;
+        return true;
+    }
+    return false;
+    
+#if 0
+    //Todo: test against new version
+    static float lastTime = 0.0f;
+    float elapsedTime = 0.0;
+    float currentTime = GetTickCount() * 0.001f; 
+    elapsedTime = currentTime - lastTime;
+
+    if( elapsedTime > (1.0f / frameRate) )
+    {
+        lastTime = currentTime;    
+        return true;
+    }
+
+    return false;
+#endif
+
+}
+
+void renderQuad()
+{
+    static float dt = 0;
+    dt += 0.2f;
+    
+    //glDisable(GL_CULL_FACE);
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+   // glRotatef(dt, 0, 1, 0);
+    {
+#ifdef HAVE_GLES
+//*SEB* *TODO*
+#else
+        glBegin(GL_QUADS);
+        {
+            glColor3f(1,0,0);   glVertex3f(-1,-1,0);
+            glColor3f(1,1,0);   glVertex3f( 1,-1,0);
+            glColor3f(0,1,1);   glVertex3f( 1, 1,0);
+            glColor3f(0,0,1);   glVertex3f(-1, 1,0);
+        }
+        glEnd();
+#endif
+    }
+    glPopMatrix();
+}
+
+void renderRedBox(float x, float y, float z, float width, float height,  float length)
+{
+    static float dt = 0;
+    dt += 10.6f;
+    glRotatef(dt, 1,1,1);
+    x = x - width  / 2;
+    y = y - height / 2;
+    z = z - length / 2;
+#ifdef HAVE_GLES
+//*SEB* *TODO*
+#else
+    glBegin(GL_QUADS);                
+        glColor3f(1,0,0);        
+        glVertex3f(x,         y,          z);
+        glVertex3f(x,         y + height, z);
+        glVertex3f(x + width, y + height, z); 
+        glVertex3f(x + width, y,          z);
+        glVertex3f(x,         y,          z + length);
+        glVertex3f(x,         y + height, z + length);
+        glVertex3f(x + width, y + height, z + length); 
+        glVertex3f(x + width, y,          z + length);        
+        glVertex3f(x,         y,          z);
+        glVertex3f(x,            y,       z + length);
+        glVertex3f(x + width, y,          z + length); 
+        glVertex3f(x + width, y,          z);
+        glVertex3f(x,         y + height, z);
+        glVertex3f(x,         y + height, z + length);
+        glVertex3f(x + width, y + height, z + length); 
+        glVertex3f(x + width, y + height, z);    
+        glVertex3f(x,         y,          z);
+        glVertex3f(x,         y,          z + length);
+        glVertex3f(x,         y + height, z + length); 
+        glVertex3f(x,         y + height, z);
+        glVertex3f(x + width, y,          z);
+        glVertex3f(x + width, y,          z + length);
+        glVertex3f(x + width, y + height, z + length); 
+        glVertex3f(x + width, y + height, z);
+        glColor3f(1,1,1);
+    glEnd();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// ProcessDisplayList
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::processDisplayList()
+{
+    if ( (m_numDListProcessed == 1 && m_romDetector->getClearType() == CT_AFTER_ONE_DISPLAY_LIST) ||
+         (m_numDListProcessed == 2 && m_romDetector->getClearType() == CT_AFTER_TWO_DISPLAY_LIST) ||
+         (m_numDListProcessed == 3 && m_romDetector->getClearType() == CT_AFTER_THREE_DISPLAY_LIST) )
+    {
+        bool scissors = OpenGLManager::getSingleton().getScissorEnabled();
+        OpenGLManager::getSingleton().setScissorEnabled(false);
+        glClear(GL_COLOR_BUFFER_BIT);
+        m_numDListProcessed = 0;
+        OpenGLManager::getSingleton().setScissorEnabled(scissors);
+    }
+
+    //Update Config?
+    if ( m_updateConfig )
+    {        
+        m_vi->calcSize(m_graphicsInfo);    
+        m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
+        OpenGLManager::getSingleton().setViewport(0, 0, m_config->windowWidth, m_config->windowHeight);
+        m_openGLMgr.setWireFrame( m_config->wireframe );
+        _setTextureCacheSize( m_config->textureCacheSize );
+        m_updateConfig = false;
+
+        //if ( OpenGLManager::getSingleton().getFullscreen() )
+        //{
+        //    //Initialize framebuffer
+        //    FrameBuffer::getSingleton().dispose();
+           // FrameBuffer::getSingleton().initialize(m_config->fullscreenWidth,  m_config->fullscreenHeight);
+        //}
+        //else
+        //{
+        //    //Initialize framebuffer
+        //    FrameBuffer::getSingleton().dispose();
+           // FrameBuffer::getSingleton().initialize(m_config->windowWidth,  m_config->windowHeight);
+        //}
+
+
+    }       
+
+    //Get Video Interface Size
+    m_vi->calcSize(m_graphicsInfo);    
+    m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
+    OpenGLManager::getSingleton().setForceDisableCulling( ROMDetector::getSingleton().getDisableFaceCulling() );
+
+    //Render Scene
+    OpenGLManager::getSingleton().beginRendering();        
+    OpenGLManager::getSingleton().setTextureing2D(true);        
+    glEnable(GL_DEPTH_TEST);                        
+    {    
+        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
+        m_rsp.reset();
+        m_rdp.reset();
+        m_openGLMgr.setCullMode(false, true);
+        m_displayListParser->processDisplayList();
+    }
+
+        //Clear Screen?
+    m_numDListProcessed++;
+
+    //glFlush();    
+//    OpenGLManager::getSingleton().endRendering();
+       OpenGLManager::getSingleton().setDrawFlag();
+    //Take screenshot?
+}
+
+//-----------------------------------------------------------------------------
+// Update Screen
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::drawScreen()
+{
+    OpenGLManager::getSingleton().endRendering();
+}
+
+void GraphicsPlugin::setDrawScreenSignal()
+{
+    m_rdp.signalUpdate();
+}
+
+//-----------------------------------------------------------------------------
+// Video Interface Status Changed
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::viStatusChanged()
+{
+    //Get new VI Size
+    m_vi->calcSize( m_graphicsInfo );
+
+    //Re Calculate Scale
+    m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
+}
+
+//-----------------------------------------------------------------------------
+// Toggle Fullscreen
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::toggleFullscreen()
+{
+    if ( m_initialized ) 
+    {   
+        CoreVideo_ToggleFullScreen();
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Take Screenshot
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::takeScreenshot(void *dest, int *width, int *height, int front)
+{
+    *width = m_config->windowWidth;
+    *height = m_config->windowHeight;
+    if (dest)
+    {
+#ifndef HAVE_GLES
+        if (front)
+            glReadBuffer(GL_FRONT);
+        else
+            glReadBuffer(GL_BACK);
+#endif
+        glReadPixels(0, 0, *width, *height, GL_RGB, GL_UNSIGNED_BYTE, dest);
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Update Configuration
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::updateConfig()
+{
+    m_updateConfig = true;
+
+    //For project 64, Give config dialog time to close before continueing
+#ifdef WIN32
+    Sleep(300); 
+#endif
+    //Resize Window
+    _setWindowMode(m_config->windowWidth, m_config->windowHeight);  
+
+    //Reinitialize OpenGL
+    OpenGLManager::getSingleton().resize(m_config->windowWidth, m_config->windowHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate);        
+}
+
+//-----------------------------------------------------------------------------
+// Set Window Mode
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::_setWindowMode(int width, int height)
+{
+    if ( m_initialized ) 
+    {
+        //TODO: is this function needed?
+        //m_windowMgr->resizeWindow(width, height);            
+    }    
+}
+
+//-----------------------------------------------------------------------------
+// Set Texture Cache Size
+//-----------------------------------------------------------------------------
+void GraphicsPlugin::_setTextureCacheSize(int sizeInBytes)
+{
+
+}
diff --git a/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h
new file mode 100755 (executable)
index 0000000..ba2ddf0
--- /dev/null
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef GRAPHICS_PLUGIN_H_
+#define GRAPHICS_PLUGIN_H_
+
+#include "TextureCache.h"
+#include "OpenGLManager.h"         //Initializes OpenGL and handles OpenGL states
+#include "RSP.h"
+#include "RDP.h"
+
+//Forward declarations
+//struct GFX_INFO;
+class VI;
+class Memory;
+class DisplayListParser;
+class FogManager;
+class ROMDetector;
+struct ConfigMap;
+
+//*****************************************************************************
+//* Graphics Plugin
+//! Main class for application
+//*****************************************************************************
+class GraphicsPlugin
+{
+public:
+
+    //Constructor / Destructor
+    GraphicsPlugin();
+    ~GraphicsPlugin();
+
+    //Set Configuration
+    void setConfig(ConfigMap* config) { m_config = config; } 
+    void updateConfig();
+
+    //Function called when rom will be opened
+    bool initialize(GFX_INFO* graphicsInfo);
+    
+    //Render
+    void processDisplayList();
+    void drawScreen();
+    void setDrawScreenSignal();
+    
+    //Toggle Fullscreen
+    void toggleFullscreen();
+
+    //Take Screenshot
+    void takeScreenshot(void *dest, int *width, int *height, int front);
+
+    //Called when the video interface has been changed
+    void viStatusChanged();
+
+    //Function called when rom will be closed
+    void dispose();
+
+private:
+
+    //Config Options
+    void _setWindowMode(int width, int height);
+    void _setTextureCacheSize(int sizeInBytes);
+
+    void _motionBlur();
+
+private:
+
+    GFX_INFO*             m_graphicsInfo;        //!< Information about window, memory...
+    RSP                   m_rsp;                 //!< Reality Signal Processor, does transform, clipping, lighting, triangle setup
+    RDP                   m_rdp;                 //!< Reality Drawing Processor
+    GBI                   m_gbi;                 //!< Graphics Binary Interface, handles mapping of GBI-commands
+    VI*                   m_vi;                  //!< Video Interface
+    Memory*               m_memory;              //!< Handle RDRAM, Texture Memory and Segments
+    TextureCache          m_textureCache;        //!< Save used texture for reuse
+    ROMDetector*          m_romDetector;         //!< 
+    OpenGLManager&        m_openGLMgr;           //!< Handles initialization of OpenGL and OpenGL states.
+    DisplayListParser*    m_displayListParser;   //!< Parses and performs instructions from emulator
+    ConfigMap*            m_config;              //!< Settings from config dialog/file
+    FogManager*           m_fogManager;          //!< Handles fog extension
+    bool                  m_updateConfig;        //!< Does configuration need to be updated?
+    bool                  m_initialized;         //!< Have graphics plugin been initialized?
+    int                   m_numDListProcessed; 
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/Memory.cpp b/source/mupen64plus-video-arachnoid/src/Memory.cpp
new file mode 100755 (executable)
index 0000000..f4f8002
--- /dev/null
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "Memory.h"
+
+//-----------------------------------------------------------------------------
+//* Static variables
+//-----------------------------------------------------------------------------
+unsigned long long Memory::m_TMEM[512] = {0};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+Memory::Memory()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+Memory::~Memory()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Saves pointers to memory areas, resets segment register, and detects
+//! size of RDRAM.
+//! @param RDRAM Pointer to "Rambus Dynamic Random Access Memory"
+//! @param DMEM Pointer to "RSP Data Memory"
+//-----------------------------------------------------------------------------
+bool Memory::initialize(unsigned char* RDRAM, unsigned char* DMEM)
+{
+    //Save pointer to memory
+    m_RDRAM = RDRAM;
+    m_DMEM = DMEM;
+
+    //Reset Segment
+    for (int i=0; i<16; ++i) 
+    {
+        m_segments[i] = 0;   
+    }
+
+    //Reset Texture Memory
+    //for (int i=0; i<512; ++i)
+    //{
+    //    m_TMEM[i] = 0;
+    //}    
+
+    m_RDRAMSize = 0x800000;
+    return true;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/Memory.h b/source/mupen64plus-video-arachnoid/src/Memory.h
new file mode 100755 (executable)
index 0000000..792dc0a
--- /dev/null
@@ -0,0 +1,78 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MEMORY_H_
+#define MEMORY_H_
+
+//*****************************************************************************
+//* Memory
+//! Handle RDRAM, Texture Memory and Segments
+//*****************************************************************************
+class Memory
+{
+public:
+
+    //Constructor / Destructor
+    Memory();
+    ~Memory();
+
+    //Initialize
+    bool initialize(unsigned char* RDRAM, unsigned char* DMEM);
+
+    //Get RDRAM
+
+    unsigned char*  getRDRAM(int address=0)                { return &m_RDRAM[address]; }
+    unsigned int*   getRDRAMint32()                        { return (unsigned int*)m_RDRAM; }
+    unsigned int    getRDRAMSize()                         { return m_RDRAMSize; }
+
+    //Get DMEM
+    unsigned char*  getDMEM(int address=0)                 { return &m_DMEM[address]; }
+
+    //Get Texture memory
+    static unsigned long long* getTextureMemory(int address=0) { return &m_TMEM[address]; }
+
+    //Get Segment adress
+    unsigned int getRDRAMAddress(unsigned int segmentAddress) 
+    {         
+        return (m_segments[(segmentAddress >> 24) & 0x0F] + (segmentAddress & 0x00FFFFFF)) & 0x00FFFFFF; 
+    }
+
+    void setSegment(unsigned int address, unsigned int value)
+    {
+        if ( address >= 16 ) {
+            //ERROR
+            return;
+        }
+
+        m_segments[address] = value;
+    }
+
+private:
+    
+    unsigned char*          m_RDRAM;          //!< Rambus Dynamic Random Access Memory
+    unsigned char*          m_DMEM;           //!< RSP Data Memory
+    static unsigned long long m_TMEM[512];    //!< Texture Memory        
+    unsigned int           m_segments[16];    //!< Temporary memory for storing segment values
+    unsigned int           m_RDRAMSize;       //!< Size of RDRAM
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp
new file mode 100755 (executable)
index 0000000..13aa92f
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "MultiTexturingExt.h"
+#include "ExtensionChecker.h"
+
+
+//Multi Texturing functions
+#if !defined(GL_GLEXT_VERSION) && !defined(HAVE_GLES)
+PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
+PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
+PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
+#endif
+bool g_MultiTextureARBSupport = false;
+
+//-----------------------------------------------------------------------------
+//! Function for initializeing multitextureing extensions
+//-----------------------------------------------------------------------------
+bool initializeMultiTexturingExtensions()
+{
+    //Initialize Extentions
+#ifdef HAVE_GLES
+       g_MultiTextureARBSupport = true;
+       return true;
+#else
+    g_MultiTextureARBSupport = isExtensionSupported("GL_ARB_multitexture");
+    if ( g_MultiTextureARBSupport )
+    {
+#ifndef GL_GLEXT_VERSION
+        glActiveTextureARB          = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress( "glActiveTextureARB" );
+        glClientActiveTextureARB    = (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress( "glClientActiveTextureARB" );
+        glMultiTexCoord2fARB        = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress( "glMultiTexCoord2fARB" );
+#endif
+        return true;
+    }
+    return false;
+#endif
+}
diff --git a/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h
new file mode 100755 (executable)
index 0000000..ba55214
--- /dev/null
@@ -0,0 +1,153 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MULTI_TEXTURING_EXTENSION_H_
+#define MULTI_TEXTURING_EXTENSION_H_
+
+#include "m64p.h"
+#include "OpenGL.h"
+
+#ifndef GL_GLEXT_VERSION
+    //Multi Texturing Definitions
+    #if !defined(GL_ARB_multitexture) && !defined(HAVE_GLES)
+        #define GL_TEXTURE0_ARB                   0x84C0
+        #define GL_TEXTURE1_ARB                   0x84C1
+        #define GL_TEXTURE2_ARB                   0x84C2
+        #define GL_TEXTURE3_ARB                   0x84C3
+        #define GL_TEXTURE4_ARB                   0x84C4
+        #define GL_TEXTURE5_ARB                   0x84C5
+        #define GL_TEXTURE6_ARB                   0x84C6
+        #define GL_TEXTURE7_ARB                   0x84C7
+        #define GL_TEXTURE8_ARB                   0x84C8
+        #define GL_TEXTURE9_ARB                   0x84C9
+        #define GL_TEXTURE10_ARB                  0x84CA
+        #define GL_TEXTURE11_ARB                  0x84CB
+        #define GL_TEXTURE12_ARB                  0x84CC
+        #define GL_TEXTURE13_ARB                  0x84CD
+        #define GL_TEXTURE14_ARB                  0x84CE
+        #define GL_TEXTURE15_ARB                  0x84CF
+        #define GL_TEXTURE16_ARB                  0x84D0
+        #define GL_TEXTURE17_ARB                  0x84D1
+        #define GL_TEXTURE18_ARB                  0x84D2
+        #define GL_TEXTURE19_ARB                  0x84D3
+        #define GL_TEXTURE20_ARB                  0x84D4
+        #define GL_TEXTURE21_ARB                  0x84D5
+        #define GL_TEXTURE22_ARB                  0x84D6
+        #define GL_TEXTURE23_ARB                  0x84D7
+        #define GL_TEXTURE24_ARB                  0x84D8
+        #define GL_TEXTURE25_ARB                  0x84D9
+        #define GL_TEXTURE26_ARB                  0x84DA
+        #define GL_TEXTURE27_ARB                  0x84DB
+        #define GL_TEXTURE28_ARB                  0x84DC
+        #define GL_TEXTURE29_ARB                  0x84DD
+        #define GL_TEXTURE30_ARB                  0x84DE
+        #define GL_TEXTURE31_ARB                  0x84DF
+        #define GL_ACTIVE_TEXTURE_ARB             0x84E0
+        #define GL_CLIENT_ACTIVE_TEXTURE_ARB      0x84E1
+        #define GL_MAX_TEXTURE_UNITS_ARB          0x84E2
+    #endif
+
+    //Multitexturing Functions
+    #if !defined(GL_ARB_multitexture) && !defined(HAVE_GLES)
+    #define GL_ARB_multitexture 1
+        #ifdef GL_GLEXT_PROTOTYPES
+            extern void APIENTRY glActiveTextureARB (GLenum);
+            extern void APIENTRY glClientActiveTextureARB (GLenum);
+            extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble);
+            extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *);
+            extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat);
+            extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *);
+            extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint);
+            extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *);
+            extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort);
+            extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *);
+            extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble);
+            extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *);
+            extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat);
+            extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *);
+            extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint);
+            extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *);
+            extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort);
+            extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *);
+            extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble);
+            extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *);
+            extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat);
+            extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *);
+            extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint);
+            extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *);
+            extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort);
+            extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *);
+            extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
+            extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *);
+            extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+            extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *);
+            extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint);
+            extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *);
+            extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort);
+            extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *);
+        #endif /* GL_GLEXT_PROTOTYPES */
+        typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+        typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+        typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+
+        extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
+        extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
+        extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
+    #endif
+#endif
+extern bool g_MultiTextureARBSupport;
+
+//Function for initializing multitexturing extensions
+bool initializeMultiTexturingExtensions();
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/N64Games.h b/source/mupen64plus-video-arachnoid/src/N64Games.h
new file mode 100755 (executable)
index 0000000..6e7f43e
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef N64_GAMES_H_
+#define N64_GAMES_H_
+
+//List of N64 Games
+enum N64_ROM_ID
+{
+    UNKNOWN_ROM,
+    _1080_SNOWBOARDING,
+    BANJO_KAZOOIE,
+    BANJO_TOOIE,
+    BOMBERMAN_64,
+    CONKERS_BAD_FUR_DAY,
+    DIDDY_KONG_RACING,
+    DONKEY_KONG_64,
+    DR_MARIO,
+    FIGHTERS_DESTINY,
+    FIGHTER_DESTINY_2,
+    F_ZERO_X,
+    GOLDEN_EYE,
+    LEGEND_OF_ZELDA_OCARINA_OF_TIME,
+    MARIO_KART_64,
+    PAPER_MARIO,
+    PERFECT_DARK,
+    SUPER_MARIO_64,
+    SUPER_SMASH_BROS,
+    STAR_FOX_64,        
+    SOUTH_PARK_RALLY,    
+    WAVE_RACE_64,
+    WORLD_DRIVER_CHAMPOINSHIP,
+    YOSHIS_STORY,
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/OpenGL.h b/source/mupen64plus-video-arachnoid/src/OpenGL.h
new file mode 100755 (executable)
index 0000000..7d991e1
--- /dev/null
@@ -0,0 +1,119 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+#ifndef OPENGL_H
+#define OPENGL_H
+
+#ifndef WIN32
+    #define GL_GLEXT_PROTOTYPES
+#endif
+#if defined(__MACOSX__)
+#include <OpenGL/gl.h>
+#elif defined(__MACOS__)
+#include <gl.h>
+#else
+#ifdef HAVE_GLES
+#include <GLES/gl.h>
+#include "eglport.h"
+#include <SDL_opengles.h>
+#define GL_CLAMP                        GL_CLAMP_TO_EDGE
+#define GL_MAX_TEXTURE_UNITS_ARB        GL_MAX_TEXTURE_IMAGE_UNITS
+#define GL_MIRRORED_REPEAT_ARB          GL_MIRRORED_REPEAT_OES
+#define GL_MIRRORED_REPEAT_IBM          GL_MIRRORED_REPEAT_OES
+#define GL_TEXTURE0_ARB                        GL_TEXTURE0
+#define GL_TEXTURE1_ARB                        GL_TEXTURE1
+#define GL_TEXTURE2_ARB                        GL_TEXTURE2
+#define GL_TEXTURE3_ARB                        GL_TEXTURE3
+#define GL_TEXTURE4_ARB                        GL_TEXTURE4
+#define GL_TEXTURE5_ARB                        GL_TEXTURE5
+#define GL_TEXTURE6_ARB                        GL_TEXTURE6
+#define GL_TEXTURE7_ARB                        GL_TEXTURE7
+#define GL_ADD_SIGNED_ARB              GL_ADD_SIGNED
+#define GL_SUBTRACT_ARB                        GL_SUBTRACT
+#define GL_INTERPOLATE_ARB             GL_INTERPOLATE
+#define GL_CONSTANT_ARB                        GL_CONSTANT
+#define GL_PREVIOUS_ARB                        GL_PREVIOUS
+#define GL_COMBINE_ARB                 GL_COMBINE
+#define GL_COMBINE_RGB_ARB             GL_COMBINE_RGB
+#define GL_COMBINE_ALPHA_ARB   GL_COMBINE_ALPHA
+#define GL_PRIMARY_COLOR_ARB   GL_PRIMARY_COLOR
+#define GL_SOURCE0_RGB_ARB             GL_SRC0_RGB
+#define GL_OPERAND0_RGB_ARB            GL_OPERAND0_RGB
+#define GL_SOURCE1_RGB_ARB             GL_SRC1_RGB
+#define GL_OPERAND1_RGB_ARB            GL_OPERAND1_RGB
+#define GL_SOURCE2_RGB_ARB             GL_SRC2_RGB
+#define GL_OPERAND2_RGB_ARB            GL_OPERAND2_RGB
+#define GL_SOURCE3_RGB_ARB             GL_SRC3_RGB
+#define GL_OPERAND3_RGB_ARB            GL_OPERAND3_RGB
+#define GL_SOURCE0_ALPHA_ARB           GL_SRC0_ALPHA
+#define GL_OPERAND0_ALPHA_ARB          GL_OPERAND0_ALPHA
+#define GL_SOURCE1_ALPHA_ARB           GL_SRC1_ALPHA
+#define GL_OPERAND1_ALPHA_ARB          GL_OPERAND1_ALPHA
+#define GL_SOURCE2_ALPHA_ARB           GL_SRC2_ALPHA
+#define GL_OPERAND2_ALPHA_ARB          GL_OPERAND2_ALPHA
+#define GL_SOURCE3_ALPHA_ARB           GL_SRC3_ALPHA
+#define GL_OPERAND3_ALPHA_ARB          GL_OPERAND3_ALPHA
+#define GL_MAX_TEXTURE_IMAGE_UNITS     GL_MAX_TEXTURE_UNITS
+
+#define GL_RGBA8                                       GL_RGBA
+#define        GL_RGB5_A1                                      0x8057 
+#define GL_RGBA4                                       0x8056
+
+#define glClearDepth                    glClearDepthf
+#define glDepthRange                                   glDepthRangef
+#define glOrtho                                                        glOrthof
+
+#define glColor4fv(a)                                          glColor4f(a[0], a[1], a[2], a[3])
+
+#define glActiveTextureARB                             glActiveTexture
+#define glClientActiveTextureARB               glClientActiveTexture
+#define APIENTRYP              GL_API
+#define GLdouble               GLfloat
+
+// save of GL Array
+extern GLint   glsav_col_size;
+extern GLenum  glsav_col_type;
+extern GLsizei glsav_col_stride;
+extern GLvoid* glsav_col_array;
+
+extern GLint   glsav_vtx_size;
+extern GLenum  glsav_vtx_type;
+extern GLsizei glsav_vtx_stride;
+extern GLvoid* glsav_vtx_array;
+
+extern GLint   glsav_tex_size;
+extern GLenum  glsav_tex_type;
+extern GLsizei glsav_tex_stride;
+extern GLvoid* glsav_tex_array;
+
+extern GLint   glsav_tex1_size;
+extern GLenum  glsav_tex1_type;
+extern GLsizei glsav_tex1_stride;
+extern GLvoid* glsav_tex1_array;
+
+#else
+#include <GL/gl.h>
+#endif
+#endif
+#ifndef WIN32
+    #include <GL/glext.h>
+#endif
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp b/source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp
new file mode 100755 (executable)
index 0000000..cf434a7
--- /dev/null
@@ -0,0 +1,349 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "OpenGLManager.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+OpenGLManager::OpenGLManager()
+{
+    m_forceDisableCulling = false;
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize 
+//! Initializes OpenGL. 
+//
+//! @param fullscreen   will render scene in fullscreen if true
+//! @param width        width of window or width of screen resolution
+//! @param height       height of window or height of screen resolution
+//! @param bitDepth     bitDepth to use
+//! @param refreshRate  refresh frequency to use
+//! @param vSync        limits frame rate to the monitor's refresh frequency
+//! @param hideCursor   hides mouse coursor if true
+//-----------------------------------------------------------------------------
+bool OpenGLManager::initialize(bool fullscreen, int width, int height, int bitDepth, int refreshRate, bool vSync, bool hideCursor)
+{
+    m_width       = width;
+    m_height      = height;
+    m_bitDepth    = bitDepth;
+    m_refreshRate = refreshRate;
+    m_fullscreen  = fullscreen;
+    m_renderingCallback = NULL;
+    //Set OpenGL Settings
+    setClearColor(0.0f, 0.0f, 0.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_CULL_FACE);
+
+    //Set render states
+    setCullMode(false, true);
+    setTextureing2D(false);
+    setLighting(false);
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Set Viewport
+//-----------------------------------------------------------------------------
+void OpenGLManager::setViewport( int x, int y, int width, int height, float zNear, float zFar )
+{
+    glViewport(x, y, width, height); 
+
+    //glViewport( gSP.viewport.x * OGL.scaleX, 
+    //           (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset, 
+    //            gSP.viewport.width * OGL.scaleX, 
+    //            gSP.viewport.height * OGL.scaleY 
+    //         ); 
+
+    //glDepthRange( 0.0f, 1.0f );//gSP.viewport.nearz, gSP.viewport.farz );
+    glDepthRange( zNear, zFar );
+}
+
+//-----------------------------------------------------------------------------
+//* Set Scissor
+//! glScissor defines a rectangle, called the scissor box, in window coordinates. 
+//! Only pixels inside the box are allowed to be modified.
+//! glScissor(0,0,1,1) allows modification of only the lower left pixel in the window
+//! glScissor(0,0,0,0) doesn't allow modification of any pixels in the window.
+//!
+//! @param x,y Specify the lower left corner of the box.  Defualt (0, 0).
+//! @param width,height Specify the width and height of the box.
+//-----------------------------------------------------------------------------
+void OpenGLManager::setScissor(int x, int y, int width, int height)
+{
+    glScissor(x,y, width, height);
+}
+
+
+//-----------------------------------------------------------------------------
+// Resize
+//-----------------------------------------------------------------------------
+void OpenGLManager::resize(int width, int height, int bitDepth, int refreshRate)
+{
+#if 0
+    dispose();
+    initialize(m_fullscreen, width, height, bitDepth, refreshRate, true, false);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Toggle Fullscreen
+//-----------------------------------------------------------------------------
+bool OpenGLManager::toggleFullscreen()
+{
+#if 0
+    dispose();
+    return initialize(!m_fullscreen, m_width, m_height, m_bitDepth, m_refreshRate,  true, !m_fullscreen);
+#endif
+    return false;
+}
+
+//-----------------------------------------------------------------------------
+//* Start Rendering 
+//! Should be called before you render everything with OpenGL
+//-----------------------------------------------------------------------------
+void OpenGLManager::beginRendering()
+{
+    glDepthMask( true );
+    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+}
+
+//-----------------------------------------------------------------------------
+//* End Rendering
+//! Should be called after you have rendered everything with OpenGL
+//-----------------------------------------------------------------------------
+void OpenGLManager::endRendering()
+{
+    glFinish();
+    if (m_renderingCallback)
+        m_renderingCallback(m_drawFlag);
+    if (m_drawFlag) {
+       m_drawFlag = 0;
+#ifdef HAVE_GLES
+       EGL_SwapBuffers();
+#else
+    CoreVideo_GL_SwapBuffers();
+#endif
+    }
+    //glFlush();
+}
+
+//-----------------------------------------------------------------------------
+// Set Wireframe
+//-----------------------------------------------------------------------------
+void OpenGLManager::setWireFrame(bool wireframe)
+{
+    m_wireframe = wireframe;
+#ifndef HAVE_GLES
+    if ( wireframe )
+    {
+        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+    }
+    else
+    {
+        glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+    }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Set ZBuffer Enabled
+//-----------------------------------------------------------------------------
+void OpenGLManager::setZBufferEnabled(bool enable)
+{
+    if ( enable ) 
+    {
+        glEnable( GL_DEPTH_TEST );
+    }
+    else 
+    {
+        glDisable( GL_DEPTH_TEST );
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Get ZBuffer Enabled
+//-----------------------------------------------------------------------------
+bool OpenGLManager::getZBufferEnabled()
+{
+    return (glIsEnabled(GL_DEPTH_TEST) == GL_TRUE);
+}
+
+//-----------------------------------------------------------------------------
+// Set Lighting
+//-----------------------------------------------------------------------------
+void OpenGLManager::setLighting(bool lighting)
+{
+    m_lighting = lighting;
+    if ( lighting ) {
+        //glEnable(GL_LIGHTING);  We dont use this type of lighting (Nintendo 64 specific)
+    }
+    else {
+        glDisable(GL_LIGHTING);
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Get Lighting
+//-----------------------------------------------------------------------------
+bool OpenGLManager::getLightingEnabled()
+{
+    return m_lighting;
+    //return (glIsEnabled(GL_LIGHTING) == GL_TRUE);  We dont use this type of lighting (Nintendo 64 specific)
+}
+
+//-----------------------------------------------------------------------------
+// Set Fog
+//-----------------------------------------------------------------------------
+void OpenGLManager::setFogEnabled(bool fog)
+{
+    if ( fog ) 
+        glEnable(GL_FOG);
+    else 
+        glDisable(GL_FOG);
+}
+
+//-----------------------------------------------------------------------------
+// Get Fog
+//-----------------------------------------------------------------------------
+bool OpenGLManager::getFogEnabled()
+{
+    return (glIsEnabled(GL_FOG) == GL_TRUE);
+}
+
+//-----------------------------------------------------------------------------
+// Set Texturing
+//-----------------------------------------------------------------------------
+void OpenGLManager::setTextureing2D(bool textureing)
+{
+    if ( textureing ) 
+        glEnable(GL_TEXTURE_2D);
+    else
+        glDisable(GL_TEXTURE_2D);
+}
+
+//-----------------------------------------------------------------------------
+// Get Texturing
+//-----------------------------------------------------------------------------
+bool getTextureing2DEnabled()
+{
+    return (glIsEnabled(GL_TEXTURE_2D) == GL_TRUE);
+}
+
+//-----------------------------------------------------------------------------
+// Set Alpha Test Enabled
+//-----------------------------------------------------------------------------
+void OpenGLManager::setAlphaTest(bool alphaTestEnable)
+{
+    if ( alphaTestEnable )
+        glEnable(GL_ALPHA_TEST);
+    else
+        glDisable(GL_ALPHA_TEST);
+}
+
+//-----------------------------------------------------------------------------
+// Get Alpha Test Enabled
+//-----------------------------------------------------------------------------
+bool getAlphaTestEnabled()
+{
+    return (glIsEnabled(GL_ALPHA_TEST) == GL_TRUE);
+}
+
+//-----------------------------------------------------------------------------
+// Scissor
+//-----------------------------------------------------------------------------
+void OpenGLManager::setScissorEnabled(bool enable)
+{
+    if ( enable )
+        glEnable(GL_SCISSOR_TEST);
+    else
+        glDisable(GL_SCISSOR_TEST);
+}
+
+bool OpenGLManager::getScissorEnabled()
+{
+    return (glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE); 
+}
+
+//-----------------------------------------------------------------------------
+// Set Cull Mode
+//-----------------------------------------------------------------------------
+void OpenGLManager::setCullMode(bool cullFront, bool cullBack)
+{
+    if( cullFront && cullBack )
+    {
+        glEnable(GL_CULL_FACE);
+        glCullFace(GL_FRONT_AND_BACK);        
+    }
+    else if( cullFront )
+    {
+        glEnable(GL_CULL_FACE);
+        glCullFace(GL_FRONT);        
+    }
+    else if( cullBack )
+    {
+        glEnable(GL_CULL_FACE);
+        glCullFace(GL_BACK);        
+    }
+    else
+    {
+        glDisable(GL_CULL_FACE);
+    }
+
+    //Override Face Culling?
+    if ( m_forceDisableCulling )
+    {        
+        glDisable(GL_CULL_FACE);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Dispose
+//! Restores old display settings and destroys the rendering context
+//-----------------------------------------------------------------------------
+void OpenGLManager::dispose()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+OpenGLManager::~OpenGLManager()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//! 2D coordinats are in proportion to N64 viewport (vi), but we use
+//! a viewport of another size, there for we need to scale the coordinats.
+//! This function calculates that scale.
+//! @param viWidth The videointerface width that defines the n64 resolution
+//! @param viHeight The videointerface height that defines the n64 resolution
+//-----------------------------------------------------------------------------
+void OpenGLManager::calcViewScale(int viWidth, int viHeight)
+{
+    m_scaleX = m_width / (float)viWidth;
+    m_scaleY = m_height / (float)viHeight;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/OpenGLManager.h b/source/mupen64plus-video-arachnoid/src/OpenGLManager.h
new file mode 100755 (executable)
index 0000000..3359cf2
--- /dev/null
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef OPEN_GL_Manager_H_
+#define OPEN_GL_Manager_H_
+
+//OpenGL includes
+#include "m64p.h"
+#include "OpenGL.h"
+
+//*****************************************************************************
+//* OpenGL Manager Class                                                        
+//! Singelton class for initializing OpenGL and contolling OpenGL states. 
+//*****************************************************************************
+class OpenGLManager
+{
+public: 
+
+    //Destructor
+    ~OpenGLManager();
+
+    //Singleton Instance
+    static OpenGLManager& getSingleton()
+    {
+        static OpenGLManager instance;
+        return instance;
+    }
+
+    //Functions
+    bool initialize(bool fullscreen, int width, int height, int bitDepth, int refreshRate, bool vSync, bool hideCursor);
+    void dispose();
+    void resize(int width, int height, int bitDepth, int refreshRate);
+    bool toggleFullscreen();
+    void beginRendering();
+    void endRendering();
+
+    //Fog
+    void setFogEnabled(bool fog);    
+    bool getFogEnabled();
+
+    //Light
+    void setLighting(bool lighting);
+    bool getLightingEnabled();
+
+    //Textureing
+    void setTextureing2D(bool textureing);
+    bool getTextureing2DEnabled();
+
+    //Depth Testing
+    void setZBufferEnabled(bool enable);
+    bool getZBufferEnabled();    
+
+    //Alpha Test
+    void setAlphaTest(bool alphaTestEnable);
+    bool getAlphaTestEnabled();
+
+    //Wireframe
+    void setWireFrame(bool wireframe);    
+
+    //Culling
+    void setCullMode(bool cullFront, bool cullBack);
+    void setForceDisableCulling(bool force) { m_forceDisableCulling = force; }
+         
+    //Set Viewport
+    void setViewport(int x, int y, int width, int height, float zNear=0.0f, float zFar=1.0f);
+
+    //Set Scissor
+    void setScissorEnabled(bool enable);
+    bool getScissorEnabled();    
+    void setScissor(int x, int y, int width, int height);
+    //! Sets the backround color of OpenGL viewport 
+    void setClearColor(float r, float g, float b) { glClearColor(r, g, b, 1.0f); }
+
+    //Set callback from the M64P core
+    void setRenderingCallback(void(*callback)(int)) { m_renderingCallback = callback; }
+       
+       //Set draw flag for rendering callback
+       void setDrawFlag() { m_drawFlag = 1; }
+
+public:
+
+    //N64 Specifics
+    void calcViewScale(int viWidth, int viHeight);
+    float getViewScaleX() { return m_scaleX; } 
+    float getViewScaleY() { return m_scaleY; }
+
+public:
+
+    //Gets
+
+    int getWidth() { return m_width; }
+    int getHeight() { return m_height; }
+    bool getFullscreen() { return m_fullscreen; }
+
+private:
+
+     //Constructor
+    OpenGLManager();          
+
+private:
+
+    bool m_wireframe;            //!< Wireframe mode enabled?
+    bool m_lighting;             //!< Lighting enabled?
+    int m_width;                 //!< Display widht
+    int m_height;                //!< Display height
+    int m_bitDepth;              //!< Fullscreen bitdepth
+    int m_refreshRate;           //!< Fullscreen refresh rate 
+    float m_scaleX;              //!< DisplayWidth aka WindowWidth / viWidth (n64 specific)
+    float m_scaleY;              //!< DisplayHeight aka WindowHeight / viHeight (n64 specific)
+    bool m_fullscreen;           //!< Fullscreen mode or window mode?
+    bool m_forceDisableCulling;  //!< Culling cant be enabled if this is true
+    
+    void (*m_renderingCallback)(int);  //Rendering callback from the core
+       int m_drawFlag;
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp b/source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp
new file mode 100755 (executable)
index 0000000..e000582
--- /dev/null
@@ -0,0 +1,923 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RDP.h"
+#include "GBIDefs.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "DisplayListParser.h"
+#include "assembler.h"
+#include "OpenGLRenderer.h"
+#include "TextureCache.h"
+#include "VI.h"
+#include "Memory.h"
+#include "OpenGLManager.h"
+#include "OpenGL2DRenderer.h"
+#include "AdvancedCombinerManager.h"
+#include "FogManager.h"
+#include "Logger.h"
+#include "MathLib.h"
+#include "RomDetector.h"
+#include "m64p.h"
+#include "OpenGL.h"
+#include <algorithm>
+using std::max;
+
+//-----------------------------------------------------------------------------
+//! Defines
+//-----------------------------------------------------------------------------
+#define MI_INTR_DP          0x00000020  //!< RDP Interrupt signal
+
+//-----------------------------------------------------------------------------
+//! Static Variables
+//-----------------------------------------------------------------------------
+Memory* RDP::m_memory  = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RDP::RDP()
+{
+    m_graphicsInfo       = 0;    
+    m_changedTiles       = false;
+    m_textureMode        = TM_NORMAL;
+    m_loadType           = LOADTYPE_BLOCK;
+    m_tmemChanged        = false;  
+    m_textureLUT         = 0;   
+    m_texRectWidth       = 1; 
+    m_texRectHeight      = 1;
+    m_displayListParser  = 0;
+    m_primitiveZ         = 0;
+    m_combinerMgr        = 0;
+    m_textureLoader      = 0;
+    m_openGL2DRenderer   = 0;
+    m_screenUpdatePending= false;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RDP::~RDP()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Sets pointers to managers and initializes objects
+//-----------------------------------------------------------------------------
+bool RDP::initialize(GFX_INFO* graphicsInfo, RSP* rsp, Memory* memory, GBI* gbi, TextureCache* textureCache, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr)
+{
+    //Set pointers
+    m_graphicsInfo      = graphicsInfo;
+    m_rsp               = rsp;
+    m_vi                = vi;
+    m_memory            = memory;
+    m_displayListParser = displayListParser;
+    m_textureCache      = textureCache;
+    m_fogMgr            = fogMgr;
+
+    //Create combiner manager
+    m_combinerMgr = new AdvancedCombinerManager();
+    m_combinerMgr->initialize();
+
+    //Create texture loader
+    m_textureLoader = new TextureLoader();
+    m_textureLoader->initialize(this, m_memory);
+
+    //Create OpenGL 2D Renderer
+    m_openGL2DRenderer = new OpenGL2DRenderer();
+    m_openGL2DRenderer->initialize(vi);
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Dispose
+//! Delets all allocated memory
+//-----------------------------------------------------------------------------
+void RDP::dispose()
+{
+    if ( m_combinerMgr      ) { delete m_combinerMgr;      m_combinerMgr      = 0; }
+    if ( m_textureLoader    ) { delete m_textureLoader;    m_textureLoader    = 0; }
+    if ( m_openGL2DRenderer ) { delete m_openGL2DRenderer; m_openGL2DRenderer = 0; }
+}
+
+//-----------------------------------------------------------------------------
+//* Update States
+//! Sets OpenGL states, updates combiner, activates textures, sets blender
+//-----------------------------------------------------------------------------
+void RDP::updateStates()
+{
+    //Depth Compare
+    if (m_otherMode.depthCompare)
+        glDepthFunc( GL_LEQUAL );
+    else
+        glDepthFunc( GL_ALWAYS );
+
+    //Depth Update
+    if (m_otherMode.depthUpdate)
+        glDepthMask( true );
+    else
+        glDepthMask( false );
+
+    // Depth Mode
+    if (m_otherMode.depthMode == ZMODE_DEC)
+    {
+        glEnable( GL_POLYGON_OFFSET_FILL );
+        glPolygonOffset( -3.0f, -3.0f );
+    }
+    else
+    {
+        glDisable( GL_POLYGON_OFFSET_FILL );
+    }
+
+    // Alpha Compare
+    if ((m_otherMode.alphaCompare == G_AC_THRESHOLD) && !(m_otherMode.alphaCvgSel))
+    {
+        glEnable( GL_ALPHA_TEST );
+        glAlphaFunc( (m_combinerMgr->getBlendColor()[3] > 0.0f) ? GL_GEQUAL : GL_GREATER, m_combinerMgr->getBlendColor()[3] );
+    }
+    // Used in TEX_EDGE and similar render modes
+    else if (m_otherMode.cvgXAlpha)
+    {
+        glEnable( GL_ALPHA_TEST );
+        glAlphaFunc( GL_GEQUAL, 0.5f );  // Arbitrary number -- gives nice results though
+    }
+    else
+        glDisable( GL_ALPHA_TEST );
+
+    //Combiner
+    if ( m_updateCombiner )
+    {
+        if ( m_otherMode.cycleType == G_CYC_COPY)
+        {
+            m_combinerMgr->setMux(72057594037727865LL, m_otherMode.cycleType); //Only normal texturing                                                                    
+            m_combinerMgr->selectCombine(m_otherMode.cycleType);
+        }
+        else if  ( m_otherMode.cycleType == G_CYC_FILL )
+        {
+            m_combinerMgr->setMux( 72057594037828926LL, m_otherMode.cycleType );
+            m_combinerMgr->selectCombine(m_otherMode.cycleType);
+        }
+        else
+        {
+            m_combinerMgr->selectCombine(m_otherMode.cycleType);
+        }
+        m_updateCombiner = false;
+        m_updateCombineColors = true;
+    }
+
+    if ( m_updateCombineColors )
+    {
+        m_combinerMgr->updateCombineColors();
+        m_updateCombineColors = false;
+    }
+
+    //Texturing
+    if ( m_changedTiles || m_tmemChanged || m_rsp->getTexturesChanged() ) 
+    {
+        m_combinerMgr->beginTextureUpdate();
+
+        //Update Texture channel 0
+        if ( m_combinerMgr->getUsesTexture0() )
+        {
+            //Enable texture 0
+            m_textureCache->update(0);
+            m_rsp->setTexturesChanged(false);
+            m_changedTiles = false;
+            m_tmemChanged = false;
+        }
+        else
+        {
+            //Disable texture 0
+            glActiveTextureARB( GL_TEXTURE0_ARB + 0 );
+            glDisable(GL_TEXTURE_2D);  
+        }
+
+        //Update Texture channel 1
+        if (  m_combinerMgr->getUsesTexture1() )
+        {
+            //Enable texture 1
+            m_textureCache->update(1);
+            m_rsp->setTexturesChanged(false);
+            m_changedTiles = false;
+            m_tmemChanged = false;
+        }
+        else
+        {
+            //Disable textureing 1
+            glActiveTextureARB( GL_TEXTURE0_ARB + 1 );
+            glDisable(GL_TEXTURE_2D); 
+        }
+
+        m_combinerMgr->endTextureUpdate();
+    }
+
+    // Blending
+    if (    (m_otherMode.forceBlender) &&    
+            (m_otherMode.cycleType != G_CYC_COPY) &&
+            (m_otherMode.cycleType != G_CYC_FILL) &&
+            !(m_otherMode.alphaCvgSel))
+    {
+        glEnable( GL_BLEND );
+        switch (m_otherMode.l >> 16)
+        {
+            case 0x0448: // Add
+            case 0x055A:
+                glBlendFunc( GL_ONE, GL_ONE );
+                break;
+            case 0x0C08: // 1080 Sky
+            case 0x0F0A: // Used LOTS of places
+                glBlendFunc( GL_ONE, GL_ZERO );
+                break;
+            case 0xC810: // Blends fog
+            case 0xC811: // Blends fog
+            case 0x0C18: // Standard interpolated blend
+            case 0x0C19: // Used for antialiasing
+            case 0x0050: // Standard interpolated blend
+            case 0x0055: // Used for antialiasing
+                glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+                break;
+            case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this?
+            case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right...
+                glBlendFunc( GL_ZERO, GL_ONE );
+                break;
+            default:
+                glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+                break;
+        }
+    }
+    else
+        glDisable( GL_BLEND );
+
+    if (m_otherMode.cycleType == G_CYC_FILL)
+    {
+        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+        glEnable( GL_BLEND );
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Reset
+//! Resets all states on RDP
+//-----------------------------------------------------------------------------
+void RDP::reset()
+{
+    setTextureFiltering( G_TF_POINT );
+    setRenderMode(0);
+}
+
+//-----------------------------------------------------------------------------
+//* Trigger Interrupt
+//! Tell emulator that the RDP is idle
+//-----------------------------------------------------------------------------
+void RDP::triggerInterrupt()
+{
+    *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_DP;
+    m_graphicsInfo->CheckInterrupts();
+}
+
+//-----------------------------------------------------------------------------
+//* Set Alpha Compare Mode
+//-----------------------------------------------------------------------------
+void RDP::setAlphaCompareMode(unsigned int mode)
+{
+    m_otherMode.alphaCompare = mode;
+    OpenGLManager::getSingleton().setAlphaTest( m_otherMode.alphaCompare != 0 );
+}
+
+//-----------------------------------------------------------------------------
+//* Set Render Mode
+//-----------------------------------------------------------------------------
+void RDP::setRenderMode(unsigned int w1)
+{
+    unsigned int mode1 = (w1 & 0xCCCCFFFF);
+    unsigned int mode2 = (w1 & 0x3333FFFF);
+
+    m_otherMode.l &= 0x00000007;
+    m_otherMode.l |= mode1 | mode2;
+}
+
+//#############################################################################
+//  UCODE FUNCTIONS:
+//#############################################################################
+
+//*****************************************************************************
+// Combiner Mode
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Set Combine
+//! Sets all combiner variables on combiner that tells it how to combine
+//! the diffrent colors and textures.
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetCombine(MicrocodeArgument* ucode)
+{ 
+    int mux0 = _SHIFTR( ucode->w0, 0, 24 );
+    int mux1 = ucode->w1;
+    m_combinerMgr->setMux(mux0, mux1, (G_CYCLE_TYPE)m_otherMode.cycleType);
+
+    m_updateCombiner = true;    
+}
+
+//*****************************************************************************
+// Colors
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Set Environment Color
+//! Sets Environment Color on combiner
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetEnvColor(float r, float g, float b, float a)
+{ 
+    m_combinerMgr->setEnvColor(r, g, b, a);
+    m_updateCombineColors = true;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Prim Color
+//! Sets Prim Color on combiner
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//! @param primLodMin
+//! @param primLevel
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetPrimColor(float r, float g, float b, float a, unsigned int primLodMin, unsigned int primLevel)
+{ 
+    int primLodFrac = max(primLevel, primLodMin);
+    m_combinerMgr->setPrimLodMin(primLodMin);
+    m_combinerMgr->setPrimLodFrac(primLodFrac / 255.0f);
+    m_combinerMgr->setPrimColor(r, g, b, a);
+    m_updateCombineColors = true;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Blend Color
+//! Sets Blend Color on combiner
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetBlendColor(float r, float g, float b, float a)
+{
+    m_combinerMgr->setBlendColor(r, g, b, a);
+    m_updateCombineColors = true;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Fill Color
+//! Sets Fill Color on combiner
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetFillColor(float r, float g, float b, float a)
+{ 
+    m_combinerMgr->setFillColor(r, g, b, a);
+    m_updateCombineColors = true;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Fog Color
+//! Sets fog color used when rendering fog
+//! @param r Red component of color (0.0 - 1.0)
+//! @param g Green component of color (0.0 - 1.0)
+//! @param b Blue component of color (0.0 - 1.0)
+//! @param a Alpha component of color (0.0 - 1.0)
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetFogColor(float r, float g, float b, float a)
+{ 
+    m_fogMgr->setFogColor(r, g, b, a);
+}
+
+//*****************************************************************************
+// Misc
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//! Set Other Mode
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetOtherMode(MicrocodeArgument* ucode)
+{          
+    unsigned int mode0 = _SHIFTR( ucode->w0, 0, 24 );    
+    unsigned int mode1 = ucode->w1;                    
+
+    m_otherMode.h = mode0;
+    m_otherMode.l = mode1;
+}
+
+//-----------------------------------------------------------------------------
+//! Set Prim Depth
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetPrimDepth(unsigned int dwZ, unsigned int dwDZ)
+{  
+    unsigned int primitiveDepth = dwZ & 0x7FFF;
+
+    //Convert to float
+    m_primitiveZ = (float)(primitiveDepth)/(float)0x8000;
+ }
+
+//-----------------------------------------------------------------------------
+//! Set Scissor
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetScissor(int x0, int y0, int x1, int y1, int mode)
+{  
+    //Get Scale
+    float vsx = OpenGLManager::getSingleton().getViewScaleX();
+    float vsy = OpenGLManager::getSingleton().getViewScaleY();
+    
+    //Get Offset
+    int offset = 0; //TODO: height offset?
+
+    //Set Scissor
+    OpenGLManager::getSingleton().setScissor( 
+               x0 * vsx, 
+               (m_vi->getHeight() - y1) * vsy + offset,
+               (x1 - x0) * vsx, 
+               (y1 - y0) * vsy 
+    );
+}
+
+//-----------------------------------------------------------------------------
+//* Set Full Sync
+//! Called when RDP is finished 
+//-----------------------------------------------------------------------------
+void RDP::RDP_FullSync()
+{ 
+    this->triggerInterrupt();
+}
+
+//*****************************************************************************
+// Rendering
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Fill Rect
+//! Renders a rectangle
+//-----------------------------------------------------------------------------
+void RDP::RDP_FillRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1)
+{ 
+    //Logger::getSingleton() << "RDP_FillRect: " << (int)x0 << " " << (int)y0 << " " << (int)x1 << " " << (int)y1 << "\n";
+
+    //Increase rectangle size?
+    if( m_otherMode.cycleType >= G_CYC_COPY )
+    {
+        x1++;
+        y1++;
+    }
+
+    //Clear Depth Buffer?
+    if ( m_depthImageInfo.rdramAddress == m_colorImageInfo.rdramAddress )
+    {
+        //Clear the Z Buffer
+        updateStates();
+        glDepthMask( true );
+        glClear(GL_DEPTH_BUFFER_BIT);
+
+        // Depth update
+        if (m_otherMode.depthUpdate)
+        {
+            glDepthMask(GL_TRUE);
+        }
+        else
+        {
+            glDepthMask(GL_FALSE);
+        }
+
+        return;
+    }
+
+    //Clear Color Buffer?
+    if ( m_otherMode.cycleType == G_CYC_FILL)
+    {
+        if ( x0 == 0 && y0 == 0 && x1 == m_vi->getWidth() && y1 == m_vi->getHeight() )
+        {
+            const float* fillColor = m_combinerMgr->getFillColor();
+            glClearColor(fillColor[0], fillColor[1], fillColor[2], fillColor[3]);
+            bool scissor = OpenGLManager::getSingleton().getScissorEnabled();
+            OpenGLManager::getSingleton().setScissorEnabled(false);
+            glClear(GL_COLOR_BUFFER_BIT);
+            OpenGLManager::getSingleton().setScissorEnabled(scissor);
+            return;
+        }
+    }
+
+    //Update States
+    this->updateStates();   
+
+    //Ignore fill rects?
+    if ( ROMDetector::getSingleton().getIgnoreFillRects() ) 
+    {
+        return;
+    }
+
+    //Disable Scissor
+    glDisable( GL_SCISSOR_TEST );
+
+    //Set Viewport
+    //int oldViewport[4];
+    //glGetIntegerv(GL_VIEWPORT, oldViewport);
+    //glViewport(0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() ); 
+    glDepthRange(0.0f, 1.0f);
+
+    //Get depth and color
+    float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0;  //TODO: Use RSP viewport nearz?
+    float* color = m_otherMode.cycleType == G_CYC_FILL ? m_combinerMgr->getFillColor() : m_combinerMgr->getPrimColor();
+
+    //Render rectangle
+    m_openGL2DRenderer->renderQuad(color, x0, y0, x1, y1, depth);
+
+    //Reset viewport
+    //glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);     
+
+    //Reset Scissor
+    glEnable( GL_SCISSOR_TEST );
+}
+
+//-----------------------------------------------------------------------------
+// Texture Rectangle Flip
+//-----------------------------------------------------------------------------
+void RDP::RDP_TexRectFlip(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, 
+                          unsigned int tileno, unsigned int dwS, unsigned int dwT, int nDSDX, int nDTDY)
+{   
+    Logger::getSingleton().printMsg("RDP_TexRect");
+
+    float fS0 = (float)dwS / 32.0f;
+    float fT0 = (float)dwT / 32.0f;
+
+    float fDSDX = (float)nDSDX / 1024.0f;
+    float fDTDY = (float)nDTDY / 1024.0f;
+
+    if (m_otherMode.cycleType == G_CYC_COPY)
+    {
+        fDSDX /= 4.0f;    // In copy mode 4 pixels are copied at once.
+        dwXH++;
+        dwYH++;
+    }
+    else if (m_otherMode.cycleType == G_CYC_FILL )
+    {
+        dwXH++;
+        dwYH++;
+    }
+
+    float fS1 = fS0 + (fDSDX * (dwYH - dwYL));
+    float fT1 = fT0 + (fDTDY * (dwXH - dwXL));
+
+    //Set Current Texture tiles
+    m_rsp->setTile( m_textureLoader->getTile(tileno), 0);
+    if ( tileno < 7 ) 
+    {
+        m_rsp->setTile( m_textureLoader->getTile(tileno + 1), 1);
+    }
+    else {
+        m_rsp->setTile( m_textureLoader->getTile(tileno), 1);
+    }
+
+    m_texRectWidth = (unsigned int)fS1;
+    m_texRectHeight = (unsigned int)fT1;
+
+    //Update States
+    this->updateStates();
+
+    float t0u0 = 0, t0v0 = 0, t0u1 =0, t0v1 = 0;
+    if ( m_textureCache->getCurrentTexture(0) )
+    {
+        t0u0 = (fS0) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_textureLoader->getTile(tileno)->uls;
+        t0v0 = (fT0) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_textureLoader->getTile(tileno)->ult;
+        t0u1 = t0u0 + (fDSDX * (dwYH - dwYL))*m_textureCache->getCurrentTexture(0)->shiftScaleS;
+        t0v1 = t0v0 + (fDTDY * (dwXH - dwXL))*m_textureCache->getCurrentTexture(0)->shiftScaleT;
+    }
+
+    _textureRectangleFlip(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno);
+        
+    //Restore RSP Tile
+    int rspTile = m_rsp->getTexture().tile;
+    m_rsp->setTile( m_textureLoader->getTile(tileno), 0);
+    m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1);
+}
+
+//-----------------------------------------------------------------------------
+//* Texture Rect
+//! Not this command use 128bits and not 64 bits wich could cause some
+//! problems with the program counter.
+//-----------------------------------------------------------------------------
+void RDP::RDP_TexRect(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, 
+                      unsigned int tileno, unsigned short dwS, unsigned short dwT, unsigned short nDSDX, unsigned short nDTDY)
+{ 
+    Logger::getSingleton().printMsg("RDP_TexRect");    
+
+    glEnable(GL_TEXTURE_2D);
+
+    //Convert to signed
+    short s16S = *(short*)(&dwS);
+    short s16T = *(short*)(&dwT);
+    short s16DSDX  = *(short*)(&nDSDX);
+    short s16DTDY    = *(short*)(&nDTDY);
+
+    //Convert to float
+    float s = s16S / 32.0f;
+    float t = s16T / 32.0f;
+    float dsdx = s16DSDX / 1024.0f;
+    float dtdy = s16DTDY / 1024.0f;
+
+
+    float ulx = (float)dwXH;
+    float uly = (float)dwYH;
+    float lrx = (float)dwXL;
+    float lry = (float)dwYL;
+
+    int tile = tileno;
+
+    _textureRectangle(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy, false);
+}
+
+//*****************************************************************************
+// Texturing
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Set Color Image
+//! Sets information about color image
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetCImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
+{ 
+    m_colorImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress );
+    m_colorImageInfo.format       = format;
+    m_colorImageInfo.size         = size;
+    m_colorImageInfo.width        = width + 1; //Note: add plus one
+    m_colorImageInfo.bpl          = m_colorImageInfo.width << m_colorImageInfo.size >> 1;
+    
+    if (m_screenUpdatePending)
+    {
+        OpenGLManager::getSingleton().endRendering();
+        m_screenUpdatePending = false;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Z Image
+//! Sets information about depth image
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetZImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
+{ 
+    m_depthImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress );
+    m_depthImageInfo.format       = format;
+    m_depthImageInfo.size         = size;
+    m_depthImageInfo.width        = width + 1; //Note: add plus one
+    m_depthImageInfo.bpl          = m_colorImageInfo.width << m_colorImageInfo.size >> 1;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Image
+//! Sets information about texture image
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetTImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
+{ 
+    m_textureLoader->setTextureImage(format, size, width, segmentAddress);
+}
+
+//-----------------------------------------------------------------------------
+// Set Tile
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetTile(int format, int size, int line, int tmem, int tile, 
+                      int palette, int clampS, int clampT, int mirrorS, 
+                      int mirrorT, int maskS, int maskT, int shiftS, int shiftT )
+{ 
+    //Set Tile
+    m_textureLoader->setTile( format, size, line, tmem, tile, palette, 
+                              clampS, clampT, mirrorS, mirrorT, maskS, maskT,
+                              shiftS, shiftT );
+
+    //m_changedTiles = true;    ??? Not needed?
+}
+
+//-----------------------------------------------------------------------------
+//* Load Tile
+//-----------------------------------------------------------------------------
+void RDP::RDP_LoadTile(int tile, int s0, int t0, int s1, int t1)
+{ 
+    //Load Tile
+    m_textureLoader->loadTile(tile, s0, t0, s1, t1);
+
+    m_textureMode = TM_NORMAL;
+    m_loadType    = LOADTYPE_TILE;
+    m_tmemChanged = true;    
+}    
+
+//-----------------------------------------------------------------------------
+// Load Block
+//-----------------------------------------------------------------------------
+void RDP::RDP_LoadBlock(int tile, int s0, int t0, int s1, int t1)
+{  
+    //Load Block
+    m_textureLoader->loadBlock(tile, s0, t0, s1, t1);
+
+    m_textureMode = TM_NORMAL;
+    m_loadType    = LOADTYPE_BLOCK;
+    m_tmemChanged = true;
+}
+
+//-----------------------------------------------------------------------------
+//! Sets the size of tile
+//! @Param tile Index of the tile to set size on
+//! @param s0 Texture Coordinats for first vertex coordinate
+//! @param t0 Texture Coordinats for first vertex coordinate
+//! @param s1 Texture Coordinats for second vertex coordinate
+//! @param t1 Texture Coordinats for second vertex coordinate
+//-----------------------------------------------------------------------------
+void RDP::RDP_SetTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1)
+{  
+    m_textureLoader->setTileSize( tile, s0, t0, s1, t1);
+
+    m_changedTiles = true;    
+}
+
+//-----------------------------------------------------------------------------
+// Load Texture Look Up Table
+//-----------------------------------------------------------------------------
+void RDP::RDP_LoadTLUT(int tile, int s0, int t0, int s1, int t1)
+{   
+    m_textureLoader->loadTLUT(tile, s0, t0, s1, t1);
+
+    m_tmemChanged = true;
+}
+
+//*****************************************************************************
+// Private Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Texture Rectangle
+//-----------------------------------------------------------------------------
+void RDP::_textureRectangle(float ulx, float uly, float lrx, float lry, int tile, float s, float t, float dsdx, float dtdy,bool flip)
+{
+    bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled();
+    OpenGLManager::getSingleton().setZBufferEnabled(false);
+
+    //Copy Mode
+    if (  m_otherMode.cycleType == G_CYC_COPY )
+    {
+        dsdx = 1.0;
+        lrx += 1.0f;
+        lry += 1.0f;
+    }
+    else if (m_otherMode.cycleType == G_CYC_FILL )
+    {
+        lrx++;
+        lry++;
+    }
+
+    //Set Current Texture tiles
+    m_rsp->setTile( m_textureLoader->getTile(tile), 0);
+    m_rsp->setTile( m_textureLoader->getTile(tile < 7 ? tile + 1 : tile), 1);
+
+
+    float lrs = s + (lrx - ulx - 1) * dsdx;
+    float lrt = t + (lry - uly - 1) * dtdy;
+
+    //Change mode to texture rectangle
+    if ( m_textureMode == TM_NORMAL )
+        m_textureMode = TM_TEXRECT;
+
+    m_texRectWidth  = (unsigned int)(max( lrs, s ) + dsdx);
+    m_texRectHeight = (unsigned int)(max( lrt, t ) + dtdy);
+
+    //Update States
+    this->updateStates();
+
+    //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
+
+    glDisable(GL_SCISSOR_TEST);
+
+    if (lrs > s)
+    {
+        if (lrt > t)
+            OpenGLRenderer::getSingleton().renderTexRect( ulx, uly, lrx, lry, s, t, lrs, lrt, flip );
+        else
+            OpenGLRenderer::getSingleton().renderTexRect( ulx, lry, lrx, uly, s, lrt, lrs, t, flip );
+    }
+    else
+    {
+        if (lrt > t)
+            OpenGLRenderer::getSingleton().renderTexRect( lrx, uly, ulx, lry, lrs, t, s, lrt, flip );
+        else
+            OpenGLRenderer::getSingleton().renderTexRect( lrx, lry, ulx, uly, lrs, lrt, s, t, flip );
+    }
+
+    //Restore RSP Tile
+    int rspTile = m_rsp->getTexture().tile;
+    m_rsp->setTile( m_textureLoader->getTile( rspTile ), 0);
+    m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1);
+
+    //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
+
+    glEnable(GL_SCISSOR_TEST);
+    OpenGLManager::getSingleton().setZBufferEnabled(zEnabled);
+}
+
+//-----------------------------------------------------------------------------
+//* Texture Rectangle Flip
+//! @todo: Clamp Tile
+//-----------------------------------------------------------------------------
+void RDP::_textureRectangleFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1, int tile)
+{
+    //Disable z buffer
+    bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled();
+    OpenGLManager::getSingleton().setZBufferEnabled(false);
+
+    float widthDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getWidth();
+    float heightDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getHeight();
+
+    float t0u0 = fS0 / widthDiv;
+    float t0v0 = fT0 / heightDiv;
+    float t0u1 = (fS1 - fS0)/ widthDiv + t0u0;
+    float t0v1 = (fT1 - fT0)/ heightDiv + t0v0;
+
+    float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0;  //TODO: Use RSP viewport nearz?
+
+    static bool warned = false;
+    if( t0u0 >= 0 && t0u1 <= 1 && t0u1 >= t0u0 ) 
+    {
+        //TODO: Clamp Tile
+        if (!warned)
+        {
+            warned = true;
+            Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING);
+        }
+    }
+    if( t0v0 >= 0 && t0v1 <= 1 && t0v1 >= t0v0 ) 
+    {
+        //TODO: Clamp tile
+        if (!warned)
+        {
+            warned = true;
+            Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING);
+        }
+    }
+
+    //HACK 
+    if ( ROMDetector::getSingleton().getRomID() == SUPER_MARIO_64 )
+    {
+        t0u0 *= 0.5f;
+        t0v0 *= 0.5f;    
+        t0u1 *= 0.5f;    
+        t0v1 *= 0.5f;
+    }
+
+    //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
+
+    //Get Color
+    float color[4] = { 1,1,1,0 }; 
+    this->getCombinerMgr()->getCombinerColor(    &color[0] );
+    float secondaryColor[4] = { 1,1,1,1 };
+
+    if (  m_otherMode.cycleType == G_CYC_COPY )
+    {
+        glActiveTextureARB( GL_TEXTURE0_ARB );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+    }
+
+    //Disable Scissor
+    glDisable( GL_SCISSOR_TEST );
+
+    //Render Quad
+    m_openGL2DRenderer->renderFlippedTexturedQuad( color, secondaryColor,
+                                                   (float)nX0, (float)nY0,
+                                                   (float)nX1, (float)nY1,
+                                                   depth,
+                                                   t0u0, t0v0,
+                                                   t0u1, t0v1, 
+                                                   t0u0, t0v0,
+                                                   t0u1, t0v1 );
+
+    //Restore states
+    glEnable(GL_SCISSOR_TEST);
+    OpenGLManager::getSingleton().setZBufferEnabled(zEnabled);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDP.h b/source/mupen64plus-video-arachnoid/src/RDP/RDP.h
new file mode 100755 (executable)
index 0000000..c203eea
--- /dev/null
@@ -0,0 +1,290 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef REALITY_DRAWING_PROCESSOR_H_
+#define REALITY_DRAWING_PROCESSOR_H_
+
+//Includes
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_plugin.h"
+#include "UCodeDefs.h"
+#include "GBI.h"
+#include "GBIDefs.h"
+#include "TextureLoader.h"
+
+//Forward declaration
+class RSP;
+class VI;
+class Memory;
+class DisplayListParser;
+class TextureCache;
+class AdvancedCombinerManager;
+class FogManager;
+class TextureLoader;
+class OpenGL2DRenderer;
+
+//*****************************************************************************
+//! RDPSetImgInfo
+//! Used by RDP to set color- and depth- image info
+//*****************************************************************************
+struct RDPSetImgInfo
+{
+    unsigned int format;
+    unsigned int size;
+    unsigned int width;
+    unsigned int rdramAddress;
+    unsigned int bpl;
+};
+
+//*****************************************************************************
+//* OtherMode
+//! Struct used to get input to combiner
+//*****************************************************************************
+union OtherMode
+{
+    struct
+    {
+        //Low 32:
+        unsigned int alphaCompare : 2;
+        unsigned int depthSource : 1;
+
+        //RenderMode
+        unsigned int AAEnable : 1;
+        unsigned int depthCompare : 1;
+        unsigned int depthUpdate : 1;
+        unsigned int imageRead : 1;
+        unsigned int clearOnCvg : 1;
+        unsigned int cvgDest : 2;
+        unsigned int depthMode : 2;
+        unsigned int cvgXAlpha : 1;
+        unsigned int alphaCvgSel : 1;
+        unsigned int forceBlender : 1;
+        unsigned int textureEdge : 1;
+
+        //Blender
+        unsigned int c2_m2b : 2;
+        unsigned int c1_m2b : 2;
+        unsigned int c2_m2a : 2;
+        unsigned int c1_m2a : 2;
+        unsigned int c2_m1b : 2;
+        unsigned int c1_m1b : 2;
+        unsigned int c2_m1a : 2;
+        unsigned int c1_m1a : 2;
+
+        // High 32:
+        unsigned int blendMask : 4;
+        unsigned int alphaDither : 2;
+        unsigned int colorDither : 2;    
+        unsigned int combineKey : 1;
+        unsigned int textureConvert : 3;
+        unsigned int textureFilter : 2;
+        unsigned int textureLUT : 2;
+        unsigned int textureLOD : 1;
+        unsigned int textureDetail : 2;
+        unsigned int texturePersp : 1;
+        unsigned int cycleType : 2;
+        unsigned int unusedColorDither : 1; // unsupported
+        unsigned int pipelineMode : 1;
+        unsigned int pad : 8;
+    };
+
+    struct
+    {
+        unsigned int l, h;   //!< Low and high values
+    };
+};
+
+//*****************************************************************************
+//* RDP
+//! Class for emulating the Reality Drawing Processor
+//*****************************************************************************
+class RDP
+{
+public:
+
+    //Constructor / Destructor
+    RDP();
+    ~RDP();
+
+    //initialize
+    bool initialize(GFX_INFO* graphicsInfo, RSP* rsp, Memory* memory, GBI* gbi, TextureCache* textureCache, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr);
+    void updateStates();
+    void dispose();
+    void reset();
+    void triggerInterrupt();
+
+public:
+    void signalUpdate() { m_screenUpdatePending = true; }
+
+    //Get Combiner Manager
+    AdvancedCombinerManager* getCombinerMgr() { return m_combinerMgr; }
+
+    //Set/Get Cycle Type
+    void setCycleType(unsigned int cycleType) { m_otherMode.cycleType = cycleType; m_updateCombiner = true; }
+    unsigned int getCycleType() { return m_otherMode.cycleType; }
+
+    //Set Texture LUT
+    void setTextureLUT(unsigned int lut) { m_textureLUT = lut; }
+    unsigned int getTextureLUT() { return m_textureLUT; }
+
+    //Set/Get Texture Filtering
+    void setTextureFiltering(unsigned int filterMode) { m_otherMode.textureFilter = filterMode; }
+    unsigned int getTextureFiltering() { return m_otherMode.textureFilter; }
+
+    // Set / Get Alpha Compare
+    void setAlphaCompareMode(unsigned int mode);
+    unsigned int getAlphaCompareMode() { return m_otherMode.alphaCompare; }
+
+    // Set Rendermode
+    void setRenderMode(unsigned int w1);        
+
+    //Get Textures, Tiles    
+    TextureImage* getTextureImage()          { return m_textureLoader->getTextureImage(); }
+    RDPTile*      getCurrentTile()           { return m_textureLoader->getCurrentTile();  }
+    RDPTile*      getTile(unsigned int tile) { return m_textureLoader->getTile(tile);     }
+
+    //Get texture modes
+    TextureMode getTextureMode() { return m_textureMode;  }
+    LoadType getLoadType()       { return m_loadType;     }
+    bool getChangedTiles()       { return m_changedTiles; }
+    bool getChangedTMEM()        { return m_tmemChanged;  }
+
+    //Texture rectangle Size
+    unsigned int getTexRectWidth() { return m_texRectWidth; }
+    unsigned int getTexRectHeight() { return m_texRectHeight; }
+
+    //Half
+    void setHalf1(unsigned int half1) { m_half1 = half1; }
+    void setHalf2(unsigned int half2) { m_half2 = half2; }
+    unsigned int getHalf1() { return m_half1; }
+    unsigned int getHalf2() { return m_half2; }
+
+    //Get Primitive Depth
+    float getPrimitiveZ() { return m_primitiveZ; }
+
+    //Depth Source (get z value from prim depth?)
+    void setDepthSource(unsigned int source) { m_otherMode.depthSource = source; }
+    unsigned int getDepthSource()            { return m_otherMode.depthSource;   }
+
+    void setUpdateCombiner(bool update) { m_updateCombiner = update; }
+
+public:
+
+    //Texture Rectangle
+    void _textureRectangle(float ulx, float uly, float lrx, float lry, int tile, float s, float t, float dsdx, float dtdy,bool flip);
+    void _textureRectangleFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1, int tile);
+
+public:
+
+    //Texturing
+    void RDP_SetCImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress);
+    void RDP_SetZImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress);
+    void RDP_SetTImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress);
+    void RDP_SetTile(int format, int size, int line, int tmem, int tile, int palette, 
+                          int clampS, int clampT, int mirrorS, int mirrorT, int maskS, 
+                          int maskT, int shiftS, int shiftT);
+    void RDP_SetTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1);
+    void RDP_LoadTile(int tile, int s0, int t0, int s1, int t1);
+    void RDP_LoadBlock(int tile, int s0, int t0, int s1, int t1);
+    void RDP_LoadTLUT(int tile, int s0, int t0, int s1, int t1);
+
+    //Colors
+    void RDP_SetEnvColor(float r, float g, float b, float a);
+    void RDP_SetFogColor(float r, float g, float b, float a);
+    void RDP_SetBlendColor(float r, float g, float b, float a);    
+    void RDP_SetPrimColor(float r, float g, float b, float a, unsigned int primLodMin, unsigned int primLevel);    
+    void RDP_SetFillColor(float r, float g, float b, float a);    
+
+    //Combiner
+    void RDP_SetCombine(MicrocodeArgument* ucode);
+
+    //Misc
+    void RDP_SetOtherMode(MicrocodeArgument* ucode);
+    void RDP_SetPrimDepth(unsigned int dwZ, unsigned int dwDZ);
+    void RDP_SetScissor(int x0, int y0, int x1, int y1, int mode);    
+
+    //Rendering
+    void RDP_FillRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1);
+    void RDP_TexRectFlip(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, 
+                              unsigned int tileno, unsigned int dwS, unsigned int dwT, int nDSDX, int nDTDY);
+    void RDP_TexRect(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, 
+                          unsigned int tileno, unsigned short dwS, unsigned short dwT, unsigned short nDSDX, unsigned short nDTDY);
+
+    //Other
+    void RDP_FullSync();
+
+public:
+
+    static Memory* m_memory;                       //!< Pointer to memory manager
+
+public:
+
+    //Other Mode
+    OtherMode m_otherMode;             //!< Lots of states for graphics and combiner
+
+    //Hash values for paletts
+    unsigned int m_paletteCRC16[16];  //!< Hash values used to select correct texture
+    unsigned int m_paletteCRC256;     //!< Hash values used to select correct texture 
+
+protected:
+
+    //Pointers to other objects and managers
+    GFX_INFO*                m_graphicsInfo;       //!< Access to emulator data (like RDRAM ...)
+    RSP*                     m_rsp;                //!< Pointer to Reality Signal Processor    
+    VI*                      m_vi;                 //!< Pointer to video interface
+    DisplayListParser*       m_displayListParser;  //!< Pointer to display list parser
+    TextureCache*            m_textureCache;       //!< Pointer to texture cache
+    FogManager*              m_fogMgr;             //!< Pointer to fog manager
+    AdvancedCombinerManager* m_combinerMgr;        //!< Pointer to combiner manager
+    TextureLoader*           m_textureLoader;      //!< Pointer to texture loader
+    OpenGL2DRenderer*        m_openGL2DRenderer;   //!< Pointer to OpenGL 2D Renderer
+
+    //Prim Depth
+    float m_primitiveZ;                //!< Z value assigned to vertices z value if depth source says so
+    float m_primitiveDeltaZ;           //!< ??? Unused by this plugin
+
+    //Update?
+    bool m_updateCombiner;             //!< Update combiner?
+    bool m_updateCombineColors;        //!< Update colors combiner uses?
+    bool m_tmemChanged;                //!< True when texture memory has been altered
+    bool m_changedTiles;               //!< True if tiles have been changed  
+
+    //Textures        
+    LoadType m_loadType;               //!< What kind of texture was previusly loaded
+    TextureMode m_textureMode;         //!< Texture mode (NORMAL, TEXRECT, BACKGROUND, FRAMEBUFFER)
+    unsigned int m_textureLUT;         //!< Texture Look Up Table
+    unsigned int m_texRectWidth;      //!< Width of the texture rectangle to be rendered
+    unsigned int m_texRectHeight;     //!< Height of the texture rectangle to be rendered
+
+    //Images
+    RDPSetImgInfo m_colorImageInfo;    //!< Information about color image
+    RDPSetImgInfo m_depthImageInfo;    //!< Information about depth image
+
+    //Half
+    unsigned int m_half1;             //!< First half value
+    unsigned int m_half2;             //!< Second half value
+
+    //Update on first CI
+    bool m_screenUpdatePending;
+
+};
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp
new file mode 100755 (executable)
index 0000000..fc4766a
--- /dev/null
@@ -0,0 +1,481 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RDPInstructions.h"
+#include "RDPUCodeStructs.h"
+#include "RDP.h"
+#include "DisplayListParser.h"
+#include "Logger.h"
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+
+RDP*               RDPInstructions::m_rdp               = 0;
+DisplayListParser* RDPInstructions::m_displayListParser = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RDPInstructions::RDPInstructions()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RDPInstructions::~RDPInstructions()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool RDPInstructions::initialize(RDP* rdp, DisplayListParser* displayListParser)
+{
+    m_rdp = rdp;
+    m_displayListParser = displayListParser;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//! Set Color Image
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetCImg(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetCImg");
+    RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
+
+    //Set Color Image
+    m_rdp->RDP_SetCImg(temp->format, temp->size, temp->width, temp->segmentAddress);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Z Image
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetZImg(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetZImg");
+    RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
+
+    //Set Depth Image
+    m_rdp->RDP_SetZImg(temp->format, temp->size, temp->width, temp->segmentAddress);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Texture Image
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetTImg(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetTImg");
+    RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
+
+    //Set Texture Image
+    m_rdp->RDP_SetTImg(temp->format, temp->size, temp->width, temp->segmentAddress);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Tile
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetTile(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetTile");
+    RDPUCodeSetTile* temp = (RDPUCodeSetTile*)ucode;
+
+    //Set Tile
+    m_rdp->RDP_SetTile( temp->format, temp->size, temp->line, temp->tmem, temp->tile, 
+        temp->palette, temp->clampS, temp->clampT, temp->mirrorS, temp->mirrorT, 
+        temp->maskS, temp->maskT, temp->shiftS, temp->shiftT
+    );
+}
+
+//-----------------------------------------------------------------------------
+//! Load Tile
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_LoadTile(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_LoadTile");
+    RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
+
+    //Load Tile
+    m_rdp->RDP_LoadTile(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
+}
+
+//-----------------------------------------------------------------------------
+//! Load Block
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_LoadBlock(MicrocodeArgument* ucode)
+{  
+    Logger::getSingleton().printMsg("RDP_LoadBlock");
+    RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
+
+    //Load Block
+    m_rdp->RDP_LoadBlock(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
+}
+
+//-----------------------------------------------------------------------------
+//! Sets the size of tile
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetTileSize(MicrocodeArgument* ucode)
+{  
+    Logger::getSingleton().printMsg("RDP_SetTileSize");
+    RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
+
+    //Set Tile Size
+    m_rdp->RDP_SetTileSize(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Texture Look Up Table
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_LoadTLUT(MicrocodeArgument* ucode)
+{   
+    Logger::getSingleton().printMsg("RDP_LoadTLUT");
+    RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
+
+    //Load Texture Look Up Table
+    m_rdp->RDP_LoadTLUT(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
+}
+
+//-----------------------------------------------------------------------------
+//* Fill Rect
+//! Renders a rectangle
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_FillRect(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_FillRect");
+    RDPUCodeRectangle* temp = (RDPUCodeRectangle*)ucode;
+
+    //Render a Rectangle
+    m_rdp->RDP_FillRect(temp->x0, temp->y0, temp->x1, temp->y1);
+}
+
+//-----------------------------------------------------------------------------
+//* Texture Rectangle Flipped
+//! Renders a textured rectangle
+//! @todo Better extraction of data
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_TexRectFlip(MicrocodeArgument* ucode)
+{   
+    Logger::getSingleton().printMsg("RDP_TexRectFlip");
+    RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode;
+
+    //Get Extra Words
+    unsigned int w2 = m_displayListParser->getNextWord();
+    unsigned int w3 = m_displayListParser->getNextWord();
+
+    //Extract Data
+    unsigned int dwS        = (  w2>>16)&0xFFFF;
+    unsigned int dwT        = (  w2    )&0xFFFF;
+    int nDSDX                   = (int)(short)((  w3>>16)&0xFFFF);
+    int nDTDY                  = (int)(short)((  w3    )&0xFFFF);
+
+    //Render Texture Rectangle Flipped
+    m_rdp->RDP_TexRectFlip(temp->x1 / 4, temp->y1 / 4, 
+                           temp->x0 / 4, temp->y0 / 4,
+                           temp->tile,                            
+                           dwS, dwT, 
+                           nDSDX, nDTDY);
+}
+
+//-----------------------------------------------------------------------------
+//* Texture Rect
+//! Not this command use 128bits and not 64 bits wich could cause some
+//! problems with the program counter.
+//! @todo Better extraction of data
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_TexRect(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_TexRect");    
+    RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode;
+
+    unsigned int w2 = m_displayListParser->getNextWord();
+    unsigned int w3 = m_displayListParser->getNextWord();
+
+    //Extract Data
+    unsigned short uS     = (unsigned short)(  w2>>16)&0xFFFF;
+    unsigned short uT     = (unsigned short)(  w2    )&0xFFFF;
+    unsigned short uDSDX = (unsigned short)((  w3>>16)&0xFFFF);
+    unsigned short uDTDY = (unsigned short)((  w3    )&0xFFFF);
+
+    //Render Texture Rectangle
+    m_rdp->RDP_TexRect( temp->x0 / 4, temp->y0 / 4, 
+                        temp->x1 / 4, temp->y1 / 4, 
+                        temp->tile, 
+                        uS, uT, 
+                        uDSDX, uDTDY);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Enviroment Color
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetEnvColor(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetEnvColor");
+    RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
+
+    //Set enviorment color
+    m_rdp->RDP_SetEnvColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Blend Color
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetBlendColor(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetBlendColor");
+    RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
+
+    //Set blend color
+    m_rdp->RDP_SetBlendColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Prim Color
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetPrimColor(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetPrimColor");
+    RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
+
+    //Set primitive color
+    m_rdp->RDP_SetPrimColor( temp->r / 255.0f,    //red
+                             temp->g / 255.0f,    //green 
+                             temp->b / 255.0f,    //blue
+                             temp->a / 255.0f,    //alpha
+                             temp->prim_min_level, 
+                             temp->prim_level );
+}
+
+//-----------------------------------------------------------------------------
+//! Set Fog Color
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetFogColor(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDPInstructions_SetFogColor");
+    RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
+
+    //Set fog color
+    m_rdp->RDP_SetFogColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Fill Color
+//! Note: Fill color is stored diffrently from the other types of colors
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetFillColor(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetFillColor");
+    RDPUCodeSetFillColor* temp = (RDPUCodeSetFillColor*)ucode;
+
+    //Set fill color (Note: alpha is 0.0 or 1.0) FIXME: 32 or 31? 31 seems to work better with Super Mario 64
+    m_rdp->RDP_SetFillColor(temp->r / 31.0f, temp->g / 31.0f, temp->b / 31.0f, (float)temp->a);  
+}
+
+//-----------------------------------------------------------------------------
+//! Set Combine
+//! @todo Extract data
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetCombine(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_SetCombine");
+    m_rdp->RDP_SetCombine(ucode);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Other Mode
+//! @todo Extract data
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetOtherMode(MicrocodeArgument* ucode)
+{  
+    Logger::getSingleton().printMsg("RDP_SetOtherMode");
+    m_rdp->RDP_SetOtherMode(ucode);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Prim Depth
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetPrimDepth(MicrocodeArgument* ucode)
+{  
+    Logger::getSingleton().printMsg("RDP_SetPrimDepth");
+    RDPUCodeSetPrimDepth* temp = (RDPUCodeSetPrimDepth*)ucode;
+
+    //Set Prim Depth
+    m_rdp->RDP_SetPrimDepth(temp->z, temp->dz);
+}
+
+//-----------------------------------------------------------------------------
+//! Set Scissor
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetScissor(MicrocodeArgument* ucode)
+{  
+    Logger::getSingleton().printMsg("RDP_SetScissor");
+    RDPUCodeScissor* temp = (RDPUCodeScissor*)ucode;
+
+    //Set Scissor
+    m_rdp->RDP_SetScissor(temp->x0 / 4, temp->y0 / 4, temp->x1 / 4, temp->y1 / 4, temp->mode);
+}
+
+//-----------------------------------------------------------------------------
+//* Full Sync
+//! Function that signals end of a frame.
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_FullSync(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("RDP_FullSync");
+    m_rdp->RDP_FullSync();
+}
+
+//-----------------------------------------------------------------------------
+//* Tile Sync
+//! Ignored (Function that signals synchronize of texture tile change)
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_TileSync(MicrocodeArgument* ucode)
+{   
+    //Ignore
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_TileSync - Ignored", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Pipe Sync 
+//! Ignored (Function that signals synchronize of RDP attribute change)
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_PipeSync(MicrocodeArgument* ucode)
+{   
+    //Ignore
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_PipeSync - Ignored", M64MSG_WARNING);
+        warned = true;
+    }    
+}
+
+//-----------------------------------------------------------------------------
+//* Load Sync
+//! Ignored (Function that signals synchronize of textureloading Ignored)
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_LoadSync(MicrocodeArgument* ucode)
+{   
+    //Ignored
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_LoadSync - Ignored", M64MSG_WARNING);
+        warned = true;
+    }   
+}
+
+//-----------------------------------------------------------------------------
+//* Set Convert
+//! Unimplemented
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetConvert(MicrocodeArgument* ucode)
+{   
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_SetConvert - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Key Red
+//! Unimplemented
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetKeyR(MicrocodeArgument* ucode)
+{   
+    Logger::getSingleton().printMsg("RDP_SetKeyR");
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_SetKeyR - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Key Green Blue
+//! Unimplemented
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_SetKeyGB(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_SetKeyGB - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Unknown
+//! This function gets called when the GBI recives an unknown instruction.
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_Unknown(MicrocodeArgument* ucode)
+{ 
+    //Ignore
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_Unknown - Ignored", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* No Operation
+//! Do nothing
+//-----------------------------------------------------------------------------
+void RDPInstructions::RDP_NoOp(MicrocodeArgument* ucode)
+{ 
+    //Ignore
+
+    static bool warned = false;
+    if ( warned ) {
+        Logger::getSingleton().printMsg("RDP_NoOp - Ignored", M64MSG_WARNING);
+        warned = true;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h
new file mode 100755 (executable)
index 0000000..708edab
--- /dev/null
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef RDP_INSTRUCTIONS_H_
+#define RDP_INSTRUCTIONS_H_
+
+#include "UCodeDefs.h"
+
+//Forward declarations
+class RDP;
+class DisplayListParser;
+
+//*****************************************************************************
+//* RDP Instructions
+//! Class for reciveing RDP instructions, and forward them to the RDP
+//*****************************************************************************
+class RDPInstructions
+{
+public:
+
+    //Constructor / Destructor
+    RDPInstructions();
+    ~RDPInstructions();
+
+    //Initialize
+    bool initialize(RDP* rdp, DisplayListParser* displayListParser);
+
+    //Texturing
+    static void RDP_SetCImg(MicrocodeArgument* ucode);
+    static void RDP_SetZImg(MicrocodeArgument* ucode);
+    static void RDP_SetTImg(MicrocodeArgument* ucode);
+    static void RDP_SetTile(MicrocodeArgument* ucode);
+    static void RDP_SetTileSize(MicrocodeArgument* ucode);
+    static void RDP_LoadTile(MicrocodeArgument* ucode);
+    static void RDP_LoadBlock(MicrocodeArgument* ucode);
+    static void RDP_LoadTLUT(MicrocodeArgument* ucode);
+
+    //Rendering
+    static void RDP_TexRectFlip(MicrocodeArgument* ucode);
+    static void RDP_TexRect(MicrocodeArgument* ucode);
+    static void RDP_FillRect(MicrocodeArgument* ucode);
+
+    //Colors
+    static void RDP_SetEnvColor(MicrocodeArgument* ucode);
+    static void RDP_SetPrimColor(MicrocodeArgument* ucode);
+    static void RDP_SetBlendColor(MicrocodeArgument* ucode);
+    static void RDP_SetFogColor(MicrocodeArgument* ucode);
+    static void RDP_SetFillColor(MicrocodeArgument* ucode);
+
+    //Combiner
+    static void RDP_SetCombine(MicrocodeArgument* ucode);
+
+    //Misc
+    static void RDP_SetOtherMode(MicrocodeArgument* ucode);
+    static void RDP_SetPrimDepth(MicrocodeArgument* ucode);
+    static void RDP_SetScissor(MicrocodeArgument* ucode);
+
+    //Sync
+    static void RDP_FullSync(MicrocodeArgument* ucode);
+
+    //Unimportant
+    static void RDP_TileSync(MicrocodeArgument* ucode);
+    static void RDP_PipeSync(MicrocodeArgument* ucode);
+    static void RDP_LoadSync(MicrocodeArgument* ucode);
+    static void RDP_SetConvert(MicrocodeArgument* ucode);
+    static void RDP_SetKeyR(MicrocodeArgument* ucode);
+    static void RDP_SetKeyGB(MicrocodeArgument* ucode);
+    static void RDP_Unknown(MicrocodeArgument* ucode);
+    static void RDP_NoOp(MicrocodeArgument* ucode);
+
+private:
+
+    static RDP* m_rdp;                                 //!< Pointer to Reality Drawing Processor
+    static DisplayListParser* m_displayListParser;     //!< Pointer to displaylist parser
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h b/source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h
new file mode 100755 (executable)
index 0000000..d67f71c
--- /dev/null
@@ -0,0 +1,147 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef RDP_UCODE_DEFS_H_
+#define RDP_UCODE_DEFS_H_
+
+//! Struct for setting color-, depth- and texture- image
+struct RDPUCodeSetImage
+{
+    unsigned int width:12;        //!< Width   
+    unsigned int :7;              //!< Padding
+    unsigned int size:2;          //!< Size    (0=4, 1=8, 2=16, or 3=32)
+    unsigned int format:3;        //!< Image format (0=RGBA, 1=YUV, 2=CI, 3=IA, 4=I, 5=?, 6=?, 7=?)
+    unsigned int cmd:8;           //!< Command
+    unsigned int segmentAddress;  //!< Address to register where there is an RDRAM address
+};
+
+//! Struct used by RDP to load textures
+struct RDPUCodeTileSize
+{
+    unsigned int t0:12;      //!< t texture coordinat for first vertex
+    unsigned int s0:12;      //!< s texture coordinat for first vertex
+    unsigned int cmd:8;      //!< Command, usualy LoadBlock, LoadTLUT, LoadTile, or SetTileSize
+    unsigned int t1:12;      //!< t texture coordinat for second vertex
+    unsigned int s1:12;      //!< s texture coordinat for second vertex  
+    unsigned int tile:3;     //!< Tile
+    unsigned int padding:5;  //!< Unused Padding 
+};
+
+//! Struct used by RDP to set tiles
+struct RDPUCodeSetTile 
+{
+    unsigned int    tmem:9;     //!< Address in Texture Memory
+    unsigned int    line:9;
+    unsigned int    pad0:1;     //!< Padding
+    unsigned int    size:2;
+    unsigned int    format:3;   //!< Image format of tile
+    unsigned int    cmd:8;      //!< Command, usualy SetTileSize
+    unsigned int    shiftS:4;
+    unsigned int    maskS:4;
+    unsigned int    mirrorS:1;  //!<
+    unsigned int    clampS:1;
+    unsigned int    shiftT:4;
+    unsigned int    maskT:4;
+    unsigned int    mirrorT:1;
+    unsigned int    clampT:1;
+    unsigned int    palette:4;
+    unsigned int    tile:3;
+    unsigned int    pad1:5;     //!< Padding
+};
+
+//! Struct used by RDP to set fog-, blend-, enviroment-, and prim- color (fillcolor is diffrent)
+struct RDPUCodeSetColor
+{
+    unsigned int prim_level:8;      //!< Only used by setPrimColor
+    unsigned int prim_min_level:8;  //!< Only used by setPrimColor
+    unsigned int pad0:8;            //!< Padding
+    unsigned int cmd:8;   //!< Command
+    unsigned int a:8;     //!< Alpha (0-255)
+    unsigned int b:8;     //!< Blue  (0-255)
+    unsigned int g:8;     //!< Green (0-255)
+    unsigned int r:8;     //!< Red   (0-255)
+};
+
+//! Struct used by RDP to set fill color
+struct RDPUCodeSetFillColor
+{
+    unsigned int pad0:24; //!< Padding
+    unsigned int cmd:8;   //!< Command
+    unsigned int a:1;     //!< Alpha  (0-1) 
+    unsigned int b:5;     //!< Blue   (0-255)
+    unsigned int g:5;     //!< Green  (0-255)
+    unsigned int r:5;     //!< Red    (0-255)
+    unsigned int pad1:16; //!< Padding
+};
+
+//! Struct used by RDP to render rectangles
+struct RDPUCodeRectangle
+{
+    unsigned int pad0 : 2;   //!< Padding
+    unsigned int y1   : 10;  //!< Y coordinate of second vertex corner
+    unsigned int pad1 : 2;   //!< Padding
+    unsigned int x1   : 10;  //!< X coordinate of second vertex corner
+    unsigned int cmd  : 8;   //!< Command
+    unsigned int pad3 : 2;   //!< Padding
+    unsigned int y0   : 10;  //!< Y coordinate of first vertex corner
+    unsigned int pad4 : 2;   //!< Padding
+    unsigned int x0   : 10;  //!< X coordinate of first vertex corner    
+    unsigned int pad5 : 8;   //!< Padding
+};
+
+//! Struct used by RDP to set scissor
+struct RDPUCodeScissor
+{
+    unsigned int    y0:12;        //!< Y coordinate of second vertex
+    unsigned int    x0:12;        //!< X coordinate of second vertex    
+    unsigned int    cmd:8;        //!< Command usualy         
+    unsigned int    y1:12;        //!< Y coordinate of first vertex    
+    unsigned int    x1:12;        //!< X coordinate of first vertex
+    unsigned int    mode:2;        //!< 
+    unsigned int    pad0:6;        //!< Padding TexRect or TexRectFlip    
+};
+
+//! Struct used by RDP to render textured rectangles
+struct RDPUCodeTextureRectangle
+{
+    unsigned int    y1:12;        //!< Y coordinate of second vertex
+    unsigned int    x1:12;        //!< X coordinate of second vertex    
+    unsigned int    cmd:8;        //!< Command usualy         
+    unsigned int    y0:12;        //!< Y coordinate of first vertex    
+    unsigned int    x0:12;        //!< X coordinate of first vertex
+    unsigned int    tile:3;       //!< Tile descriptor index    
+    unsigned int    pad0:5;       //!< Padding TexRect or TexRectFlip            
+    unsigned int    t:16;         //!< T texture coord at first vertex
+    unsigned int    s:16;         //!< S texture coord at first vertex
+    unsigned int    dtdy:16;      //!< Change in T per change in Y    
+    unsigned int    dsdx:16;      //!< Change in S per change in X    
+};
+
+//! Struct used by RDP to set prim depth
+struct RDPUCodeSetPrimDepth
+{
+    unsigned int pad0:24; //!< Padding
+    unsigned int cmd:8;   //!< Command
+    unsigned int dz:16;   
+    unsigned int z:16;    //!< Depth value
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp
new file mode 100755 (executable)
index 0000000..0d86e22
--- /dev/null
@@ -0,0 +1,635 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RSP.h"
+#include "../UCodeDefs.h"
+#include "../RDP/RDP.h"
+#include <cmath>
+#include "GBIDefs.h"
+#include "VI.h"
+#include "Memory.h"
+#include "Logger.h"
+#include "OpenGLRenderer.h"
+#include "OpenGLManager.h"
+#include "RSPLightManager.h"
+#include "FogManager.h"
+#include "DisplayListParser.h"
+#include "MathLib.h"
+#include "MathLib.h"
+
+#define MI_INTR_SP                 0x00000001  //!< RSP Interrupt signal
+
+//Geometry Mode Definitions
+#define G_ZBUFFER                0x00000001
+#define G_SHADE                    0x00000004
+#define G_FOG                    0x00010000
+#define G_LIGHTING                0x00020000
+#define G_TEXTURE_GEN            0x00040000
+#define G_TEXTURE_GEN_LINEAR    0x00080000
+#define G_LOD                    0x00100000
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RSP::RSP()
+{
+    m_texturesChanged = false;
+    m_matrixMgr = 0;
+    m_vertexMgr = 0;
+    m_lightMgr  = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RSP::~RSP()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool RSP::initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* dlp, FogManager* fogMgr)
+{
+    //Save pointers
+    m_graphicsInfo = graphicsInfo;
+    m_rdp = rdp;
+    m_vi = vi;
+    m_memory = memory;
+    m_displayListParser = dlp;
+    m_fogMgr = fogMgr;       
+
+    //Initialize Matrix Manager
+    m_matrixMgr = new RSPMatrixManager();
+    if ( !m_matrixMgr->initialize(m_memory) ) {
+        return false;
+    }
+
+    //Initialzie Light Manager
+    m_lightMgr = new RSPLightManager();
+    if ( !m_lightMgr->initialize(m_memory) ) {
+        return false;
+    }
+
+    //Initialzie Vertex Manager
+    m_vertexMgr = new RSPVertexManager();
+    if ( !m_vertexMgr->initialize(&OpenGLManager::getSingleton(), m_memory, m_matrixMgr, m_lightMgr) ) {
+        return false;
+    }
+
+    m_textureTiles[0] = m_rdp->getTile(0);
+    m_textureTiles[1] = m_rdp->getTile(1);
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Dispose
+//-----------------------------------------------------------------------------
+void RSP::dispose()
+{
+    if ( m_matrixMgr ) { delete m_matrixMgr; m_matrixMgr = 0; }
+    if ( m_vertexMgr ) { delete m_vertexMgr; m_vertexMgr = 0; }
+    if ( m_lightMgr  ) { delete m_lightMgr ; m_lightMgr  = 0; }    
+}
+
+//-----------------------------------------------------------------------------
+//* Update Geometry States
+//-----------------------------------------------------------------------------
+void RSP::updateGeometryStates()
+{
+    bool cullFront           = (m_geometryMode & GBI::G_CULL_FRONT    ) != 0;
+    bool cullBack            = (m_geometryMode & GBI::G_CULL_BACK     ) != 0;
+    bool fog                 = (m_geometryMode & G_FOG                ) != 0;
+    bool textureGen          = (m_geometryMode & G_TEXTURE_GEN        ) != 0;
+    bool lighting            = (m_geometryMode & G_LIGHTING           ) != 0;
+    bool zBuffer             = (m_geometryMode & G_ZBUFFER            ) != 0;
+
+    //Update states
+    m_lightMgr->setLightEnabled(lighting);
+    m_vertexMgr->setTexCoordGenType( textureGen ? TCGT_LINEAR : TCGT_NONE);
+    OpenGLManager::getSingleton().setZBufferEnabled(zBuffer);
+    OpenGLManager::getSingleton().setCullMode(cullFront, cullBack);
+    OpenGLManager::getSingleton().setFogEnabled(fog);
+}
+
+//-----------------------------------------------------------------------------
+// Reset
+//-----------------------------------------------------------------------------
+void RSP::reset()
+{
+    m_matrixMgr->resetMatrices();
+}
+
+//-----------------------------------------------------------------------------
+//* Trigger Interupt
+//-----------------------------------------------------------------------------
+void RSP::triggerInterrupt()
+{
+    *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_SP;
+    m_graphicsInfo->CheckInterrupts();    
+}
+
+//-----------------------------------------------------------------------------
+//* Move Segment
+//-----------------------------------------------------------------------------
+void RSP::moveSegment(int segmentID, int value)
+{
+    m_memory->setSegment(segmentID, value);
+}
+
+//-----------------------------------------------------------------------------
+// Set Viewport
+// FIXME
+//-----------------------------------------------------------------------------
+void RSP::moveMemViewport(unsigned int segmentAddress)
+{
+    //Get Adress
+    unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress);
+
+    //Error controll
+    if ( rdramAddress + 16 > m_memory->getRDRAMSize() )
+    {
+        Logger::getSingleton().printMsg("MoveMem Viewport, accessed invalid memory", M64MSG_ERROR);
+        return;
+    }
+
+    m_viewport.vscale[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress +  2), 2 );
+    m_viewport.vscale[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress     ), 2 );
+    m_viewport.vscale[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress +  6), 10 );// * 0.00097847357f;
+    m_viewport.vscale[3] = *(short*)m_memory->getRDRAM(rdramAddress +  4);
+    m_viewport.vtrans[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 10), 2 );
+    m_viewport.vtrans[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress +  8), 2 );
+    m_viewport.vtrans[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 14), 10 );// * 0.00097847357f;
+    m_viewport.vtrans[3] = *(short*)m_memory->getRDRAM(rdramAddress + 12);
+
+    m_viewport.x      = m_viewport.vtrans[0] - m_viewport.vscale[0];
+    m_viewport.y      = m_viewport.vtrans[1] - m_viewport.vscale[1];
+    m_viewport.width  = m_viewport.vscale[0] * 2;
+    m_viewport.height = m_viewport.vscale[1] * 2;
+    m_viewport.nearz  = m_viewport.vtrans[2] - m_viewport.vscale[2];
+    m_viewport.farz   = (m_viewport.vtrans[2] + m_viewport.vscale[2]) ;
+
+    /*
+    //Set Viewport
+    OpenGLManager::getSingleton().setViewport( 
+            m_viewport.x, // * OGL.scaleX, 
+            m_viewport.y, //(VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset, 
+            //(m_vi->getHeight() - (m_viewport.y + m_viewport.height)),
+            m_viewport.width, // * OGL.scaleX, 
+            m_viewport.height, // * OGL.scaleY,
+            0.0f,   //m_viewport.nearz, 
+            1.0f ); //m_viewport.farz );            
+            */
+}
+
+//-----------------------------------------------------------------------------
+//* Load UCode Ex
+//! @todo Change ucode while running
+//-----------------------------------------------------------------------------
+void RSP::RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize )
+{
+    Logger::getSingleton().printMsg("RSP_LoadUcodeEx - Unimplemented", M64MSG_WARNING);
+    //TODO or skip
+
+    /*
+
+    RSP.PCi = 0;
+    gSP.matrix.modelViewi = 0;
+    gSP.changed |= CHANGED_MATRIX;
+    gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0;
+
+    if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize))
+    {
+            return;
+    }
+
+    MicrocodeInfo *ucode = GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize );
+
+    if (ucode->type != NONE)
+        GBI_MakeCurrent( ucode );
+    else
+        SetEvent( RSP.threadMsg[RSPMSG_CLOSE] );
+    */
+}
+
+//*****************************************************************************
+// Matrix Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// RSP Matrix
+//-----------------------------------------------------------------------------
+void RSP::RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace )
+{ 
+    Logger::getSingleton().printMsg("RSP_Matrix");
+    m_matrixMgr->addMatrix( segmentAddress,             //Segment adress 
+                            projectionMatrix,           //Projection or view matrix?
+                            push,                       //Save Current Matrix?
+                            replace );                  //Replace aka Load or Mult 
+}
+
+//-----------------------------------------------------------------------------
+// RSP DMA Matrix
+//-----------------------------------------------------------------------------
+void RSP::RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply )
+{
+    m_matrixMgr->DMAMatrix(m_memory->getRDRAMAddress(matrix), index, multiply);
+}
+
+//-----------------------------------------------------------------------------
+// RSP Force Matrix
+//-----------------------------------------------------------------------------
+void RSP::RSP_ForceMatrix( unsigned int segmentAddress )
+{ 
+    // Logger::getSingleton().printMsg("RSP_ForceMatrix", M64MSG_WARNING);
+    m_matrixMgr->ForceMatrix( m_memory->getRDRAMAddress(segmentAddress));
+}
+
+//-----------------------------------------------------------------------------
+// Pop Matrix
+//-----------------------------------------------------------------------------
+void RSP::RSP_PopMatrix( )
+{
+    m_matrixMgr->popMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//* Pop Matrix N
+//! Pop Matrix from stack N number of times
+//! @param num The number of matrices to pop from matrix-stack
+//-----------------------------------------------------------------------------
+void RSP::RSP_PopMatrixN( unsigned int num )
+{ 
+    m_matrixMgr->popMatrixN(num);
+}
+
+//-----------------------------------------------------------------------------
+// Insert Matrix
+//-----------------------------------------------------------------------------
+void RSP::RSP_InsertMatrix(unsigned int where, unsigned int num)
+{
+    m_matrixMgr->insertMatrix(where, num);
+}
+
+//*****************************************************************************
+// Misc
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Fog Factor
+//-----------------------------------------------------------------------------
+void RSP::RSP_FogFactor(short fogMultiplier, short fogOffset)
+{
+    m_fogMgr->setFogSettings((float)fogMultiplier, (float)fogOffset);
+}
+
+//-----------------------------------------------------------------------------
+// Texture
+//-----------------------------------------------------------------------------
+void RSP::RSP_Texture( float scaleS, float scaleT, int level, int tile, int on )
+{ 
+    //Set Texture
+    m_texture.scaleS = (scaleS != 0.0f) ? scaleS : 1.0f;
+    m_texture.scaleT = (scaleT != 0.0f) ? scaleT : 1.0f;
+    m_texture.level  = level;
+    m_texture.on     = on;
+    m_texture.tile   = tile;
+
+    //Set Tiles (note: There are max 8 tiles)    
+    if ( tile < 7 )
+    {
+        m_textureTiles[0] = m_rdp->getTile(tile);
+        m_textureTiles[1] = m_rdp->getTile(tile+1);
+    }
+    else
+    {
+        m_textureTiles[0] = m_rdp->getTile(tile);
+        m_textureTiles[1] = m_rdp->getTile(tile);
+    }
+
+    m_texturesChanged = true;
+}
+
+//-----------------------------------------------------------------------------
+// Set DMA Offsets
+//-----------------------------------------------------------------------------
+void RSP::RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset )
+{
+    m_matrixMgr->setRDRAMOffset(mtxoffset);
+    m_vertexMgr->setRDRAMOffset(vtxoffset);
+}
+
+//*****************************************************************************
+// Light
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// RSP Light
+//-----------------------------------------------------------------------------
+void RSP::RSP_Light( unsigned int lightIndex, unsigned int segmentAddress )
+{ 
+    m_lightMgr->setLight(lightIndex, m_memory->getRDRAMAddress(segmentAddress) );
+}
+
+//-----------------------------------------------------------------------------
+// Num Lights
+//-----------------------------------------------------------------------------
+void RSP::RSP_NumLights( int numLights )
+{ 
+    m_lightMgr->setNumLights(numLights);
+}
+
+//-----------------------------------------------------------------------------
+// Light Color
+//-----------------------------------------------------------------------------
+void RSP::RSP_LightColor( unsigned int lightIndex, unsigned int packedColor )
+{
+    m_lightMgr->setLightColor(lightIndex, packedColor);
+}
+
+//*****************************************************************************
+// Vertex
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Vertex
+//-----------------------------------------------------------------------------
+void RSP::RSP_Vertex( unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex  )
+{ 
+    m_vertexMgr->setVertices(m_memory->getRDRAMAddress(segmentAddress), numVertices, firstVertexIndex);
+}
+
+//-----------------------------------------------------------------------------
+// Modify Vertex
+//-----------------------------------------------------------------------------
+void RSP::RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val )
+{
+    m_vertexMgr->modifyVertex(vtx, where, val);
+}
+
+void RSP::RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a)
+{
+    m_vertexMgr->setVertexColor(vtx, r,g,b,a);
+}
+
+void RSP::RSP_SetVertexTexCoord( unsigned int vtx, float s, float t)
+{
+    m_vertexMgr->setVertexTextureCoord(vtx, s,t);
+}
+
+//-----------------------------------------------------------------------------
+//! Color Index Vertex
+//! param segmentAddress Address to register where there is an RDRAM address 
+//!                      used to retrieve vertices from RDRAM.
+//! param numVertices Number of vertices to retrive from RDRAM.
+//! param firstVertexIndex Index of first vertex
+//-----------------------------------------------------------------------------
+void RSP::RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex )
+{    
+    m_vertexMgr->ciVertex(segmentAddress, numVertices, firstVertexIndex);
+}
+
+//-----------------------------------------------------------------------------
+// DMA Vertex
+//-----------------------------------------------------------------------------
+void RSP::RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 )
+{
+    m_vertexMgr->DMAVertex(v, n, v0);
+}
+
+//-----------------------------------------------------------------------------
+// Set Vertex Color Base
+//-----------------------------------------------------------------------------
+void RSP::RSP_SetVertexColorBase(unsigned int segmentAddress)
+{
+    m_vertexMgr->setVertexColorBase( m_memory->getRDRAMAddress(segmentAddress) );
+}
+
+//*****************************************************************************
+// Display List
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Display List
+//-----------------------------------------------------------------------------
+void RSP::RSP_DisplayList(unsigned int segmentAddress)
+{
+    m_displayListParser->displayList(segmentAddress);
+}
+
+//-----------------------------------------------------------------------------
+// DMA Display List
+//-----------------------------------------------------------------------------
+void RSP::RSP_DMADisplayList( unsigned int w0, unsigned int w1 )
+{ 
+    m_displayListParser->DMADisplayList(w0, w1);
+}
+
+//-----------------------------------------------------------------------------
+// Branch Display List
+//-----------------------------------------------------------------------------
+void RSP::RSP_BranchList( unsigned int dl )
+{ 
+    m_displayListParser->branchDisplayList(dl);
+}
+
+//-----------------------------------------------------------------------------
+// Branch Display List Z
+//-----------------------------------------------------------------------------
+void RSP::RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval )
+{ 
+    if ( m_vertexMgr->getVertex(vtx)->z <= zval ) {
+        m_displayListParser->branchDisplayList(branchdl);
+    }
+}
+
+//-----------------------------------------------------------------------------
+// End Display List
+//-----------------------------------------------------------------------------
+void RSP::RSP_EndDisplayList() 
+{ 
+    m_displayListParser->endDisplayList();
+}
+
+//-----------------------------------------------------------------------------
+//* Cull Display List
+//! @todo Cull Display List
+//-----------------------------------------------------------------------------
+void RSP::RSP_CullDisplayList( unsigned int v0, unsigned int vn )
+{
+    //Logger::getSingleton().printMsg("RSP_CullDisplayList - Unimplemented", M64MSG_WARNING);
+    //TODO
+}
+
+//*****************************************************************************
+// Indices
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// 1 Triangle
+//-----------------------------------------------------------------------------
+void RSP::RSP_1Triangle( int v0, int v1, int v2)
+{ 
+    m_vertexMgr->add1Triangle(v0, v1, v2);
+}
+
+//-----------------------------------------------------------------------------
+// 2 Trangles
+//-----------------------------------------------------------------------------
+void RSP::RSP_2Triangles( int v00, int v01, int v02, int flag0, 
+                    int v10, int v11, int v12, int flag1 )
+{            
+    m_vertexMgr->add1Triangle(v00, v01, v02);        
+    m_vertexMgr->add1Triangle(v10, v11, v12);
+}
+
+//-----------------------------------------------------------------------------
+// 4 Triangles
+//-----------------------------------------------------------------------------
+void RSP::RSP_4Triangles( int v00, int v01, int v02,
+                    int v10, int v11, int v12,
+                    int v20, int v21, int v22,
+                    int v30, int v31, int v32 )
+{
+    m_vertexMgr->add1Triangle(v00, v01, v02);
+    m_vertexMgr->add1Triangle(v10, v11, v12);
+    m_vertexMgr->add1Triangle(v20, v21, v22);
+    m_vertexMgr->add1Triangle(v30, v31, v32);
+}
+
+//-----------------------------------------------------------------------------
+// DMA Triangel
+//-----------------------------------------------------------------------------
+void RSP::RSP_DMATriangles( unsigned int tris, unsigned int n )
+{ 
+    m_vertexMgr->addDMATriangles(tris, n);
+}
+
+//-----------------------------------------------------------------------------
+// Quadrangle
+//-----------------------------------------------------------------------------
+void RSP::RSP_1Quadrangle( int v0, int v1, int v2, int v3 )
+{
+    m_vertexMgr->add1Triangle(v0, v1, v2);
+    m_vertexMgr->add1Triangle(v0, v2, v3);
+}
+
+//*****************************************************************************
+// Geometry Mode
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Geometry Mode
+//-----------------------------------------------------------------------------
+void RSP::RSP_GeometryMode(unsigned int clear, unsigned int set)
+{ 
+    RSP_ClearGeometryMode(clear);
+    RSP_SetGeometryMode(set);    
+}
+
+//-----------------------------------------------------------------------------
+// Set Geometry Mode
+//-----------------------------------------------------------------------------
+void RSP::RSP_SetGeometryMode( unsigned int mode )
+{ 
+    m_geometryMode |= mode;
+    updateGeometryStates();
+}
+
+//-----------------------------------------------------------------------------
+// Clear Geometry Mode
+//-----------------------------------------------------------------------------
+void RSP::RSP_ClearGeometryMode( unsigned int mode )
+{
+    m_geometryMode &= ~mode;
+    updateGeometryStates();
+}
+
+//*****************************************************************************
+// Other
+//*****************************************************************************
+
+void RSP::RSP_Line3D( int v0, int v1, int flag )
+{
+    Logger::getSingleton().printMsg("RSP_Line3D - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_LineW3D( int v0, int v1, int wd, int flag )
+{
+    Logger::getSingleton().printMsg("RSP_LineW3D - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjRectangle( unsigned int sp )
+{
+    Logger::getSingleton().printMsg("RSP_ObjRectangle - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjSprite( unsigned int sp )
+{
+    Logger::getSingleton().printMsg("RSP_ObjSprite - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjLoadTxtr( unsigned int tx )
+{
+    Logger::getSingleton().printMsg("RSP_ObjLoadTxtr - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjLoadTxSprite( unsigned int txsp )
+{
+    Logger::getSingleton().printMsg("RSP_ObjLoadTxSprite - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjLoadTxRectR( unsigned int txsp )
+{
+    Logger::getSingleton().printMsg("RSP_ObjLoadTxRectR - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_BgRect1Cyc( unsigned int bg )
+{
+    Logger::getSingleton().printMsg("RSP_BgRect1Cyc - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_BgRectCopy( unsigned int bg )
+{
+    Logger::getSingleton().printMsg("RSP_BgRectCopy - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjMatrix( unsigned int mtx )
+{ 
+    Logger::getSingleton().printMsg("RSP_ObjMatrix - Unimplemented", M64MSG_WARNING);
+}
+void RSP::RSP_ObjSubMatrix( unsigned int mtx )
+{
+    Logger::getSingleton().printMsg("RSP_ObjSubMatrix - Unimplemented", M64MSG_WARNING);
+}
+
+//*****************************************************************************
+// Non important functions
+//*****************************************************************************
+
+void RSP::RSP_Sprite2DBase( unsigned int base ) {
+    Logger::getSingleton().printMsg("RSP_Sprite2DBase - Unimplemented", M64MSG_WARNING);
+}
+
+void RSP::RSP_LookAt( unsigned int l ) {
+    Logger::getSingleton().printMsg("RSP_LookAt - Unimplemented", M64MSG_WARNING);
+}
+
+void RSP::RSP_ClipRatio( unsigned int r ) {
+    Logger::getSingleton().printMsg("RSP_ClipRatio - Unimplemented", M64MSG_WARNING);
+}
+
+void RSP::RSP_PerspNormalize( unsigned short scale ) {
+    Logger::getSingleton().printMsg("RSP_PerspNormalize - Unimplemented", M64MSG_WARNING);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSP.h b/source/mupen64plus-video-arachnoid/src/RSP/RSP.h
new file mode 100755 (executable)
index 0000000..26692f6
--- /dev/null
@@ -0,0 +1,256 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef REALITY_SIGNAL_PROCESSOR_H_
+#define REALITY_SIGNAL_PROCESSOR_H_
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_plugin.h"
+#include "UCodeDefs.h"
+#include "RSPMatrixManager.h"
+#include "RSPVertexManager.h"
+#include "Matrix4.h"
+
+//Forward declarations
+class VI;
+struct RDPTile;
+class RDP;
+class Memory;
+class DisplayListParser;
+class RSPLightManager;
+class FogManager;
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+#define RSP_1ST                 0xBF
+#define RSP_TRI1                (RSP_1ST-0)
+#define RSP_CULLDL              (RSP_1ST-1)
+#define RSP_POPMTX              (RSP_1ST-2)
+#define RSP_MOVEWORD            (RSP_1ST-3)
+#define RSP_TEXTURE             (RSP_1ST-4)
+#define RSP_SETOTHERMODE_H      (RSP_1ST-5)
+#define RSP_SETOTHERMODE_L      (RSP_1ST-6)
+#define RSP_ENDDL               (RSP_1ST-7)
+#define RSP_SETGEOMETRYMODE     (RSP_1ST-8)
+#define RSP_CLEARGEOMETRYMODE   (RSP_1ST-9)
+#define RSP_LINE3D              (RSP_1ST-10)
+#define RSP_RDPHALF_1           (RSP_1ST-11)
+#define RSP_RDPHALF_2           (RSP_1ST-12)
+#define RSP_RDPHALF_CONT        (RSP_1ST-13)
+
+#define RSP_MODIFYVTX           (RSP_1ST-13)
+#define RSP_TRI2                (RSP_1ST-14)
+#define RSP_BRANCH_Z            (RSP_1ST-15)
+#define RSP_LOAD_UCODE          (RSP_1ST-16)
+
+#define RSP_SPRITE2D_SCALEFLIP  (RSP_1ST-1)
+#define RSP_SPRITE2D_DRAW       (RSP_1ST-2)
+
+// flags to inhibit pushing of the display list (on branch)
+#define RSP_DLIST_PUSH          0x00
+#define RSP_DLIST_NOPUSH        0x01
+
+//-----------------------------------------------------------------------------
+//! Viewport
+//-----------------------------------------------------------------------------
+struct Viewport
+{
+    float vscale[4];
+    float vtrans[4];
+    float x, y, width, height;
+    float nearz, farz;
+};
+
+
+//-----------------------------------------------------------------------------
+//! Struct used to store Information about Background Image
+//-----------------------------------------------------------------------------
+struct BGImageInfo
+{
+    unsigned int address;  //!< Where texture is stored (in RDRAM)
+    unsigned int width;    //!< Width of texture
+    unsigned int height;   //!< Height of texture
+    unsigned int format;   //!< Format of texture
+    unsigned int size;     //!< Size of texture
+    unsigned int palette;  //!< What Texture Lookup Table to use
+};
+
+//-----------------------------------------------------------------------------
+//* RSPTexture
+//! Struct used to store information about current texture on rsp
+//-----------------------------------------------------------------------------
+struct RSPTexture
+{
+    float scaleS, scaleT;
+    int level, on, tile;
+};
+
+//-----------------------------------------------------------------------------
+//! Singnal Processor Triangle
+//-----------------------------------------------------------------------------
+typedef SPVertex SPTriangle[3];
+
+//*****************************************************************************
+//* RSP
+//! Class for emulating the Reality Signal Processor
+//*****************************************************************************
+class RSP
+{
+public:
+    //Constructor
+    RSP();
+    //Destructor    
+    ~RSP();
+
+    //Initialize
+    bool initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr);
+    void dispose();
+    void reset();
+
+    void updateGeometryStates();
+
+    //Trigger Interrupt
+    void triggerInterrupt();
+
+    void moveSegment(int segmentID, int value);
+
+    void moveMemViewport(unsigned int segmentAddress);
+
+    RDPTile* getTile(int tile) { return m_textureTiles[tile]; }
+    void setTile(RDPTile* tile, int index) { m_textureTiles[index] = tile; }
+    RSPTexture& getTexture() { return m_texture; }
+    bool getTexturesChanged() { return m_texturesChanged; }
+    void setTexturesChanged(bool changed) { m_texturesChanged = changed; }
+
+    RSPMatrixManager* getMatrixMgr() { return m_matrixMgr; }
+    RSPVertexManager* getVertexMgr() { return m_vertexMgr; }
+
+public:
+
+    //Matrix
+    void RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace );
+    void RSP_PopMatrix();
+    void RSP_PopMatrixN(unsigned int num);
+    void RSP_InsertMatrix(unsigned int where, unsigned int num);
+    void RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply );
+    void RSP_ForceMatrix( unsigned int segmentAddress );
+    void RSP_LookAt( unsigned int l );
+    void RSP_PerspNormalize( unsigned short scale );    
+
+    //Display List
+    void RSP_DisplayList(unsigned int segmentAddress);
+    void RSP_DMADisplayList( unsigned int w0, unsigned int w1 );
+    void RSP_CullDisplayList( unsigned int v0, unsigned int vn );
+    void RSP_BranchList( unsigned int dl );
+    void RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval );    
+    void RSP_EndDisplayList();
+
+    //Light
+    void RSP_Light( unsigned int lightIndex, unsigned int segmentAddress  );
+    void RSP_NumLights( int n );
+    void RSP_LightColor( unsigned int lightIndex, unsigned int packedColor );    
+
+    //Vertices
+    void RSP_Vertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex);
+    void RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex);
+    void RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val );    
+    void RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a);    
+    void RSP_SetVertexTexCoord( unsigned int vtx, float s, float t);    
+
+    void RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 );
+    void RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset );
+    void RSP_SetVertexColorBase(unsigned int segmentAddress);
+
+    //Indices
+    void RSP_1Triangle( int v00, int v01, int v02 );
+    void RSP_2Triangles( int v00, int v01, int v02, int flag0, 
+                         int v10, int v11, int v12, int flag1 );
+    void RSP_4Triangles( int v00, int v01, int v02,
+                         int v10, int v11, int v12,
+                         int v20, int v21, int v22,
+                         int v30, int v31, int v32 );
+    void RSP_DMATriangles( unsigned int tris, unsigned int n );
+    void RSP_1Quadrangle( int v0, int v1, int v2, int v4 );
+
+    //Object
+    void RSP_ObjRectangle( unsigned int sp );
+    void RSP_ObjSprite( unsigned int sp );
+    void RSP_ObjLoadTxtr( unsigned int tx );
+    void RSP_ObjLoadTxSprite( unsigned int txsp );
+    void RSP_ObjLoadTxRectR( unsigned int txsp );
+    void RSP_ObjMatrix( unsigned int mtx );
+    void RSP_ObjSubMatrix( unsigned int mtx );
+
+    //Rendering
+    void RSP_Line3D( int v0, int v1, int flag );
+    void RSP_LineW3D( int v0, int v1, int wd, int flag );
+    void RSP_BgRect1Cyc( unsigned int bg );
+    void RSP_BgRectCopy( unsigned int bg );
+    void RSP_Sprite2DBase( unsigned int base );
+
+    //States
+    void RSP_GeometryMode( unsigned int clear, unsigned int set );
+    void RSP_SetGeometryMode( unsigned int mode );
+    void RSP_ClearGeometryMode( unsigned int mode );
+
+    //Clipping    
+    void RSP_ClipRatio( unsigned int r );
+
+    //Texturing
+    void RSP_Texture( float sc, float tc, int level, int tile, int on );
+
+    //Fog
+    void RSP_FogFactor( short fm, short fo );    
+
+    //UCode
+    void RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize );
+
+private:
+
+    //Pointers to big objects and managers
+    GFX_INFO*          m_graphicsInfo;       //!< Access to emulator data (like RDRAM ...)
+    VI*                m_vi;                 //!< Videointerface
+    Memory*            m_memory;             //!< Memory managers (handles RDRAM, Texture Memory...)
+    DisplayListParser* m_displayListParser;  //!< Display list parser
+    FogManager*        m_fogMgr;             //!< Manager that handles fog
+    RDP*               m_rdp;                //!< Pointer to Reality Drawing Processor 
+
+    //Helper managers
+    RSPMatrixManager* m_matrixMgr;           //!< Handles matrix stack
+    RSPVertexManager* m_vertexMgr;           //!< Vertex Manager, processes and modifies vertices 
+    RSPLightManager*  m_lightMgr;            //!< Light Manager, handles lights
+
+    //Geometry Mode
+    unsigned int m_geometryMode;  //!< Contains states (lighting, shading, culling...)
+
+    //Textures
+    RSPTexture m_texture;  
+    RDPTile* m_textureTiles[2];
+    bool m_texturesChanged;
+
+    //Viewport
+    Viewport m_viewport;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp
new file mode 100755 (executable)
index 0000000..3384fcb
--- /dev/null
@@ -0,0 +1,105 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RSPLightManager.h"
+#include "Memory.h"
+#include "MathLib.h"
+#include "GBI.h"
+#include "Logger.h"
+
+#define RGBA_GETALPHA(rgb)      ((rgb) >> 24)
+#define RGBA_GETRED(rgb)        (((rgb) >> 16) & 0xff)
+#define RGBA_GETGREEN(rgb)      (((rgb) >> 8) & 0xff)
+#define RGBA_GETBLUE(rgb)       ((rgb) & 0xff)
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RSPLightManager::RSPLightManager() 
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RSPLightManager::~RSPLightManager()
+{
+}
+
+bool RSPLightManager::initialize(Memory* memory)
+{
+    m_memory = memory;
+    m_numLights = 0;
+    m_lightEnabled = false;
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Set Light
+//-----------------------------------------------------------------------------
+void RSPLightManager::setLight( unsigned int lightIndex, unsigned int rdramAddress  )
+{
+    //Error control 
+    if ((rdramAddress + sizeof(RDRAMLight)) > m_memory->getRDRAMSize() ) {
+        return;
+    }
+
+    //Get Light from memory
+    RDRAMLight* light = (RDRAMLight*)m_memory->getRDRAM(rdramAddress);
+
+    if ( lightIndex < 8 ) //Only supports 8 lights
+    {
+        m_lights[lightIndex].r = light->r * 0.0039215689f;  //Convert from 0-255 to 0-1
+        m_lights[lightIndex].g = light->g * 0.0039215689f;
+        m_lights[lightIndex].b = light->b * 0.0039215689f;
+
+        m_lights[lightIndex].x = light->x;
+        m_lights[lightIndex].y = light->y;
+        m_lights[lightIndex].z = light->z;    
+
+        Vec3Normalize( &m_lights[lightIndex].x );
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Set Num Lights
+//-----------------------------------------------------------------------------
+void RSPLightManager::setNumLights(int numLights)
+{
+    if (numLights <= 8) 
+    {
+        m_numLights = numLights;    
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Set Light Color
+//-----------------------------------------------------------------------------
+void RSPLightManager::setLightColor( unsigned int lightIndex, unsigned int packedColor )
+{
+    if (lightIndex < 8)
+    {
+        m_lights[lightIndex].r = _SHIFTR( packedColor, 24, 8 ) * 0.0039215689f;
+        m_lights[lightIndex].g = _SHIFTR( packedColor, 16, 8 ) * 0.0039215689f;
+        m_lights[lightIndex].b = _SHIFTR( packedColor, 8, 8 ) * 0.0039215689f;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h
new file mode 100755 (executable)
index 0000000..7c99ebf
--- /dev/null
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef RSP_LIGHT_MANAGER_H_
+#define RSP_LIGHT_MANAGER_H_
+
+//Forward declarations
+class Memory;
+
+//-----------------------------------------------------------------------------
+//* Light
+//! Struct defining how lights are stored in RDRAM 
+//-----------------------------------------------------------------------------
+struct RDRAMLight
+{
+    unsigned char pad0;       //!< Padding
+    unsigned char b, g, r;    //!< Color <blue, green, red>
+    unsigned char pad1;       //!< Padding
+    unsigned char b2, g2, r2; //!< Color <blue, green, red>
+    char pad2;                //!< Padding
+    char z, y, x;             //!< Direction
+};
+
+//-----------------------------------------------------------------------------
+//* RSP Light
+//! Struct used to store information about lights
+//-----------------------------------------------------------------------------
+struct RSPLight
+{
+    float r, g, b;  //Color
+    float x, y, z;  //Direction
+};
+
+//*****************************************************************************
+//! RSP Light Manager
+//*****************************************************************************
+class RSPLightManager
+{
+public:
+
+    //Constructor / Destructor
+    RSPLightManager();
+    ~RSPLightManager();
+
+    bool initialize(Memory* memory);
+
+    void setLight( unsigned int lightIndex, unsigned int rdramAddress  );
+    void setNumLights(int numLights);
+    void setLightColor( unsigned int lightIndex, unsigned int packedColor );    
+    const float* getAmbientLight() { return &m_lights[m_numLights].r; }
+
+    //Get
+    int getNumLights()                              { return m_numLights; }
+    void setLightEnabled(bool enabled)              { m_lightEnabled = enabled; }
+    bool getLightEnabled()                          { return m_lightEnabled; }    
+    const float* getLightColor(int lightIndex)      { return &m_lights[lightIndex].r; }
+    const float* getLightDirection(int lightIndex)  { return &m_lights[lightIndex].x; }
+
+private:
+
+    Memory* m_memory;
+
+    //Light
+    bool m_lightEnabled;
+    RSPLight m_lights[8];
+    int m_numLights;
+
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp
new file mode 100755 (executable)
index 0000000..89a4923
--- /dev/null
@@ -0,0 +1,291 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RSPMatrixManager.h"
+#include "Memory.h"
+#include <cmath>      //modff
+#include "GBI.h"      //SHIFT
+#include "GBIDefs.h"  //_FIXED2FLOAT
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RSPMatrixManager::RSPMatrixManager()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RSPMatrixManager::~RSPMatrixManager()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool RSPMatrixManager::initialize(Memory* memory)
+{
+    m_memory = memory;
+    m_rdramOffset = 0;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//! Add Matrix
+//! @param segmentAddress Later converted to RDRam address pointing to Matrix to load
+//! @param projectionMatrix True if matrix is a projection matrix, 
+//!                         False if matrix is a modelview matrix
+//! @param push True if adding a new matrix to stack(and saving the old one)
+//! @param replace True if loading matrix (glLoadMatrix), false if multiplying with the previus matrix (glMultMatrix)
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::addMatrix(unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace)
+{
+    unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress);
+
+    if (rdramAddress + 64 > m_memory->getRDRAMSize() ) {
+        return;
+    }
+
+    Matrix4 temp;
+    _loadMatrix(rdramAddress, temp);
+    
+    if ( projectionMatrix )
+    {
+        _setProjection(temp, push, replace);
+    }
+    else
+    {
+        _setWorldView(temp, push, replace);
+    }
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! Insert Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::insertMatrix(unsigned int where, unsigned int num) 
+{
+    float fraction, integer;
+
+    _updateCombinedMatrix();
+
+    if ((where & 0x3) || (where > 0x3C))
+    {
+        return;
+    }
+
+    if (where < 0x20)
+    {
+        fraction = modff( m_worldProject[0][where >> 1], &integer );
+        m_worldProject[0][where >> 1] = (short)_SHIFTR( num, 16, 16 ) + fabs( fraction );
+
+        fraction = modff( m_worldProject[0][(where >> 1) + 1], &integer );
+        m_worldProject[0][(where >> 1) + 1] = (short)_SHIFTR( num, 0, 16 ) + fabs( fraction );
+    }
+    else
+    {
+        float newValue;
+
+        fraction = modff( m_worldProject[0][(where - 0x20) >> 1], &integer );
+        newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 16, 16 ), 16);
+
+        // Make sure the sign isn't lost
+        if ((integer == 0.0f) && (fraction != 0.0f))
+            newValue = newValue * (fraction / fabs( fraction ));
+
+        m_worldProject[0][(where - 0x20) >> 1] = newValue;
+
+        fraction = modff( m_worldProject[0][((where - 0x20) >> 1) + 1], &integer );
+        newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 0, 16 ), 16 );
+
+        // Make sure the sign isn't lost
+        if ((integer == 0.0f) && (fraction != 0.0f))
+            newValue = newValue * (fraction / fabs( fraction ));
+
+        m_worldProject[0][((where - 0x20) >> 1) + 1] = newValue;
+    }
+}
+void RSPMatrixManager::ForceMatrix(unsigned int rdramAddress)
+{
+    _loadMatrix(rdramAddress, m_worldProject);
+}
+        
+
+
+//-----------------------------------------------------------------------------
+// Pop Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::popMatrix()
+{
+    if ( m_modelViewMatrixTop > 0 )
+    {
+        m_modelViewMatrixTop--;             //Pop Matrix from stack
+    }
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+// Pop Matrix N
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::popMatrixN(unsigned int num)
+{
+    if ( m_modelViewMatrixTop > num - 1)
+    {
+        m_modelViewMatrixTop -= num;
+    }
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! DMA Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::DMAMatrix( unsigned int rdramAddress, unsigned char index, unsigned char multiply )
+{
+    //Get final address
+    unsigned int address = m_rdramOffset + rdramAddress;
+
+    if (address + 64 > m_memory->getRDRAMSize())
+    {
+        return;
+    }
+
+    //Load Matrix from Memory
+    Matrix4 temp;
+    _loadMatrix(rdramAddress, temp);
+    
+    //Set Modelview index
+    m_modelViewMatrixTop = index;
+
+    //FIXME: Other way around?
+    if (multiply)
+    {
+        m_modelViewMatrices[m_modelViewMatrixTop] = m_modelViewMatrices[0];  
+        m_modelViewMatrices[m_modelViewMatrixTop] = m_modelViewMatrices[m_modelViewMatrixTop] * temp;
+    }
+    else 
+    {
+        m_modelViewMatrices[m_modelViewMatrixTop] = temp;
+    }
+
+    //Set Projection Matrix to Identity
+    m_projectionMatrices[m_projectionMatrixTop] = Matrix4::IDENTITY;
+
+    //Update Matrices
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! Reset Matrices
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::resetMatrices()
+{
+    m_modelViewMatrices[0] = Matrix4::IDENTITY;
+    m_projectionMatrices[0] = Matrix4::IDENTITY;
+
+    m_modelViewMatrixTop = 0;
+    m_projectionMatrixTop = 0;
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! Load Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::_loadMatrix(unsigned int addr, Matrix4& out)
+{
+    if ( addr + 64 > m_memory->getRDRAMSize() ) {
+        return;
+    }
+
+    unsigned char* RDRAM = m_memory->getRDRAM();
+
+
+    for (int i = 0; i < 4; i++)
+    {
+        for (int j = 0; j < 4; j++) 
+        {
+            int             hi = *(short *)(RDRAM + ((addr+(i<<3)+(j<<1)     )^0x2));
+            unsigned short  lo = *(unsigned short  *)(RDRAM + ((addr+(i<<3)+(j<<1) + 32)^0x2));
+            out[i][j] = (float)((hi<<16) | (lo))/ 65536.0f;
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Set Projection Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::_setProjection(const Matrix4& mat, bool push, bool replace) 
+{
+    Matrix4& oldMatrix = m_projectionMatrices[m_projectionMatrixTop];
+
+    if (push)
+    {
+        m_projectionMatrixTop++;
+    }
+
+    if ( replace )
+    {
+        m_projectionMatrices[m_projectionMatrixTop] = mat;
+    }
+    else
+    {
+        m_projectionMatrices[m_projectionMatrixTop] = mat * oldMatrix;        
+    }
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! Set World View Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::_setWorldView(const Matrix4 & mat, bool push, bool replace)
+{
+    Matrix4& oldMatrix = m_modelViewMatrices[m_modelViewMatrixTop];
+
+    if (push)
+    {
+        m_modelViewMatrixTop++;
+    }
+
+    if ( replace )
+    {
+        m_modelViewMatrices[m_modelViewMatrixTop] = mat;
+    }
+    else
+    {
+        m_modelViewMatrices[m_modelViewMatrixTop] = mat * oldMatrix;        
+    }    
+
+    _updateCombinedMatrix();
+}
+
+//-----------------------------------------------------------------------------
+//! Update Combined Matrix
+//-----------------------------------------------------------------------------
+void RSPMatrixManager::_updateCombinedMatrix()
+{
+    m_worldProject = m_modelViewMatrices[m_modelViewMatrixTop] * m_projectionMatrices[m_projectionMatrixTop];
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h
new file mode 100755 (executable)
index 0000000..bdfe776
--- /dev/null
@@ -0,0 +1,92 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef RSP_MATRIX_MANAGER_H_
+#define RSP_MATRIX_MANAGER_H_
+
+#include "Matrix4.h"
+
+//Forward Declarations
+class Memory;
+
+//*****************************************************************************
+//! RSP Matrix Manager
+//*****************************************************************************
+class RSPMatrixManager
+{
+public:
+
+    //Constructor / Destructor
+    RSPMatrixManager();
+    ~RSPMatrixManager();
+
+    bool initialize(Memory* memory);
+
+    //Add Matrices
+    void addMatrix(unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace);
+    void insertMatrix(unsigned int where, unsigned int num);
+
+    //Remove Matrices
+    void popMatrix();
+    void popMatrixN(unsigned int num);
+    void ForceMatrix( unsigned int segmentAddress );
+    void selectViewMatrix(unsigned int index) { m_modelViewMatrixTop = index; _updateCombinedMatrix(); }    
+    void DMAMatrix(unsigned int segmentAddress, unsigned char index, unsigned char multiply );
+    //void RSP_ForceMatrix( unsigned int mptr );
+    //void RSP_LookAt( unsigned int l );
+    //void RSP_PerspNormalize( unsigned short scale );    
+
+    void setRDRAMOffset(unsigned int offset) { m_rdramOffset = offset; }
+
+    void resetMatrices();
+
+public:
+
+    float* getModelViewMatrix()      { return m_modelViewMatrices[m_modelViewMatrixTop]._m;   }
+    float* getProjectionMatrix()     { return m_projectionMatrices[m_projectionMatrixTop]._m; }
+    float* getViewProjectionMatrix() { return m_worldProject._m;                              }
+
+private:
+
+    void _loadMatrix(unsigned int addr, Matrix4& out);
+    void _setProjection(const Matrix4& mat, bool push, bool replace);
+    void _setWorldView(const Matrix4 & mat, bool push, bool replace);
+    void _updateCombinedMatrix();
+
+private:
+
+    Memory* m_memory;    //!< Pointer to memory
+
+    static const int NUM_STACK_MATRICES = 60;
+
+    unsigned int m_rdramOffset;
+
+    //Stack indices
+    unsigned int m_modelViewMatrixTop;
+    unsigned int m_projectionMatrixTop;
+
+    //Matrices
+    Matrix4 m_modelViewMatrices[NUM_STACK_MATRICES];   //!< Stack with projection matrices
+    Matrix4 m_projectionMatrices[NUM_STACK_MATRICES];  //!< Stack with projection matrices
+    Matrix4 m_worldProject;                            //!< Combined modelviewprojection matrix
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp
new file mode 100755 (executable)
index 0000000..d87b11e
--- /dev/null
@@ -0,0 +1,578 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RSPVertexManager.h"
+#include "OpenGLManager.h"
+#include "Memory.h"
+#include "RSPMatrixManager.h"
+#include "RSPLightManager.h"
+#include "OpenGLRenderer.h"
+#include "GBIDefs.h"   //hmm
+#include "MathLib.h"   //Transform, Vec3Normalize
+#include <cmath> //sqrt
+#include "Logger.h"
+
+//Vertex
+struct Vertex
+{
+    //Position (x,y,z)
+    short y;
+    short x;
+    unsigned short flag;  //Special Flags
+    short z;
+
+    //TexCoords
+    short t;
+    short s;
+
+    //Color or Normal
+    union 
+    {
+        struct { unsigned char a; unsigned char b; unsigned char g; unsigned char r; } color;
+        struct { signed char a;   signed char z;   signed char y;   signed char x; } normal;
+    };
+};
+
+//Perfect Dark Vertex
+struct PerfectDarkVertex
+{
+    short y;
+    short x;
+    unsigned short ci;  //Color Index
+    short z;
+    short t;
+    short s;
+};
+
+struct DKRTriangle 
+{
+    unsigned char v2, v1, v0, flag;
+    short        t0, s0;
+    short        t1, s1;
+    short        t2, s2;
+};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+RSPVertexManager::RSPVertexManager() 
+{
+    m_openGLMgr = 0;
+    m_memory    = 0;
+    m_matrixMgr = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+RSPVertexManager::~RSPVertexManager()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool RSPVertexManager::initialize(OpenGLManager* openGLMgr, Memory* memory, RSPMatrixManager* matrixMgr, RSPLightManager* lightMgr)
+{
+    m_openGLMgr = openGLMgr;
+    m_memory    = memory;
+    m_matrixMgr = matrixMgr;    
+    m_lightMgr  = lightMgr;
+    m_texCoordGenType = TCGT_NONE;
+    m_rdramOffset = 0;
+    m_billboard = false;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Set Vertices
+//-----------------------------------------------------------------------------
+void RSPVertexManager::setVertices( unsigned int address, unsigned int numVertices, unsigned int firstVertexIndex)
+{
+    //Make sure address is valid
+    if ((address + sizeof( Vertex ) * numVertices) > m_memory->getRDRAMSize()) {
+        return;
+    }
+
+    //Get vertex from rdram
+    Vertex *vertex = (Vertex*) m_memory->getRDRAM(address);
+
+    //Avoid overflow. There can only be MAX_VERTICES in size.
+    if ( numVertices+firstVertexIndex >= MAX_VERTICES)
+    {
+        return;
+    }
+
+    //For each vertex
+    for (unsigned int i=firstVertexIndex; i <numVertices+firstVertexIndex; ++i)
+    {
+        m_vertices[i].x = vertex->x;
+        m_vertices[i].y = vertex->y;
+        m_vertices[i].z = vertex->z;
+        m_vertices[i].flag = vertex->flag;
+        m_vertices[i].s = _FIXED2FLOAT( vertex->s, 5 );
+        m_vertices[i].t = _FIXED2FLOAT( vertex->t, 5 );
+
+        if ( m_lightMgr->getLightEnabled() )
+        {
+            m_vertices[i].nx = vertex->normal.x;
+            m_vertices[i].ny = vertex->normal.y;
+            m_vertices[i].nz = vertex->normal.z;
+            m_vertices[i].a = vertex->color.a * 0.0039215689f;
+        }
+        else
+        {
+            m_vertices[i].r = vertex->color.r * 0.0039215689f;
+            m_vertices[i].g = vertex->color.g * 0.0039215689f;
+            m_vertices[i].b = vertex->color.b * 0.0039215689f;
+            m_vertices[i].a = vertex->color.a * 0.0039215689f;
+        }
+
+        _processVertex(i);
+        vertex++;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Modify Vertex
+//-----------------------------------------------------------------------------
+void RSPVertexManager::modifyVertex( unsigned int vtx, unsigned int where, unsigned int val )
+{
+    switch (where)
+    {
+        case G_MWO_POINT_RGBA:
+            m_vertices[vtx].r = _SHIFTR( val, 24, 8 ) * 0.0039215689f;
+            m_vertices[vtx].g = _SHIFTR( val, 16, 8 ) * 0.0039215689f;
+            m_vertices[vtx].b = _SHIFTR( val, 8, 8 ) * 0.0039215689f;
+            m_vertices[vtx].a = _SHIFTR( val, 0, 8 ) * 0.0039215689f;
+            break;
+        case G_MWO_POINT_ST:
+            m_vertices[vtx].s = _FIXED2FLOAT( (short)_SHIFTR( val, 16, 16 ), 5 );
+            m_vertices[vtx].t = _FIXED2FLOAT( (short)_SHIFTR( val, 0, 16 ), 5 );
+            break;
+        case G_MWO_POINT_XYSCREEN:
+            break;
+        case G_MWO_POINT_ZSCREEN:
+            break;
+    }
+}
+
+void RSPVertexManager::setVertexColor(unsigned int vertexIndex, float r, float g, float b, float a)
+{
+    m_vertices[vertexIndex].r = r;
+    m_vertices[vertexIndex].g = g;
+    m_vertices[vertexIndex].b = b;
+    m_vertices[vertexIndex].a = a;
+}
+
+void RSPVertexManager::setVertexTextureCoord(unsigned int vertexIndex, float s, float t)
+{
+    m_vertices[vertexIndex].s = s;
+    m_vertices[vertexIndex].t = t;
+}
+
+
+//-----------------------------------------------------------------------------
+// ?
+//-----------------------------------------------------------------------------
+void RSPVertexManager::ciVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex)
+{
+    unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress);
+
+    if ((rdramAddress + sizeof(PerfectDarkVertex) * numVertices) > m_memory->getRDRAMSize())
+    {
+        return;
+    }
+
+    PerfectDarkVertex* vertex = (PerfectDarkVertex*)m_memory->getRDRAM(rdramAddress);
+
+    //Avoid overflow. There can only be MAX_VERTICES in size.
+    if ( numVertices+firstVertexIndex >= MAX_VERTICES)
+    {
+        return;    
+    }
+
+    //For each vertex
+    for (unsigned int i=firstVertexIndex; i <numVertices+firstVertexIndex; ++i)
+    {
+        m_vertices[i].x    = vertex->x;
+        m_vertices[i].y    = vertex->y;
+        m_vertices[i].z    = vertex->z;
+        m_vertices[i].flag = 0;
+        m_vertices[i].s    = _FIXED2FLOAT( vertex->s, 5 );
+        m_vertices[i].t    = _FIXED2FLOAT( vertex->t, 5 );
+
+        //Get color
+        unsigned char* color = m_memory->getRDRAM(m_colorBaseRDRAMAddress + (vertex->ci & 0xff));
+
+        //Assign color
+        if ( m_lightMgr->getLightEnabled() )
+        {
+            m_vertices[i].nx = (short)color[3];
+            m_vertices[i].ny = (short)color[2];
+            m_vertices[i].nz = (short)color[1];
+            m_vertices[i].a = color[0] * 0.0039215689f;
+        }
+        else
+        {
+            m_vertices[i].r = color[3] * 0.0039215689f;
+            m_vertices[i].g = color[2] * 0.0039215689f;
+            m_vertices[i].b = color[1] * 0.0039215689f;
+            m_vertices[i].a = color[0] * 0.0039215689f;
+        }
+
+        _processVertex( i );
+        vertex++;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// ?
+//-----------------------------------------------------------------------------
+void RSPVertexManager::DMAVertex( unsigned int v, unsigned int numVertices, unsigned int firstVertexIndex)
+{
+    unsigned int address = m_rdramOffset + m_memory->getRDRAMAddress( v );
+
+    if ((address + 10 * numVertices) > m_memory->getRDRAMSize())
+    {
+        return;
+    }
+
+    unsigned char* RDRAM = m_memory->getRDRAM();
+
+    if ((numVertices + firstVertexIndex) < (80))
+    {
+        for (unsigned int i = firstVertexIndex; i < numVertices + firstVertexIndex; i++)
+        {
+            m_vertices[i].x = *(short*)&RDRAM[address ^ 2];
+            m_vertices[i].y = *(short*)&RDRAM[(address + 2) ^ 2];
+            m_vertices[i].z = *(short*)&RDRAM[(address + 4) ^ 2];
+
+            if ( m_lightMgr->getLightEnabled() )
+            {
+                m_vertices[i].nx = *(char*)&RDRAM[(address + 6) ^ 3];
+                m_vertices[i].ny = *(char*)&RDRAM[(address + 7) ^ 3];
+                m_vertices[i].nz = *(char*)&RDRAM[(address + 8) ^ 3];
+                m_vertices[i].a = *(unsigned char*)&RDRAM[(address + 9) ^ 3] * 0.0039215689f;
+            }
+            else
+            {
+                m_vertices[i].r = *(unsigned char*)&RDRAM[(address + 6) ^ 3] * 0.0039215689f;
+                m_vertices[i].g = *(unsigned char*)&RDRAM[(address + 7) ^ 3] * 0.0039215689f;
+                m_vertices[i].b = *(unsigned char*)&RDRAM[(address + 8) ^ 3] * 0.0039215689f;
+                m_vertices[i].a = *(unsigned char*)&RDRAM[(address + 9) ^ 3] * 0.0039215689f;
+            }
+
+            _processVertex( i );
+
+            address += 10;
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------
+// ?
+//-----------------------------------------------------------------------------
+void RSPVertexManager::DMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset )
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("VertexManager - DMAOffsets - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! @param v0 Index of first vertex in triangle
+//! @param v1 Index of second vertex in triangle
+//! @param v2 Index of third vertex in triangle
+//-----------------------------------------------------------------------------
+bool RSPVertexManager::add1Triangle(unsigned int v0, unsigned int v1, unsigned int v2 )
+{
+    bool triangleAdded = false;
+
+    if (true)//IsTriangleVisible(dwV0, dwV1, dwV2))
+    {
+        if ( !((v0 < MAX_VERTICES) && (v1 < MAX_VERTICES) && (v2 < MAX_VERTICES)) )
+        {
+            return false;
+        }
+
+        // Don't bother with triangles completely outside clipping frustrum
+        if (((m_vertices[v0].xClip <  0.0f) && (m_vertices[v1].xClip <  0.0f) && (m_vertices[v2].xClip <  0.0f)) ||
+            ((m_vertices[v0].xClip >  0.0f) && (m_vertices[v1].xClip >  0.0f) && (m_vertices[v2].xClip >  0.0f)) ||
+            ((m_vertices[v0].yClip <  0.0f) && (m_vertices[v1].yClip <  0.0f) && (m_vertices[v2].yClip <  0.0f)) ||
+            ((m_vertices[v0].yClip >  0.0f) && (m_vertices[v1].yClip >  0.0f) && (m_vertices[v2].yClip >  0.0f)) ||
+            ((m_vertices[v0].zClip >  0.1f) && (m_vertices[v1].zClip >  0.1f) && (m_vertices[v2].zClip >  0.1f)) ||
+            ((m_vertices[v0].zClip < -0.1f) && (m_vertices[v1].zClip < -0.1f) && (m_vertices[v2].zClip < -0.1f))    )
+        {
+            return false;
+        }
+        triangleAdded = true;
+
+        //Add vertex to vertex buffer
+        OpenGLRenderer::getSingleton().addTriangle( m_vertices, v0, v1, v2 );
+    }
+
+    return triangleAdded;
+}
+
+void RSPVertexManager::add2Triangles( int v00, int v01, int v02, int flag0,
+                                      int v10, int v11, int v12, int flag1 )
+{
+    //implemented by calling add1Triangle multiple times
+
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("VertexManager - add2Triangles - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+void RSPVertexManager::add4Triangles( int v00, int v01, int v02,
+                    int v10, int v11, int v12,
+                    int v20, int v21, int v22,
+                    int v30, int v31, int v32 )
+{
+    //implemented by calling add1Triangle multiple times
+
+
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("VertexManager - add4Triangles - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//! @todo Set culling
+void RSPVertexManager::addDMATriangles( unsigned int tris, unsigned int n )
+{
+    unsigned int address = m_memory->getRDRAMAddress(tris);
+
+    if (address + sizeof( DKRTriangle ) * n > m_memory->getRDRAMSize() )
+    {
+        return;
+    }
+
+    DKRTriangle *triangles = (DKRTriangle*)m_memory->getRDRAM(address);
+
+    for (unsigned int i = 0; i < n; i++)
+    {
+        //TODO Set culling
+        //gSP.geometryMode &= ~G_CULL_BOTH;
+        //if (!(triangles->flag & 0x40))
+        //{
+        //    if (gSP.viewport.vscale[0] > 0)
+        //        gSP.geometryMode |= G_CULL_BACK;
+        //    else
+        //        gSP.geometryMode |= G_CULL_FRONT;
+        //}
+        //gSP.changed |= CHANGED_GEOMETRYMODE;
+        glDisable(GL_CULL_FACE);
+        
+        m_vertices[triangles->v0].s = _FIXED2FLOAT( triangles->s0, 5 );
+        m_vertices[triangles->v0].t = _FIXED2FLOAT( triangles->t0, 5 );
+        m_vertices[triangles->v1].s = _FIXED2FLOAT( triangles->s1, 5 );
+        m_vertices[triangles->v1].t = _FIXED2FLOAT( triangles->t1, 5 );
+        m_vertices[triangles->v2].s = _FIXED2FLOAT( triangles->s2, 5 );
+        m_vertices[triangles->v2].t = _FIXED2FLOAT( triangles->t2, 5 );
+
+        add1Triangle( triangles->v0, triangles->v1, triangles->v2 /*, 0 */ );
+
+        triangles++;
+    }
+}
+
+
+void RSPVertexManager::setConkerAddress(unsigned int segmentAddress)
+{
+    m_conkerRDRAMAddress = m_memory->getRDRAMAddress(segmentAddress);
+}
+    
+
+void RSPVertexManager::add1Quadrangle( int v0, int v1, int v2, int v4 )
+{
+    //implemented by calling add1Triangle multiple times
+
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("VertexManager - add1Quadrangle - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+
+inline float DotProduct( float* v0, float* v1 )
+{
+    float    dot;
+    dot = v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
+    return dot;
+}
+
+
+void RSPVertexManager::_processVertex( unsigned int v )
+{
+//    float intensity;
+//    float r, g, b;
+
+    transformVertex( m_matrixMgr->getViewProjectionMatrix(), &m_vertices[v].x, &m_vertices[v].x);
+    //TransformVertex( &m_vertices[v].x, m_worldProject );
+
+
+    if ( m_billboard )
+    {
+        m_vertices[v].x += m_vertices[0].x;
+        m_vertices[v].y += m_vertices[0].y;
+        m_vertices[v].z += m_vertices[0].z;
+        m_vertices[v].w += m_vertices[0].w;
+    }
+
+
+    if ( !OpenGLManager::getSingleton().getZBufferEnabled() )
+    {
+        m_vertices[v].z = -m_vertices[v].w;
+    }
+
+    //Temporary variables
+    float intensity;
+    float r, g, b;
+
+    if ( m_lightMgr->getLightEnabled() )
+    {
+        //Transform normal
+        transformVector( m_matrixMgr->getModelViewMatrix(), &m_vertices[v].nx, &m_vertices[v].nx );
+        Vec3Normalize( &m_vertices[v].nx );
+
+        //Get Ambient Color
+        const float* ambientColor = m_lightMgr->getAmbientLight();
+        r = ambientColor[0];
+        g = ambientColor[1];
+        b = ambientColor[2];
+
+        for (int i=0; i<m_lightMgr->getNumLights(); ++i)
+        {
+            intensity = DotProduct( (float*)&m_vertices[v].nx, (float*)m_lightMgr->getLightDirection(i) );
+
+            if (intensity < 0.0f) intensity = 0.0f;
+
+            const float* lightColor = m_lightMgr->getLightColor(i);
+            r += lightColor[0] * intensity;
+            g += lightColor[1] * intensity;
+            b += lightColor[2] * intensity;
+        }
+
+        //Set Color
+        m_vertices[v].r = r;
+        m_vertices[v].g = g;
+        m_vertices[v].b = b;    
+    }
+
+    //Texture Generation
+    if ( m_texCoordGenType != TCGT_NONE )
+    {
+        transformVector( m_matrixMgr->getProjectionMatrix(), &m_vertices[v].nx, &m_vertices[v].nx );
+
+        Vec3Normalize( &m_vertices[v].nx );
+
+        if ( m_texCoordGenType == TCGT_LINEAR )
+        {   
+            m_vertices[v].s = acosf(m_vertices[v].nx) * 325.94931f;
+            m_vertices[v].t = acosf(m_vertices[v].ny) * 325.94931f;
+        }
+        else // TGT_GEN
+        {
+            m_vertices[v].s = (m_vertices[v].nx + 1.0f) * 512.0f;
+            m_vertices[v].t = (m_vertices[v].ny + 1.0f) * 512.0f;
+        }
+    }
+
+    //Clipping
+    if (m_vertices[v].x < -m_vertices[v].w)  
+        m_vertices[v].xClip = -1.0f;
+    else if (m_vertices[v].x > m_vertices[v].w)
+        m_vertices[v].xClip = 1.0f;
+    else
+        m_vertices[v].xClip = 0.0f;
+
+    if (m_vertices[v].y < -m_vertices[v].w)
+        m_vertices[v].yClip = -1.0f;
+    else if (m_vertices[v].y > m_vertices[v].w)
+        m_vertices[v].yClip = 1.0f;
+    else
+        m_vertices[v].yClip = 0.0f;
+
+    if (m_vertices[v].w <= 0.0f)
+        m_vertices[v].zClip = -1.0f;
+    else if (m_vertices[v].z < -m_vertices[v].w)
+        m_vertices[v].zClip = -0.1f;
+    else if (m_vertices[v].z > m_vertices[v].w)
+        m_vertices[v].zClip = 1.0f;
+    else
+        m_vertices[v].zClip = 0.0f;
+
+}
+
+
+void RSPVertexManager::addConkerVertices(unsigned int segmentAddress, unsigned int n, unsigned int v0 )
+{
+    unsigned int numVertices = n;
+    unsigned int firstVertexIndex = v0;
+    unsigned int address = m_memory->getRDRAMAddress( segmentAddress );
+
+    //Make sure address is valid
+    if ((address + sizeof( Vertex ) * numVertices) > m_memory->getRDRAMSize()) {
+        return;
+    }
+
+    //Get vertex from rdram
+    Vertex *vertex = (Vertex*) m_memory->getRDRAM(address);
+
+
+    //For each vertex
+    for (unsigned int i=firstVertexIndex; i <numVertices+firstVertexIndex; ++i)
+    {
+        m_vertices[i].x = vertex->x;
+        m_vertices[i].y = vertex->y;
+        m_vertices[i].z = vertex->z;
+        m_vertices[i].flag = vertex->flag;
+        m_vertices[i].s = _FIXED2FLOAT( vertex->s, 5 );
+        m_vertices[i].t = _FIXED2FLOAT( vertex->t, 5 );
+
+        if ( m_lightMgr->getLightEnabled() )
+        {
+            m_vertices[i].nx = vertex->normal.x;
+            m_vertices[i].ny = vertex->normal.y;
+            m_vertices[i].nz = vertex->normal.z;
+            m_vertices[i].a = vertex->color.a * 0.0039215689f;
+        }
+        else
+        {
+            m_vertices[i].r = vertex->color.r * 0.0039215689f;
+            m_vertices[i].g = vertex->color.g * 0.0039215689f;
+            m_vertices[i].b = vertex->color.b * 0.0039215689f;
+            m_vertices[i].a = vertex->color.a * 0.0039215689f;
+        }
+
+        _processVertex(i);
+        vertex++;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h
new file mode 100755 (executable)
index 0000000..6939878
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef RSP_VERTEX_MANAGER_H_
+#define RSP_VERTEX_MANAGER_H_
+
+//Forward declarations
+class Memory;
+class RSPMatrixManager;
+class RSPLightManager;
+class OpenGLManager;
+
+enum TexCoordGenType
+{
+    TCGT_NONE = 0,
+    TCGT_LINEAR = 1,
+    TCGT_GEN = 2,
+};
+
+//-----------------------------------------------------------------------------
+//! Signal Processor Vertex
+//-----------------------------------------------------------------------------
+struct SPVertex
+{
+    float        x, y, z, w;
+    float        nx, ny, nz;
+    float        r, g, b, a;
+    float        s, t;
+    float        xClip, yClip, zClip;
+    float        flag;
+};
+
+//*****************************************************************************
+//! RSP Vertex Manager
+//*****************************************************************************
+class RSPVertexManager
+{
+public:
+
+    //Constructor / Destructor
+    RSPVertexManager();
+    ~RSPVertexManager();
+
+    bool initialize(OpenGLManager* openGLMgr, Memory* memory, RSPMatrixManager* matrixMgr, RSPLightManager* lightMgr);
+
+    //Vertices
+    void setVertices( unsigned int address, unsigned int numVertices, unsigned int firstVertexIndex);
+    void modifyVertex( unsigned int vtx, unsigned int where, unsigned int val );    
+    void setVertexColor(unsigned int vertexIndex, float r, float g, float b, float a);
+    void setVertexTextureCoord(unsigned int vertexIndex, float s, float t);
+
+    void ciVertex(unsigned int segmentAddress, unsigned int n, unsigned int v0 );
+
+    void addConkerVertices(unsigned int segmentAddress, unsigned int n, unsigned int v0 );
+
+    void DMAVertex( unsigned int v, unsigned int n, unsigned int v0 );
+    void DMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset );
+    void setVertexColorBase( unsigned int rdramAddress ) { m_colorBaseRDRAMAddress = rdramAddress; }
+
+    bool add1Triangle( unsigned int v0, unsigned int v1, unsigned int v2);
+    void add2Triangles( int v00, int v01, int v02, int flag0, 
+                        int v10, int v11, int v12, int flag1 );
+    void add4Triangles( int v00, int v01, int v02,
+                        int v10, int v11, int v12,
+                        int v20, int v21, int v22,
+                        int v30, int v31, int v32 );
+    void addDMATriangles( unsigned int tris, unsigned int n );
+    void add1Quadrangle( int v0, int v1, int v2, int v4 );
+    void setTexCoordGenType(TexCoordGenType texCoordGenType) { m_texCoordGenType       = texCoordGenType; }
+    
+    void setRDRAMOffset(unsigned int offset) { m_rdramOffset = offset; }
+    void setBillboard(unsigned int billboard) { m_billboard = billboard; }
+    unsigned int getBillboard() { return m_billboard; }
+
+    void setConkerAddress(unsigned int segmentAddress);   
+
+public:
+
+    SPVertex* getVertex(unsigned int index) { return &m_vertices[index]; }
+
+private:
+
+    void _processVertex( unsigned int v );
+
+private:
+
+    OpenGLManager* m_openGLMgr;
+    Memory* m_memory;
+    RSPMatrixManager* m_matrixMgr;
+    RSPLightManager* m_lightMgr;
+    
+    //Vertex Buffer
+    static const unsigned int MAX_VERTICES = 300;
+    SPVertex m_vertices[MAX_VERTICES];
+
+    unsigned int m_colorBaseRDRAMAddress;  //!< Address in RDRAM where colors for vertices are located (used by Perfect Dark)
+
+    unsigned int m_rdramOffset;
+
+    unsigned int m_billboard;
+    TexCoordGenType m_texCoordGenType;  //!< Texture Coordinate Generation Technique
+
+    unsigned int m_conkerRDRAMAddress;
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/RomDetector.cpp b/source/mupen64plus-video-arachnoid/src/RomDetector.cpp
new file mode 100755 (executable)
index 0000000..b1336f4
--- /dev/null
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "RomDetector.h"
+#include "assembler.h"   //swapRomHeaderBytes
+#include <string.h>      //memcpy
+#include "StringFunctions.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+ROMDetector::ROMDetector()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+ROMDetector::~ROMDetector()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialzie
+//! Saves rom header, detects which rom it is, and sets states after
+//! which rom it is.
+//! @param romHeader Header with information about rom.
+//-----------------------------------------------------------------------------
+void ROMDetector::initialize(unsigned char* romHeader)
+{
+
+    //Copy Header
+    memcpy(&m_romHeader, romHeader, sizeof(ROMHeader));
+
+    //Header are stored really strange, swap bytes around to make sense of it
+    swapRomHeaderBytes((void*)&m_romHeader, sizeof(ROMHeader));
+
+    //Trim rom name (remove unnecessary whitespaces)
+    StringFunctions::trim(m_romHeader.romName);
+
+    //What game is it?
+    m_currentRomID = this->_getRomID(m_romHeader.romName);
+}
+
+//-----------------------------------------------------------------------------
+//* Get ROM ID
+//! Detects and returns which rom it is, and sets states after
+//! which rom it is.
+//! @param romName Name of rom from rom-header.
+//! @return ID of the rom that was identified by rom name.
+//-----------------------------------------------------------------------------
+N64_ROM_ID ROMDetector::_getRomID(char romName[20])
+{  
+    m_combinerType            = CT_ADVANCED;  //Use advanced combiner
+    m_clearType               = CT_NEVER;     //Never Clear Screen
+    m_ignoreFillRects         = false;
+    m_forceDisableFaceCulling = false;
+    m_useMultiTexture         = true;
+    m_useSecondaryColor       = true;
+
+    //Return ROM-ID and set ROM options
+    if ( !strncmp(romName, "Banjo-Kazooie", 13) )
+    {
+        m_combinerType = CT_SIMPLE;
+        return BANJO_KAZOOIE;
+    }
+    else if ( !strncmp(romName, "BANJO TOOIE", 11) )
+    {
+        m_combinerType = CT_SIMPLE;
+        return BANJO_TOOIE;
+    }
+    else if ( !strncmp(romName, "F-ZERO X", 8) )
+    {
+        m_clearType = CT_AFTER_ONE_DISPLAY_LIST;
+        return F_ZERO_X;
+    }
+    else if ( !strncmp(romName, "STARFOX64", 9) )
+    {
+        m_clearType = CT_AFTER_ONE_DISPLAY_LIST;
+        return STAR_FOX_64;
+    }
+    else if ( !strncmp(romName, "SMASH BROTHERS", 14) )
+    {
+        m_clearType = CT_AFTER_ONE_DISPLAY_LIST;
+        return SUPER_SMASH_BROS;
+    }
+    else if ( !strncmp(romName, "SUPER MARIO 64", 14) )
+    {
+        return SUPER_MARIO_64;
+    }
+    else if ( !strncmp(romName, "BOMBERMAN64E", 11) )
+    {
+        m_clearType = CT_AFTER_ONE_DISPLAY_LIST;
+        m_ignoreFillRects         = true;
+        return BOMBERMAN_64;
+    }
+    else if ( !strncmp(romName, "DONKEY KONG 64", 14) )
+    {
+        return DONKEY_KONG_64;
+    }
+    else if ( !strncmp(romName, "WAVE RACE 64", 12) )
+    {        
+        m_clearType = CT_AFTER_ONE_DISPLAY_LIST;
+        m_ignoreFillRects = true;
+        return WAVE_RACE_64;
+    }        
+    else if ( !strncmp(romName, "GOLDENEYE", 9) )
+    {
+        return GOLDEN_EYE;
+    }
+    else if ( !strncmp(romName, "PAPER MARIO", 11) )
+    {
+        m_clearType = CT_NEVER;
+        return PAPER_MARIO;
+    }
+    else
+    {
+        return UNKNOWN_ROM;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/RomDetector.h b/source/mupen64plus-video-arachnoid/src/RomDetector.h
new file mode 100755 (executable)
index 0000000..8c57c89
--- /dev/null
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef ROM_DETECTOR_H_
+#define ROM_DETECTOR_H_
+
+#include "N64Games.h"
+
+//*****************************************************************************
+//* ROM Header
+//! Stored in each rom, gives us information about rom.
+//*****************************************************************************
+//#pragma pack(push, 1)
+struct ROMHeader
+{
+    unsigned char    x1, x2, x3, x4;
+    unsigned int    clockRate;
+    unsigned int    bootAddressOffset;
+    unsigned int    release;
+    unsigned int    CRC1;              //!< Hash value
+    unsigned int    CRC2;              //!< Hash value
+    unsigned long long unknown0; 
+    char             romName[20];       //!< Name of rom, used to identify what rom it is.
+    unsigned int    unknown1;
+    unsigned short   unknown2;
+    unsigned char    unknown3;
+    unsigned char    nManufacturer;
+    unsigned short   cartID;
+    signed char      countryID;
+    unsigned char    unknown4;
+};
+//#pragma pack(pop)
+//*****************************************************************************
+//* COMBINER TYPE
+//! What kind of combiner to use
+//*****************************************************************************
+enum COMBINER_TYPE
+{
+    CT_ADVANCED,
+    CT_SIMPLE,
+    CT_DUMMY,
+};
+
+//*****************************************************************************
+//* CLEAR TYPE 
+//! When to clear screen
+//*****************************************************************************
+enum CLEAR_TYPE
+{
+    CT_NEVER,
+    CT_AFTER_ONE_DISPLAY_LIST,
+    CT_AFTER_TWO_DISPLAY_LIST,
+    CT_AFTER_THREE_DISPLAY_LIST,
+};
+
+//*****************************************************************************
+//* ROM Detector
+//! Class for detecting which rom it is and settings states after that.
+//*****************************************************************************
+class ROMDetector
+{
+public:
+
+    //Destructor
+    ~ROMDetector();
+
+    //Singleton Instance
+    static ROMDetector& getSingleton()
+    {
+        static ROMDetector instance;
+        return instance;
+    }
+
+    //Initialize
+    void initialize(unsigned char* romHeader);
+
+    const char* getRomName() { return m_romHeader.romName; }
+
+public:
+
+    //! Get Rom ID
+    //! @return ID of the current running rom (game).
+    N64_ROM_ID    getRomID()              { return m_currentRomID;            }
+
+    //! Get Combiner Type
+    //! @return ID of the combiner to use.
+    COMBINER_TYPE getCombinerType()       { return m_combinerType;            }
+
+    //! Get Clear Type
+    //! @return when to clear screen.
+    CLEAR_TYPE    getClearType()          { return m_clearType;               }
+
+    //! Get Ignore Fill Rects
+    //! @return True if we should ignore fill rect instructions.
+    bool          getIgnoreFillRects()    { return m_ignoreFillRects;         }
+
+    //! Get Disable Face Culling
+    //! @return True if we never should enable Face Culling.
+    bool          getDisableFaceCulling() { return m_forceDisableFaceCulling; }
+
+    //! Get Use Multi Texturing
+    //! @return True if we should use multiple textures when rendering
+    bool          getUseMultiTexture()    { return m_useMultiTexture;         }
+
+    //! Get Use Secondary Color
+    //! @return True if we should secondary color when rendering
+    bool          getUseSecondaryColor()  { return m_useSecondaryColor;       }
+
+private:
+
+    //Construtor
+    ROMDetector();
+
+    //Get rom ID
+    N64_ROM_ID _getRomID(char romName[20]);  
+
+private:
+
+    ROMHeader     m_romHeader;                //!< Rom header with information about rom
+
+    N64_ROM_ID    m_currentRomID;             //!< What rom is running
+    COMBINER_TYPE m_combinerType;             //!< What combiner to use
+    CLEAR_TYPE    m_clearType;                //!< When  to clear screen
+    bool          m_ignoreFillRects;          //!< Ignore fill rectangles?
+    bool          m_forceDisableFaceCulling;  //!< Disable face culling?
+    bool          m_useMultiTexture;          //!< Use multitextureing?
+    bool          m_useSecondaryColor;        //!< Use secondary color?
+
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp
new file mode 100755 (executable)
index 0000000..9d125da
--- /dev/null
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "SecondaryColorExt.h"
+#include "ExtensionChecker.h"
+
+// EXT_secondary_color functions
+#ifndef HAVE_GLES
+#ifndef GL_GLEXT_VERSION
+PFNGLSECONDARYCOLOR3BEXTPROC glSecondaryColor3bEXT;
+PFNGLSECONDARYCOLOR3BVEXTPROC glSecondaryColor3bvEXT;
+PFNGLSECONDARYCOLOR3DEXTPROC glSecondaryColor3dEXT;
+PFNGLSECONDARYCOLOR3DVEXTPROC glSecondaryColor3dvEXT;
+PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT;
+PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
+PFNGLSECONDARYCOLOR3IEXTPROC glSecondaryColor3iEXT;
+PFNGLSECONDARYCOLOR3IVEXTPROC glSecondaryColor3ivEXT;
+PFNGLSECONDARYCOLOR3SEXTPROC glSecondaryColor3sEXT;
+PFNGLSECONDARYCOLOR3SVEXTPROC glSecondaryColor3svEXT;
+PFNGLSECONDARYCOLOR3UBEXTPROC glSecondaryColor3ubEXT;
+PFNGLSECONDARYCOLOR3UBVEXTPROC glSecondaryColor3ubvEXT;
+PFNGLSECONDARYCOLOR3UIEXTPROC glSecondaryColor3uiEXT;
+PFNGLSECONDARYCOLOR3UIVEXTPROC glSecondaryColor3uivEXT;
+PFNGLSECONDARYCOLOR3USEXTPROC glSecondaryColor3usEXT;
+PFNGLSECONDARYCOLOR3USVEXTPROC glSecondaryColor3usvEXT;
+#endif
+#endif
+PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT;
+
+bool initializeSecondaryColorExtension()
+{
+#ifndef HAVE_GLES
+    if ( isExtensionSupported( "GL_EXT_secondary_color" ))
+    {
+#ifndef GL_GLEXT_VERSION
+        glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)wglGetProcAddress( "glSecondaryColor3bEXT" );
+        glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)wglGetProcAddress( "glSecondaryColor3bvEXT" );
+        glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)wglGetProcAddress( "glSecondaryColor3dEXT" );
+        glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)wglGetProcAddress( "glSecondaryColor3dvEXT" );
+        glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)wglGetProcAddress( "glSecondaryColor3fEXT" );
+        glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)wglGetProcAddress( "glSecondaryColor3fvEXT" );
+        glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)wglGetProcAddress( "glSecondaryColor3iEXT" );
+        glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)wglGetProcAddress( "glSecondaryColor3ivEXT" );
+        glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)wglGetProcAddress( "glSecondaryColor3sEXT" );
+        glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)wglGetProcAddress( "glSecondaryColor3svEXT" );
+        glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)wglGetProcAddress( "glSecondaryColor3ubEXT" );
+        glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)wglGetProcAddress( "glSecondaryColor3ubvEXT" );
+        glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)wglGetProcAddress( "glSecondaryColor3uiEXT" );
+        glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)wglGetProcAddress( "glSecondaryColor3uivEXT" );
+        glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)wglGetProcAddress( "glSecondaryColor3usEXT" );
+        glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)wglGetProcAddress( "glSecondaryColor3usvEXT" );
+        glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)wglGetProcAddress( "glSecondaryColorPointerEXT" );
+#endif
+        return true;
+    }
+#endif
+    return false;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h
new file mode 100755 (executable)
index 0000000..6fd20e1
--- /dev/null
@@ -0,0 +1,85 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef SECONDARY_COLOR_EXTENSION_H_
+#define SECONDARY_COLOR_EXTENSION_H_
+
+#include "m64p.h"
+#include "OpenGL.h"
+
+#ifndef GL_GLEXT_VERSION
+    #ifndef GL_EXT_secondary_color
+    #define GL_EXT_secondary_color 1
+
+        //Definitions
+        #define GL_COLOR_SUM_EXT                     0x8458
+        #define GL_CURRENT_SECONDARY_COLOR_EXT       0x8459
+        #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT    0x845A
+        #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT    0x845B
+        #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT  0x845C
+        #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+        #define GL_SECONDARY_COLOR_ARRAY_EXT         0x845E
+
+        //Functions
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat r, GLfloat g, GLfloat b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble r, GLdouble g, GLdouble b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte r, GLbyte g, GLbyte b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort r, GLshort g, GLshort b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint r, GLint g, GLint b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC)(GLubyte r, GLubyte g, GLubyte b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC)(GLushort r, GLushort g, GLushort b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC)(GLuint r, GLuint g, GLuint b);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC)(const GLubyte *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC)(const GLushort *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC)(const GLuint *v);
+        typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, void *pointer);
+
+    #endif //GL_EXT_secondary_color 
+
+    // EXT_secondary_color functions
+    extern PFNGLSECONDARYCOLOR3BEXTPROC glSecondaryColor3bEXT;
+    extern PFNGLSECONDARYCOLOR3BVEXTPROC glSecondaryColor3bvEXT;
+    extern PFNGLSECONDARYCOLOR3DEXTPROC glSecondaryColor3dEXT;
+    extern PFNGLSECONDARYCOLOR3DVEXTPROC glSecondaryColor3dvEXT;
+    extern PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT;
+    extern PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
+    extern PFNGLSECONDARYCOLOR3IEXTPROC glSecondaryColor3iEXT;
+    extern PFNGLSECONDARYCOLOR3IVEXTPROC glSecondaryColor3ivEXT;
+    extern PFNGLSECONDARYCOLOR3SEXTPROC glSecondaryColor3sEXT;
+    extern PFNGLSECONDARYCOLOR3SVEXTPROC glSecondaryColor3svEXT;
+    extern PFNGLSECONDARYCOLOR3UBEXTPROC glSecondaryColor3ubEXT;
+    extern PFNGLSECONDARYCOLOR3UBVEXTPROC glSecondaryColor3ubvEXT;
+    extern PFNGLSECONDARYCOLOR3UIEXTPROC glSecondaryColor3uiEXT;
+    extern PFNGLSECONDARYCOLOR3UIVEXTPROC glSecondaryColor3uivEXT;
+    extern PFNGLSECONDARYCOLOR3USEXTPROC glSecondaryColor3usEXT;
+    extern PFNGLSECONDARYCOLOR3USVEXTPROC glSecondaryColor3usvEXT;
+    extern PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT;
+#endif
+
+bool initializeSecondaryColorExtension();
+
+#endif //SECONDARY_COLOR_EXTENSION_H_
diff --git a/source/mupen64plus-video-arachnoid/src/UCodeDefs.h b/source/mupen64plus-video-arachnoid/src/UCodeDefs.h
new file mode 100755 (executable)
index 0000000..c1d13d5
--- /dev/null
@@ -0,0 +1,443 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef _UCODE_DEFS_H_
+#define _UCODE_DEFS_H_
+
+//*****************************************************************************
+// Matrices
+//*****************************************************************************
+
+//! Add matrix struct used for example ucode F3D
+struct RSPUCodeAddMatrix0
+{
+    unsigned int length:16;       //!< Length
+    unsigned int projection:1;    //!< Is this a projection or view matrix?
+    unsigned int load:1;          //!< Replace current matrix or multiply with it?
+    unsigned int push:1;          //!< Save current matrix in stack? 
+    unsigned int :5;              //!< Padding
+    unsigned int cmd:8;           //!< Command
+    unsigned int segmentAddress;  //!< Address to register where there is an RDRAM address used to retrieve matrix
+};
+
+//! Add matrix struct used for example ucode F3DEX2
+#pragma pack(push, 1)
+struct RSPUCodeAddMatrixF3DEX2 
+{
+    union 
+    {
+        struct 
+        {
+            unsigned int param:8;         //!< Push?, Load?, Projection?
+            unsigned int len:16;          //!< Length
+        };
+        struct
+        {
+            unsigned int nopush:1;        //!< Save current matrix in stack? 
+            unsigned int load:1;          //!< Replace current matrix or multiply with it?
+            unsigned int projection:1;    //!< Is this a projection or view matrix?
+            unsigned int :5;              //!< Padding
+            unsigned int lenght:16;       //!< Length
+        };
+    };
+    unsigned int cmd:8;           //!< Command
+    unsigned int segmentAddress:32;  //!< Address to register where there is an RDRAM address used to retrieve matrix
+};
+#pragma pack(pop)
+//*****************************************************************************
+// Vertices
+//*****************************************************************************
+
+//! Add vertices struct used for ucode F3D
+struct RSPUCodeAddVertices0 
+{
+    unsigned int length:16;      //!< Length
+    unsigned int firstVertex:4;  //!< Index of first vertex
+    unsigned int numVertices:4;  //!< Number of vertices minus one
+    unsigned int cmd:8;          //!< Command
+    unsigned int segmentAddress; //!< Address to register where there is an RDRAM address used to retrieve vertices
+};
+//! Add vertices struct used for ucode F3DEX
+struct RSPUCodeAddVertices1 
+{
+    unsigned int length:10;      //!< Length
+    unsigned int numVertices:6;  //!< Number of vertices
+    unsigned int :1;             //!< Padding
+    unsigned int firstVertex:7;  //!< Index of first vertex
+    unsigned int cmd:8;          //!< Command
+    unsigned int segmentAddress; //!< Address to register where there is an RDRAM address used to retrieve vertices
+};
+
+//! Add vertices struct used for ucode F3DEX2
+struct RSPUCodeAddVerticesF3DEX2
+{
+    unsigned int pad0:1;             //!< Padding
+    unsigned int vertexEnd:7;        //!< Index of last vertex
+    unsigned int pad1:4;             //!< Padding
+    unsigned int numVertices:8;      //!< Number of vertices
+    unsigned int pad2:4;             //!< Padding
+    unsigned int cmd:8;              //!< Command
+    unsigned int segmentAddress:32;  //!< Address to register where there is an RDRAM address used to retrieve vertices
+};
+
+//! Add vertices struct used for ucode 9 (Perfect Dark)
+struct RSPUCode9AddColorIndexVertices
+{
+    unsigned int pad0:16;             //!< Padding
+    unsigned int firstVertexIndex:4;  //!< Index of first vertex (where to place vertices in vertexbuffer)
+    unsigned int numVertices:4;       //!< Add one
+    unsigned int cmd:8;               //!< Command
+    unsigned int segmentAddress:32;   //!< Address to register where there is an RDRAM address used to retrieve vertices
+};
+
+//! Add vertices struct used for ucode 4 (Wave Rave 64)
+struct RSPUCodeAddVerticesWaveRace64
+{
+    unsigned int pad0:8;                //!< Padding
+    unsigned int pad1:1;                //!< Padding
+    unsigned int numVertices:7;         //!< Number of vertices
+    unsigned int firstVertexIndex:8;    //!< Index of first vertex (where to place vertices in vertexbuffer)(divide by 5)
+    unsigned int cmd:8;                 //!< Command
+    unsigned int segmentAddress:32;     //!< Address to register where there is an RDRAM address used to retrieve vertices
+};
+
+//*****************************************************************************
+// One triangle
+//*****************************************************************************
+
+//! Add triangle struct used for ucode F3D (and F3DEX)
+struct RSPUCodeAddOneTriangleF3D 
+{
+    unsigned int padding:24; //!< padding
+    unsigned int cmd:8;      //!< Command
+    unsigned int index2:8;   //!< Third vertex index  (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race)
+    unsigned int index1:8;   //!< Second vertex index (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race)
+    unsigned int index0:8;   //!< First vertex index  (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race)
+    unsigned int flag:8;     //!< ???
+};
+
+//! Add triangle struct used for example ucode F3DEX
+struct RSPUCodeAddOneTriangleF3DEX 
+{
+    unsigned int padding:24; //!< padding
+    unsigned int cmd:8;      //!< Command
+    unsigned int pad0:1;     //!< Padding
+    unsigned int index2:7;   //!< Third vertex index  
+    unsigned int pad1:1;     //!< Padding
+    unsigned int index1:7;   //!< Second vertex index 
+    unsigned int pad2:1;     //!< Padding
+    unsigned int index0:7;   //!< First vertex index  
+    unsigned int pad3:8;     //!< Padding
+};
+
+//! Add triangle struct used for ucode F3DEX2
+struct RSPUCodeAddOneTriangleF3DEX2 
+{
+    unsigned int index2:8;   //!< Third vertex index  
+    unsigned int index1:8;   //!< Second vertex index 
+    unsigned int index0:8;   //!< First vertex index  
+    unsigned int cmd:8;      //!< Command
+    unsigned int pad:32;     //!< padding
+};
+
+//*****************************************************************************
+// Two triangles
+//*****************************************************************************
+
+//! Add triangle struct used for adding two triangles
+struct RSPUCodeAddTwoTrianglesWaveRace64
+{
+    unsigned int v2:8;     //!< Third vertex index for first triangle   (divide by 5 for wave race)
+    unsigned int v1:8;     //!< Second vertex index for first triangle  (divide by 5 for wave race)
+    unsigned int v0:8;     //!< First vertex index for first triangle    (divide by 5 for wave race) 
+    unsigned int cmd:8;    //!< Command
+    unsigned int v5:8;     //!< Third vertex index for second triangle  (divide by 5 for wave race)
+    unsigned int v4:8;     //!< Second vertex index for second triangle (divide by 5 for wave race)
+    unsigned int v3:8;     //!< First vertex index for second triangle    (divide by 5 for wave race) 
+    unsigned int flag:8;   //!< ???
+};
+
+//! Add triangle struct used for adding two triangles
+struct RSPUCodeAddTwoTrianglesF3DEX 
+{
+    unsigned int pad0:1;   //!< Padding
+    unsigned int v2:7;     //!< Third vertex index for first triangle
+    unsigned int pad1:1;   //!< Padding
+    unsigned int v1:7;     //!< Second vertex index for first triangle
+    unsigned int pad2:1;   //!< Padding
+    unsigned int v0:7;     //!< First vertex index for first triangle    
+    unsigned int cmd:8;    //!< Command
+    unsigned int pad3:1;   //!< Padding
+    unsigned int v5:7;     //!< Third vertex index for second triangle
+    unsigned int pad4:1;   //!< Padding
+    unsigned int v4:7;     //!< Second vertex index for second triangle
+    unsigned int pad8:1;   //!< Padding
+    unsigned int v3:7;     //!< First vertex index for second triangle    
+    unsigned int flag:8;   //!< ???
+};
+
+//*****************************************************************************
+// Four triangles
+//*****************************************************************************
+
+//! Add triangle struct used for adding four triangles, used by ucode F3D
+struct RSPUCodeAddFourTrianglesF3D
+{
+    unsigned int v0:4;
+    unsigned int v3:4;
+    unsigned int v6:4;
+    unsigned int v9:4;
+    unsigned int pad:8;
+    unsigned int cmd:8;
+    unsigned int v1:4;
+    unsigned int v2:4;
+    unsigned int v4:4;
+    unsigned int v5:4;
+    unsigned int v7:4;
+    unsigned int v8:4;
+    unsigned int v10:4;
+    unsigned int v11:4;
+};
+
+//*****************************************************************************
+// One Quad
+//*****************************************************************************
+
+//! Add quad struct used for adding a rectangel, used by ucode F3D
+struct RSPUCodeAddOneQuadF3D
+{
+    unsigned int pad0:24;  //!< Padding
+    unsigned int cmd:8;    //!< Command 
+    unsigned int index3:8; //!< (divide by 10, 5 for Wave Race)
+    unsigned int index2:8; //!< (divide by 10, 5 for Wave Race)
+    unsigned int index1:8; //!< (divide by 10, 5 for Wave Race)
+    unsigned int index0:8; //!< (divide by 10, 5 for Wave Race)
+};
+
+//! Add quad struct used for adding a rectangel, used by ucode F3DEX
+struct RSPUCodeAddOneQuadF3DEX
+{
+    unsigned int pad0:24;  //!< Padding
+    unsigned int cmd:8;    //!< Command 
+    unsigned int pad1:1;   //!< Padding
+    unsigned int index3:7; //!< Index of fourth vertex
+    unsigned int pad2:1;   //!< Padding
+    unsigned int index2:7; //!< Index of third vertex
+    unsigned int pad3:1;   //!< Padding
+    unsigned int index1:7; //!< Index of second vertex
+    unsigned int pad4:1;   //!< Padding
+    unsigned int index0:7; //!< Index of first vertex
+};
+
+//! Add quad struct used for adding a rectangel, used by ucode F3DEX2
+struct RSPUCodeAddOneQuadF3DEX2  //aka TwoTriangles
+{
+    unsigned int v2:8;
+    unsigned int v1:8;
+    unsigned int v0:8;
+    unsigned int cmd:8;
+    unsigned int v5:8;
+    unsigned int v4:8;
+    unsigned int v3:8;
+    unsigned int pad0:8;
+};
+
+//*****************************************************************************
+// Misc
+//*****************************************************************************
+
+//! Struct used to set DMA Offsets (Mainly used by Diddy Kong Racing UCode6)
+struct RSPUCodeSetDMAOffsets
+{
+    unsigned int addressOffsetMatrix:24;
+    unsigned int cmd:8;
+    unsigned int addressOffsetVertex:24;
+    unsigned int padding:8;
+};
+
+//! Struct used to set Vertex Color Base
+struct RSPUCodeSetVertexColorBase
+{
+    unsigned int padding:24;       //!< Padding 
+    unsigned int cmd:8;            //!< Command
+    unsigned int rdramAddress:32;  //!< Address to RDRAM where vertex colors are located.
+};
+
+//! Struct used to change display list
+struct RSPUCodeDisplayList 
+{
+    unsigned int padding:16;         //!< Padding
+    unsigned int param:8;            //!< Push display list or not?
+    unsigned int cmd:8;              //!< Command
+    unsigned int segmentAddress:32;  //!< 
+};
+
+//! Struct used when modifying vertex data
+struct RSPUCodeModifyVertex
+{
+    unsigned int pad0:1;          //!< Padding
+    unsigned int vertexIndex:15;  //!< Vertex Index (witch vertex to modify
+    unsigned int modifyType:8;    //!< How to modify vertex (set color or texcoords?)
+    unsigned int cmd:8;           //!< Command
+    union
+    {
+        unsigned int value:16;    //!< Input values for vertex
+        struct
+        {
+            unsigned int a:8;         //!< Alpha component of color
+            unsigned int b:8;         //!< Blue component of color
+            unsigned int g:8;         //!< Green component of color
+            unsigned int r:8;         //!< Red component of color
+        };
+        struct
+        {
+            unsigned int t:16;        //!< Second value of texturecoord
+            unsigned int s:16;        //!< First value of texturecoord
+        };
+    };
+};
+
+//*****************************************************************************
+// Move Word
+//*****************************************************************************
+
+//! Struct used to extract information in MoveWord instruction for ucode F3D
+struct RSPUCodeMoveWordF3D
+{
+    unsigned int type:8;          //!< Type of MoveWord
+    unsigned int offset:16;       //!< Offset
+    unsigned int cmd:8;           //!< Command
+
+    union
+    {
+        unsigned int value:32;    //!< Value
+        struct
+        {
+            unsigned int fo:16;       //!< Fog
+            unsigned int fm:16;       //!< Fog
+        };
+    };
+};
+
+//! Struct used to extract information in MoveWord instruction for ucode F3DEX2  
+struct RSPUCodeMoveWordF3DEX2 
+{
+    unsigned int offset:16;     //!< Offset
+    unsigned int type:8;        //!< Type of MoveWord
+    unsigned int cmd:8;         //!< Command
+    union
+    {
+        unsigned int value:32;  //!< Value
+        struct
+        {
+            unsigned int fo:16;     //!< Fog
+            unsigned int fm:16;     //!< Fog
+        };
+    };
+};
+
+//*****************************************************************************
+//* Texture
+//! Struct used when retriving texture information on RSP 
+//*****************************************************************************
+struct RSPUCodeTexture
+{
+    unsigned int    enable_gbi0:1;
+    unsigned int    enable_gbi2:1;
+    unsigned int    :6;
+    unsigned int    tile:3;
+    unsigned int    level:3;
+    unsigned int    :10;
+    unsigned int    cmd:8;
+    unsigned int    scaleT:16;
+    unsigned int    scaleS:16;
+};
+
+//*****************************************************************************
+//* RSPUCodeLoadUCode
+//! Struct used when changing ucode on RSP 
+//*****************************************************************************
+struct RSPUCodeLoadUCode
+{
+    unsigned int ucodeSize:16;     //!< UCode size, note: Add one
+    unsigned int padding:8;        //!< Padding?
+    unsigned int cmd:8;            //!< Command
+    unsigned int ucodeStart:32;    //!< UCode Start
+};
+
+
+//*****************************************************************************
+// Display List
+//*****************************************************************************
+
+//! Struct used to cull displaylist
+struct RSPUCodeCullDisplayList
+{
+    unsigned int pad0:1;             //!< Padding
+    unsigned int vertexIndex:15;     //!< First vertex index to vertices to cull
+    unsigned int pad2:8;             //!< Padding
+    unsigned int cmd:8;              //!< Command
+    unsigned int pad3:1;             //!< Padding
+    unsigned int numVerticies:15;    //!< Number of vertices to cull
+    unsigned int pad4:8;             //!< Padding
+};
+
+//! Used by instruction branch display list by ucode F3DEX
+struct RSPUCodeBranchZF3DEX
+{
+    unsigned int pad0:1;        //!< Padding
+    unsigned int vertex:11;     //!< Vertex to retrive z value from
+    unsigned int pad1:12;       //!< Padding
+    unsigned int cmd:8;         //!< Command
+    unsigned int zvalue:32;     //!< z value used to compare with
+}; 
+
+//*****************************************************************************
+// Others
+//*****************************************************************************
+
+//typedef struct {
+//    union {
+//        unsigned int w0;
+//        struct {
+//            unsigned int arg0:24;
+//            unsigned int cmd:8;
+//        };
+//    };
+//    unsigned int w1;
+//} Gwords;
+
+//! Stuct used to give GBI instructions input data as function argument.
+typedef union {
+    struct {
+        union {
+            unsigned int w0;
+            struct {
+                unsigned int arg0:24;
+                unsigned int cmd:8;
+            };
+        };
+        unsigned int w1;
+    };
+    long long int force_structure_alignment;
+} MicrocodeArgument; 
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/VI.cpp b/source/mupen64plus-video-arachnoid/src/VI.cpp
new file mode 100755 (executable)
index 0000000..08c43a6
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "VI.h"
+#include "GBIDefs.h" //_FIXED2FLOAT, _SHIFTR
+#include "m64p.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+VI::VI()
+{
+    m_width = 320;
+    m_height = 240;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+VI::~VI()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Calculate Size
+//! Calculates width and height of video interface
+//-----------------------------------------------------------------------------
+void VI::calcSize(GFX_INFO*  graphicsInfo)
+{
+    //Get video interface values
+    //unsigned int viScaleX          = *graphicsInfo->VI_X_SCALE_REG;
+    //unsigned int viScaleY          = *graphicsInfo->VI_X_SCALE_REG;
+    unsigned int viStartHorizontal = *graphicsInfo->VI_H_START_REG;
+    unsigned int viStartVertical   = *graphicsInfo->VI_V_START_REG;
+
+    //Get Scale
+    float xScale = _FIXED2FLOAT(_SHIFTR(*graphicsInfo->VI_X_SCALE_REG, 0, 12), 10);
+    float yScale = _FIXED2FLOAT(_SHIFTR(*graphicsInfo->VI_Y_SCALE_REG, 0, 12), 10);
+
+    //Get Offsets (no need for these?)
+    //float xOffset = _FIXED2FLOAT(_SHIFTR(viScaleX, 16, 12), 10);
+    //float yOffset = _FIXED2FLOAT(_SHIFTR(viScaleY, 16, 12), 10);
+
+    //Get horizontal coordinats
+    unsigned int hEnd = _SHIFTR( viStartHorizontal, 0, 10 );
+    unsigned int hStart = _SHIFTR( viStartHorizontal, 16, 10 );
+
+    //Get vertical coordinats
+    // These are in half-lines, so shift an extra bit
+    unsigned int vEnd = _SHIFTR( viStartVertical, 1, 9 );
+    unsigned int vStart = _SHIFTR( viStartVertical, 17, 9 );
+
+    //Calculate size
+    m_width = (int)((hEnd - hStart) * xScale);
+    m_height = (int)((vEnd - vStart) * yScale * 1.0126582f);
+
+    //If Zero: Set to defaults
+    if ( m_width == 0.0f ) m_width = 320;
+    if ( m_height == 0.0f ) m_height = 240;
+
+    //m_width = 320;
+    //m_height = 240;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/VI.h b/source/mupen64plus-video-arachnoid/src/VI.h
new file mode 100755 (executable)
index 0000000..6df4782
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VIDEO_INTERFACE_H_
+#define VIDEO_INTERFACE_H_
+
+//Forward declarations
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "UCodeDefs.h"
+#include "m64p_plugin.h"
+
+//*****************************************************************************
+//! Video Interface
+//*****************************************************************************
+class VI
+{
+public:
+
+    //Constructor
+    VI();
+    ~VI();
+
+    //Calculate height and width
+    void calcSize(GFX_INFO*  graphicsInfo);
+
+    //Get Height and Width
+    unsigned int getWidth() { return m_width; }
+    unsigned int getHeight() { return m_height; }
+
+private:
+
+    unsigned int m_width;   //!< Width of video interface viewport
+    unsigned int m_height;  //!< Height of video interface viewport
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/config/Config.cpp b/source/mupen64plus-video-arachnoid/src/config/Config.cpp
new file mode 100755 (executable)
index 0000000..69f9a0a
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "Config.h"
+#include <cstdio> 
+#include "GraphicsPlugin.h"
+#include "Logger.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+Config::Config(GraphicsPlugin* graphicsPlugin)
+{
+    m_graphicsPlugin   = graphicsPlugin;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+Config::~Config()
+{
+}
+
+bool Config::initialize()
+{
+    if (ConfigOpenSection("Video-General", &m_videoGeneralSection) != M64ERR_SUCCESS ||
+        ConfigOpenSection("Video-Arachnoid", &m_videoArachnoidSection) != M64ERR_SUCCESS)
+    {
+        Logger::getSingleton().printMsg("Could not open configuration", M64MSG_ERROR);
+        return false;
+    }
+    
+    ConfigSetDefaultBool(m_videoGeneralSection, "Fullscreen", false, "Use fullscreen mode if True, or windowed mode if False");
+    ConfigSetDefaultInt(m_videoGeneralSection, "ScreenWidth", 640, "Width of output window or fullscreen width");
+    ConfigSetDefaultInt(m_videoGeneralSection, "ScreenHeight", 480, "Height of output window or fullscreen height");
+    ConfigSetDefaultInt(m_videoArachnoidSection, "ColorDepth", 32, "Color bit-depth in fullscreen mode");
+    ConfigSetDefaultInt(m_videoArachnoidSection, "RefreshRate", 60, "Screen refresh-rate in fullscreen mode");
+    ConfigSetDefaultInt(m_videoArachnoidSection, "TextureCacheSize", 15 * (1024 * 1024), "Size of texture cache used to store textures");
+    ConfigSetDefaultBool(m_videoArachnoidSection, "Wireframe", false, "Render in wireframe?");
+    ConfigSetDefaultBool(m_videoArachnoidSection, "Fog", false, "Render fog?");
+    ConfigSetDefaultInt(m_videoArachnoidSection, "MultiSampling", 0, "Use MultiSampling? 0=no 2,4,8,16=quality");
+    ConfigSetDefaultInt(m_videoArachnoidSection, "Mipmapping", 0, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear");
+#ifdef WIN32
+    ConfigSetDefaultInt(m_videoArachnoidSection, "ScreenUpdateSetting", SCREEN_UPDATE_CI, "When to update the screen: 1 - on VI, 2 - on first CI");
+#else
+    ConfigSetDefaultInt(m_videoArachnoidSection, "ScreenUpdateSetting", SCREEN_UPDATE_VI, "When to update the screen: 1 - on VI, 2 - on first CI");
+#endif
+    ConfigSetDefaultBool(m_videoArachnoidSection, "FrameSkip", false, "Use FrameSkipping?");
+    return true;
+}
+
+void Config::load()
+{
+    m_cfg.fullscreenWidth       = ConfigGetParamInt(m_videoGeneralSection, "ScreenWidth");
+    m_cfg.fullscreenHeight      = ConfigGetParamInt(m_videoGeneralSection, "ScreenHeight");
+    m_cfg.fullscreenBitDepth    = ConfigGetParamInt(m_videoArachnoidSection, "ColorDepth");
+    m_cfg.fullscreenRefreshRate = ConfigGetParamInt(m_videoArachnoidSection, "RefreshRate");
+    m_cfg.windowWidth           = ConfigGetParamInt(m_videoGeneralSection, "ScreenWidth");
+    m_cfg.windowHeight          = ConfigGetParamInt(m_videoGeneralSection, "ScreenHeight");
+    m_cfg.startFullscreen       = ConfigGetParamBool(m_videoGeneralSection, "Fullscreen");
+    m_cfg.textureCacheSize      = ConfigGetParamInt(m_videoArachnoidSection, "TextureCacheSize");
+    m_cfg.wireframe             = ConfigGetParamBool(m_videoArachnoidSection, "Wireframe");
+    m_cfg.fog                   = ConfigGetParamBool(m_videoArachnoidSection, "Fog");
+    m_cfg.multiSampling         = ConfigGetParamBool(m_videoArachnoidSection, "MultiSampling");
+    m_cfg.mipmapping             = ConfigGetParamInt(m_videoArachnoidSection, "Mipmapping");
+    m_cfg.screenUpdateSetting   = ConfigGetParamInt(m_videoArachnoidSection, "ScreenUpdateSetting");
+    m_cfg.frameSkip             = ConfigGetParamBool(m_videoArachnoidSection, "FrameSkip");
+}
diff --git a/source/mupen64plus-video-arachnoid/src/config/Config.h b/source/mupen64plus-video-arachnoid/src/config/Config.h
new file mode 100755 (executable)
index 0000000..0dffe32
--- /dev/null
@@ -0,0 +1,78 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+#include "m64p.h"
+#include "ConfigMap.h"
+
+//Forward declaration
+class GraphicsPlugin;
+
+//*****************************************************************************
+//* Config
+//! Manages configuration of graphics plugin
+//!
+//! Responability:
+//!  * Loads config data from core
+//!  * Sets default config values
+//!
+//! @see ConfigMap
+//*****************************************************************************
+class Config
+{
+public:
+
+    //Constructor / Destructor
+    Config(GraphicsPlugin* graphicsPlugin);
+    ~Config();
+
+    bool initialize();
+
+    //Loads settings from core
+    void load();
+
+    //Tell Graphics plugin that config has changed
+    void updateGraphics();
+
+public:
+
+    //Get configuration
+    ConfigMap* getConfig() { return &m_cfg; }
+
+private:
+
+    ConfigMap m_cfg;                     //!< Config map with all settings
+    GraphicsPlugin* m_graphicsPlugin;    //!< Pointer to graphics plugin
+
+    m64p_handle m_videoGeneralSection;
+    m64p_handle m_videoArachnoidSection;
+};
+
+enum
+{
+    SCREEN_UPDATE_VI = 1,
+    SCREEN_UPDATE_CI = 2
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/config/ConfigMap.h b/source/mupen64plus-video-arachnoid/src/config/ConfigMap.h
new file mode 100755 (executable)
index 0000000..b0d75bf
--- /dev/null
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CONFIG_MAP_H_
+#define CONFIG_MAP_H_
+
+//*****************************************************************************
+//! Struct with all configuration settings are stored
+//*****************************************************************************
+struct ConfigMap
+{
+    //Configuration Settings
+    int  fullscreenWidth;        //!< Display width in fullscreen mode,             default = 800
+    int  fullscreenHeight;       //!< Display height in fullscreen mode,            default = 600
+    int  fullscreenRefreshRate;  //!< Screen refresh-rate in fullscreen mode,       default = 60
+    int  fullscreenBitDepth;     //!< Bitdepth in fullscreen mode,                  default = 32
+    bool startFullscreen;        //!< Whether to start in fullscreen mode,          default = false
+    int  windowWidth;            //!< Width of render window in window mode,        default = 800
+    int  windowHeight;           //!< Height of render window in window mode,       default = 600    
+    int  textureCacheSize;       //!< Size of texture cache used to store textures, default = 15 MB
+    bool wireframe;              //!< Render in wireframe?                          defualt = false
+    bool fog;                    //!< Render fog?                                   default = true
+    int  multiSampling;          //!< Use MultiSampling? 0=no 2,4,8,16=quality      default = 0
+    int  mipmapping;              //!< Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear default = 0
+    int  screenUpdateSetting;    //!< When to redraw the screen                     default = SCREEN_UPDATE_VI
+    bool frameSkip;            //!< Use frameskipping?
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp
new file mode 100755 (executable)
index 0000000..eddb9fa
--- /dev/null
@@ -0,0 +1,155 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "StringFunctions.h"
+#include <cstring>
+using std::string;
+using std::vector;
+
+namespace StringFunctions {
+
+//-----------------------------------------------------------------------------
+// split
+// @param str The string you want to split into many strings
+// @param delims The character(s) that split strings
+// @return Vector with the new strings
+//-----------------------------------------------------------------------------
+vector<string> split(const string& str, const string& delims, size_t maxSplits)
+{
+    size_t pos;
+    size_t start = 0;
+    vector<string> strings;
+    size_t numSplits = 0;
+       
+    do 
+    {
+        //Find next interesting data
+        start = str.find_first_not_of(delims, start);
+
+        //Try to find delimiter
+        pos = str.find_first_of(delims, start);
+
+        if (pos == start)
+        {            
+            //Do nothing
+            start = pos + 1;  
+        }
+        else if (pos == string::npos || (maxSplits!=string::npos && numSplits == maxSplits)  )
+        {
+            //No more spliting, copy the rest of the string
+            strings.push_back( str.substr(start) );
+            break;
+        }
+        else
+        {
+            //Split string and add to return 
+            strings.push_back( str.substr(start, pos - start) );
+            start = pos + 1;
+            numSplits++;
+        }
+
+    } while (pos != string::npos);
+
+    //Return vector with strings
+    return strings;
+}
+
+//-----------------------------------------------------------------------------
+// String Trim
+//-----------------------------------------------------------------------------
+void trim(string& str, bool left, bool right, const string delims)
+{
+    //Erase characters from the left
+    if(left)
+    {
+        str.erase(0, str.find_first_not_of(delims)); 
+    }
+
+    //Erase characters from the right
+    if(right) 
+    {
+        str.erase(str.find_last_not_of(delims)+1); 
+    }    
+}
+
+//-----------------------------------------------------------------------------
+// String Trim
+//-----------------------------------------------------------------------------
+char* trim(char* str, bool left, bool right)
+{
+    //Trim from the left
+    if(left)
+    {
+        //Set pointer to string
+        char* p1 = str;
+        char* p2 = str;
+        char* end = &str[strlen(str)-1];
+
+        //Skip white spaces
+        while ( isspace( *p1 ) && p1 != end )
+        {
+            ++p1;
+        }
+
+        char* newEnd = p1;
+
+        //Copy characters to begining of string
+        while ( p2 != end )
+        {
+            if ( p1 < newEnd )
+            {
+                *p2 = '\0';
+            }
+            else
+            {
+                *p2 = *p1;
+            }
+
+            ++p1;
+            ++p2;
+        }
+    }
+
+    //Trim from the right
+    if(right) 
+    {
+        //Point to end of string
+        char* end = str + strlen(str) - 1;
+
+        //Remove white spaces in the end
+        while( end >= str && *end == ' ' )
+        {
+            *end-- = '\0';
+        }
+    }  
+    return str;
+}
+
+//-----------------------------------------------------------------------------
+// String Trim
+//-----------------------------------------------------------------------------
+std::vector<string> split(const char* str, const std::string& delims)
+{
+    return split(string(str), delims);
+}
+
+
+} //namespace StringFunctions
diff --git a/source/mupen64plus-video-arachnoid/src/config/StringFunctions.h b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.h
new file mode 100755 (executable)
index 0000000..beef848
--- /dev/null
@@ -0,0 +1,85 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+/*
+What is the difference between '\n' and '\r\n'?
+-----------------------------------------------
+
+There are a few characters which can indicate a new line. The usual ones are these two:
+
+    * '\n' or '0x0A' (10 in decimal) -> This character is called "Line Feed" (LF).
+    * '\r' or '0x0D' (13 in decimal) -> This one is called "Carriage return" (CR).
+
+Different Operating Systems handle newlines in a different way. Here is a short list of the most common ones:
+
+    * DOS and Windows
+      They expect a newline to be the combination of two characters, namely '\r\n' (or 13 followed by 10).
+
+    * Unix (and hence Linux as well)
+      Unix uses a single '\n' to indicate a new line.
+
+    * Mac
+      Macs use a single '\r'.
+
+To unify things a bit, so that writing portable C/C++ programs is possible, file streams have both a 
+"translated" and an "untranslated" mode. If you open a file in translated mode, the runtime library 
+will convert a '\n' to the appropriate newline character(s). If the following program is compiled under 
+Unix, the file will contain a single LF to indicate the newline. If it's compiled under windows, it will 
+contain a CRLF.
+
+#include <stdio.h> 
+#include <stdlib.h>   
+int main() { 
+    FILE *fp = fopen("testfile.txt", "w"); 
+    fprintf(fp, "Hello World\n"); 
+    fclose(fp); 
+    return 0; 
+}
+
+Important
+If you want to be able to read text files written on different operating systems, you have to open the file 
+in binary (= untranslated) mode and check for the different newlines yourself.
+
+*/
+
+
+#ifndef STRING_FUNCTIONS_H_
+#define STRING_FUNCTIONS_H_
+
+#include <string>
+#include <vector>
+#include <ctype.h>
+#include <algorithm>  //std::transform
+    
+namespace StringFunctions 
+{
+    //Split
+    std::vector<std::string> split(const std::string& str, const std::string& delims="\n\t ", size_t maxSplits=std::string::npos);
+    std::vector<std::string> split(const char* str, const std::string& delims="\n\t ");
+
+    //Trim
+    void trim(std::string& str, bool left=true, bool right=true, const std::string delims=" \t\r\n");
+
+    //Trim
+    char* trim(char* str, bool left=true, bool right=true); 
+}
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/config/StringValue.h b/source/mupen64plus-video-arachnoid/src/config/StringValue.h
new file mode 100755 (executable)
index 0000000..1462585
--- /dev/null
@@ -0,0 +1,133 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef STRING_VALUE_H_
+#define STRING_VALUE_H_
+#include <cstdlib>
+#include <string>
+#include <sstream>
+
+//! Represents numeric value(s) with a string using conversion operators 
+struct StringValue
+{
+    StringValue() {data = "";}
+    StringValue(const StringValue& v) { data=v.data; }
+    StringValue(const std::string& s) { data=s; }
+    StringValue(const char *s) { data = s; }
+
+    StringValue(bool b) 
+    {
+        std::stringstream s;
+        s << b;
+        data= s.str();
+    }
+
+    StringValue(int i) { 
+        std::stringstream s;
+        s << i;
+        data= s.str();
+    }
+
+    StringValue(float f) {
+        std::stringstream s;
+        s << f;
+        data= s.str();
+    }
+
+    StringValue(double f) {
+        std::stringstream s;
+        s << f;
+        data= s.str();
+    }
+
+    // assignment operators
+    StringValue& operator=(const char* s) { data=s; return *this; }
+    StringValue& operator=(const std::string& s) { data=s; return *this; }
+    StringValue& operator=(const StringValue& v) { data=v.data; return *this; }
+    template<class T> StringValue& operator=(T x)
+    {
+        std::string y;
+        std::stringstream ss;
+        ss << x;
+        ss >> y;
+        data = y;
+        return *this;
+    }
+    // comparison operators
+    bool operator==(const char* s) const { return data==s; }
+    bool operator==(const std::string& s) const { return data==s; }
+    bool operator==(const StringValue& x) const { return data==x.data; }
+    template<class T> bool operator==(T x) const { return (x == T(*this)); }
+    // conversion operators
+    operator bool() const {
+        if (data=="false" || data=="0") return false;
+        return true;
+    }
+    operator float() const {
+        return (float) atof(data.c_str());
+    }
+    operator double() const {
+        return atof(data.c_str());
+    }
+    operator char() const {
+        char x;
+        std::stringstream ss; ss << data; ss >> x;
+        return x;
+    }
+    operator unsigned char() const {
+        unsigned char x;
+        std::stringstream ss; ss << data; ss >> x;
+        return x;
+    }
+    operator int() const {
+        return atoi(data.c_str());
+    }
+    operator short() const {
+        return (short) atoi(data.c_str());
+    }
+    operator long() const {
+        return atol(data.c_str());
+    }
+    operator unsigned short() const {
+        unsigned short x;
+        std::stringstream ss; ss << data; ss >> x;
+        return x;
+    }
+    operator unsigned int() const {
+        unsigned int x;
+        std::stringstream ss; ss << data; ss >> x;
+        return x;
+    }
+    operator unsigned long() const {
+        unsigned int x;
+        std::stringstream ss; ss << data; ss >> x;
+        return x;
+    }
+    operator const char *() const {
+        return data.c_str();
+    }
+
+    std::string str() const { return data; }
+private:
+    std::string data;
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp
new file mode 100755 (executable)
index 0000000..31255da
--- /dev/null
@@ -0,0 +1,371 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "FrameBuffer.h"
+#include "m64p.h"
+#include "OpenGL.h"
+
+#ifndef GL_GLEXT_VERSION
+#ifndef HAVE_GLES
+    //-----------------------------------------------------------------------------
+    //OpenGL Texture Definitions
+    //-----------------------------------------------------------------------------
+    typedef GLvoid (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum texture);
+    PFNGLACTIVETEXTUREPROC      glActiveTexture = NULL;
+#endif
+#endif
+
+#ifndef GL_TEXTURE0
+    #define GL_TEXTURE0     0x84C0
+#endif
+#ifndef GL_CLAMP_TO_EDGE
+    #define GL_CLAMP_TO_EDGE  0x812F
+#endif
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+FrameBuffer::FrameBuffer()
+{
+    m_id = ~0U;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+FrameBuffer::~FrameBuffer()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! @param width Width of framebuffer, usually equal to window-client-width
+//! @param height Height of framebuffer, usually equal to window-client-height
+//-----------------------------------------------------------------------------
+void FrameBuffer::initialize(int width, int height)
+{
+    //Save parameters
+    m_width    = width;
+    m_height   = height;
+    int channels = 3;     //!< RGB=3 or RGBA=4    
+
+    //Allocate memory
+    unsigned char* data = new unsigned char[width * height * channels];
+    memset(data, 0, width * height * channels * sizeof(unsigned char));    
+
+    //Register the texture with OpenGL and bind it to the texture ID
+    glGenTextures(1, &m_id);                                
+    glBindTexture(GL_TEXTURE_2D, m_id);                    
+
+    //Create the texture and store it on the video card
+#ifdef HAVE_GLES
+    if (channels == 3)
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);    
+    else
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);    
+#else
+    glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);    
+#endif
+        
+    //No texure filtering
+    //glPixelStorei(GL_UNPACK_ALIGNMENT, 1 );            
+    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+    //Clamp texture to edges
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    //Delete data (no need for it when it is stored in video card)
+    delete[] data;
+    data = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Dispose
+//-----------------------------------------------------------------------------
+void FrameBuffer::dispose()
+{
+    if ( m_id != ~0U )
+    {
+        glDeleteTextures(1, &m_id);        
+        m_id = -1;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Resize
+//-----------------------------------------------------------------------------
+void FrameBuffer::resize(int width, int height)
+{
+    dispose();
+    initialize(width, height);
+}
+
+//-----------------------------------------------------------------------------
+//* Begin Rendering
+//! 
+//-----------------------------------------------------------------------------
+void FrameBuffer::beginRendering()
+{
+    //Get viewport
+    glGetIntegerv(GL_VIEWPORT, m_oldViewport);
+
+    //Set new viewport for texture
+    //glViewport(0, 20, m_width, m_height);
+
+    //glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    //glClear(GL_COLOR_BUFFER_BIT);
+    //glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+
+    //Clear Buffers
+   // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+//-----------------------------------------------------------------------------
+//* End Rendering
+//! Will save all rendering to a texture
+//-----------------------------------------------------------------------------
+void FrameBuffer::endRendering()
+{
+    //Activate texture
+    _activate();
+
+    //Render to Texture
+    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 20, m_width, m_height );
+
+    //TODO Deactivate texture?
+    //_deactivate();
+
+    //Reset Viewport
+    //glViewport(m_oldViewport[0], m_oldViewport[1], m_oldViewport[2], m_oldViewport[3]);
+
+    //Clear Buffers
+    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+//-----------------------------------------------------------------------------
+//* Render
+//! Will render frame buffer to screen.
+//-----------------------------------------------------------------------------
+void FrameBuffer::render()
+{
+    //Push states
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+     //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
+    //glViewport( 0, 0, m_width, m_height );
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    //glPushAttrib(GL_LIGHTING_BIT);
+    glDisable(GL_LIGHTING);
+
+    //Render QUAD (using framebuffer texture)
+    _activate();
+    {
+#ifdef HAVE_GLES
+               GLfloat tex[] = {
+                       0, 0,
+                       1, 0,
+                       1, 1,
+                       0, 1
+               };
+               GLfloat vtx[] = {
+                       -1, -1, 0,
+                       0, -1, 0,
+                       0, 0, 0,
+                       -1, 0, 0
+               };
+               glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
+               
+               GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
+               if (glcol) glDisableClientState(GL_COLOR_ARRAY);
+               GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);
+               if (!glvtx)
+                       glEnableClientState(GL_VERTEX_ARRAY);
+               glVertexPointer(3,GL_FLOAT, 0,&vtx);
+               glActiveTexture( GL_TEXTURE1 );
+               GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex1) glDisable(GL_TEXTURE_2D);
+               glActiveTexture( GL_TEXTURE0 );
+               glClientActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+               // draw
+               glDrawArrays(GL_TRIANGLE_FAN,0,4);
+               // restaure
+               if (glcol) glEnableClientState(GL_COLOR_ARRAY);
+               glActiveTexture( GL_TEXTURE1 );
+               if (gltex1) glEnable(GL_TEXTURE_2D);
+               if (!glvtx)
+                       glDisableClientState(GL_VERTEX_ARRAY);
+               else
+                       glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
+               glActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
+               
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+#else
+        glBegin(GL_QUADS);
+        {
+            glColor3f(0.0f, 0.0f, 1.0f);
+            glTexCoord2f(0,0);
+            glVertex3f(-1,-1,0);
+            glTexCoord2f(1,0);
+            glVertex3f( 0,-1,0);
+            glTexCoord2f(1,1);
+            glVertex3f( 0, 0,0);
+            glTexCoord2f(0,1);
+            glVertex3f(-1, 0,0);
+            glColor3f(1.0f, 1.0f, 1.0f);
+        }
+        glEnd();
+#endif
+    }
+    _deactivate();
+
+    //Pop states
+    //glPopAttrib();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix(); 
+}
+
+//-----------------------------------------------------------------------------
+//* Render
+//! Will render frame buffer to screen.
+//-----------------------------------------------------------------------------
+void FrameBuffer::render2()
+{
+    //Push states
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+     //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
+    //glViewport( 0, 0, m_width, m_height );
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    //glPushAttrib(GL_LIGHTING_BIT);
+    glDisable(GL_LIGHTING);
+
+    //Render QUAD (using framebuffer texture)
+    _activate();
+    {
+#ifdef HAVE_GLES
+               GLfloat tex[] = {
+                       0, 0,
+                       1, 0,
+                       1, 1,
+                       0, 1
+               };
+               GLfloat vtx[] = {
+                       -1, -1, 0,
+                       0, -1, 0,
+                       0, 0, 0,
+                       -1, 0, 0
+               };
+               
+               GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
+               if (glcol) glDisableClientState(GL_COLOR_ARRAY);
+               GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);         
+               if (!glvtx)
+                       glEnableClientState(GL_VERTEX_ARRAY);
+               glVertexPointer(3,GL_FLOAT, 0,&vtx);
+               glActiveTexture( GL_TEXTURE1 );
+               GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex1) glDisable(GL_TEXTURE_2D);
+               glActiveTexture( GL_TEXTURE0 );
+               glClientActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+               // draw
+               glDrawArrays(GL_TRIANGLE_FAN,0,4);
+               // restaure
+               if (glcol) glEnableClientState(GL_COLOR_ARRAY);
+               glActiveTexture( GL_TEXTURE1 );
+               if (gltex1) glEnable(GL_TEXTURE_2D);
+               if (!glvtx)
+                       glDisableClientState(GL_VERTEX_ARRAY);
+               else 
+                       glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
+               glActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
+               
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+#else
+        glBegin(GL_QUADS);
+        {
+            glTexCoord2f(0,0);
+            glVertex3f(-1,-1,0);
+            glTexCoord2f(1,0);
+            glVertex3f( 1,-1,0);
+            glTexCoord2f(1,1);
+            glVertex3f( 1, 1,0);
+            glTexCoord2f(0,1);
+            glVertex3f(-1, 1,0);
+            glColor3f(1.0f, 1.0f, 1.0f);
+        }
+        glEnd();
+#endif
+    }
+    _deactivate();
+
+    //Pop states
+    //glPopAttrib();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix(); 
+}
+
+//-----------------------------------------------------------------------------
+// Activate
+//-----------------------------------------------------------------------------
+void FrameBuffer::_activate()
+{
+    //Activate Texture (so we can copy to it)
+#ifndef GL_GLEXT_VERSION
+#ifndef HAVE_GLES
+    if ( glActiveTexture == 0 ) {
+        glActiveTexture = (PFNGLACTIVETEXTUREPROC) CoreVideo_GL_GetProcAddress("glActiveTexture");
+    }
+#endif
+#endif
+    glActiveTexture(GL_TEXTURE0);
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, m_id);
+}
+
+//-----------------------------------------------------------------------------
+// Deactivate
+//-----------------------------------------------------------------------------
+void FrameBuffer::_deactivate()
+{
+    glActiveTexture((GLuint)GL_TEXTURE0);
+    glDisable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, 0);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h
new file mode 100755 (executable)
index 0000000..2285ce3
--- /dev/null
@@ -0,0 +1,74 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef FRAME_BUFFER_H_
+#define FRAME_BUFFER_H_
+
+
+//*****************************************************************************
+//* FrameBuffer
+//! A Texture that we can render to.
+//*****************************************************************************
+class FrameBuffer
+{
+public:
+
+    //Get Singleton
+    //static FrameBuffer& getSingleton() {
+    //    static FrameBuffer instance;
+    //    return instance;
+    //}
+
+    //Constructor
+    FrameBuffer();
+
+    //Destructor
+    ~FrameBuffer();
+
+    void initialize(int width, int height);
+    void dispose();
+    void resize(int width, int height);
+    void beginRendering();
+    void endRendering();
+    void render();
+    void render2();
+
+protected:
+
+    void _activate();
+    void _deactivate();
+
+private:
+
+
+
+protected:
+
+    unsigned int m_id;       //!< TextureID, Used mainly for OpenGL (so it can keep track of textures)
+    int m_width;             //!< Width of framebuffer
+    int m_height;            //!< Height of framebuffer 
+
+    int m_oldViewport[4];
+
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp
new file mode 100755 (executable)
index 0000000..57a1806
--- /dev/null
@@ -0,0 +1,161 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "CRCCalculator.h"
+
+#define CRC32_POLYNOMIAL    0xedb88320L    //0x04C11DB7
+typedef unsigned char byte;
+
+//-----------------------------------------------------------------------------
+// Static Variabels
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator::m_crcTable[256] = {0};   
+
+static unsigned int crc_table[256];
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+CRCCalculator::CRCCalculator()
+{
+    static bool hashTableInitialized = false;
+
+    //Build hash table
+    //http://www.gamedev.net/reference/articles/article1941.asp
+    if ( !hashTableInitialized )
+    {
+     //   unsigned int crc;
+
+     //   //For each value 
+     //   for (int i=0; i<256; i++)
+        //{
+     //       crc = _reflect( i, 8 ) << 24;
+
+     //       for (int j = 0; j < 8; j++) 
+     //       {
+              //  crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
+     //       }
+     //       
+     //       m_crcTable[i] = _reflect( crc, 32 );
+     //   }
+
+        unsigned int crc;
+        unsigned int poly;  // polynomial exclusive-or pattern 
+        // terms of polynomial defining this crc (except x^32): 
+        static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+        /* make exclusive-or pattern from polynomial (0xedb88320L) */
+        poly = 0L;
+        for (unsigned int n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+        {
+            poly |= 1L << (31 - p[n]);
+        }
+         
+        for (int n=0; n<256; ++n)
+        {
+            crc = (unsigned int)n;
+
+            for (int k = 0; k < 8; k++)
+            {
+                crc = (crc & 1) ? (poly ^ (crc >> 1)) : crc >> 1;
+            }
+            crc_table[n] = crc;
+        }
+
+        hashTableInitialized = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// CalculateCRC
+//-----------------------------------------------------------------------------
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO1b(buf) crc = (crc >> 8) ^ crc_table[(crc & 0xFF) ^ *buf++]
+unsigned int CRCCalculator::calcCRC(unsigned int crc, void *buffer, unsigned int count)
+{
+    byte* p = (byte*) buffer; 
+    //unsigned int orig = crc;
+
+ //   p = (byte*) buffer;
+ //   while (count--) 
+ //   {
+    //    crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+ //   }
+
+ //   return crc ^ orig;
+
+    if (buffer == 0) return 0L;
+
+    crc = crc ^ 0xffffffffL;
+    while (count--)
+    {
+        crc = crc_table[((int)crc ^ (*p++)) & 0xff] ^ (crc >> 8);
+    }
+   // if (len) do {
+   //   DO1(buf);
+   // } while (--len);
+    return crc ^ 0xffffffffL;
+}
+
+//-----------------------------------------------------------------------------
+// CalculatePaletteCRC
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator::calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count)
+{
+    byte *p;
+    unsigned int orig = crc;
+
+    p = (byte*) buffer;
+    while (count--)
+    {
+        crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+        crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+
+        p += 6;
+    }
+
+    return crc ^ orig;
+}
+
+//*****************************************************************************
+// Private Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Reflect
+//! Help function when creating the CRC Table
+//! Swaps bit 0 for bit 7
+//!       bit 1 for bit 6
+//!       bit 2 for bit 5 ...
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator::_reflect(unsigned int ref, char ch)
+{
+    unsigned int value = 0;
+    for (int i=1; i<(ch + 1); ++i)
+    {
+        if(ref & 1) 
+        {
+            value |= 1 << (ch - i);
+        }
+        ref >>= 1;
+    }
+    return value;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h
new file mode 100755 (executable)
index 0000000..06629eb
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CYCLIC_REDUNDANCY_CHECK_CALCULATOR_H_
+#define CYCLIC_REDUNDANCY_CHECK_CALCULATOR_H_
+
+//*****************************************************************************
+//! Cyclic Redundancy Check Calculator 
+//! CRC is a type of hash function which is used to produce a small, 
+//! fixed-size checksum of a larger block of data.
+//!
+//! Often used in networks for reducing errors caused by noise.
+//!
+//! http://en.wikipedia.org/wiki/CRC32
+//! http://en.wikipedia.org/wiki/Hash_function
+//! http://en.wikipedia.org/wiki/Hash_table
+//! http://www.gamedev.net/reference/articles/article1941.asp
+//! http://www.codeproject.com/cpp/crc32_large.asp
+//*****************************************************************************
+class CRCCalculator
+{
+public:
+
+    //Constructor
+    CRCCalculator();
+
+    //Functions for calculating crc values
+    unsigned int calcCRC(unsigned int crc, void *buffer, unsigned int count);
+    unsigned int calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count);
+
+private:
+
+    //Help function used to build hash table
+    unsigned int _reflect(unsigned int ref, char ch);
+
+private:   
+
+    static unsigned int m_crcTable[256];   //!< Hash table that associates keys with values
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp
new file mode 100755 (executable)
index 0000000..f0950da
--- /dev/null
@@ -0,0 +1,122 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "CRCCalculator2.h"
+
+#define CRC32_POLYNOMIAL    0xedb88320    //0x04C11DB7
+typedef unsigned char byte;
+
+//-----------------------------------------------------------------------------
+// Static Variabels
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator2::m_crcTable[256] = {0};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+CRCCalculator2::CRCCalculator2()
+{
+    static bool hashTableInitialized = false;
+
+    //Build hash table
+    //http://www.gamedev.net/reference/articles/article1941.asp
+    if ( !hashTableInitialized )
+    {
+        unsigned int crc;
+
+        //For each value 
+        for (int i=0; i<256; i++)
+        {
+            crc = _reflect( i, 8 ) << 24;
+
+            for (int j = 0; j < 8; j++) 
+            {
+                crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
+            }
+            
+            m_crcTable[i] = _reflect( crc, 32 );
+        }
+
+        hashTableInitialized = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// CalculateCRC
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator2::calcCRC(unsigned int crc, void *buffer, unsigned int count)
+{
+    byte* p = (byte*) buffer; 
+    unsigned int orig = crc;
+
+    p = (byte*) buffer;
+    while (count--) 
+    {
+        crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+    }
+
+    return crc ^ orig;
+}
+
+//-----------------------------------------------------------------------------
+// CalculatePaletteCRC
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator2::calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count)
+{
+    byte *p;
+    unsigned int orig = crc;
+
+    p = (byte*) buffer;
+    while (count--)
+    {
+        crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+        crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++];
+
+        p += 6;
+    }
+
+    return crc ^ orig;
+}
+
+//*****************************************************************************
+// Private Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Reflect
+//! Help function when creating the CRC Table
+//! Swaps bit 0 for bit 7
+//!       bit 1 for bit 6
+//!       bit 2 for bit 5 ...
+//-----------------------------------------------------------------------------
+unsigned int CRCCalculator2::_reflect(unsigned int ref, char ch)
+{
+    unsigned int value = 0;
+    for (int i=1; i<(ch + 1); ++i)
+    {
+        if(ref & 1) 
+        {
+            value |= 1 << (ch - i);
+        }
+        ref >>= 1;
+    }
+    return value;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h
new file mode 100755 (executable)
index 0000000..7082bc8
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CYCLIC_REDUNDANCY_CHECK_CALCULATOR_2_H_
+#define CYCLIC_REDUNDANCY_CHECK_CALCULATOR_2_H_
+
+//*****************************************************************************
+//! Cyclic Redundancy Check Calculator 
+//! CRC is a type of hash function which is used to produce a small, 
+//! fixed-size checksum of a larger block of data.
+//!
+//! Often used in networks for reducing errors caused by noise.
+//!
+//! http://en.wikipedia.org/wiki/CRC32
+//! http://en.wikipedia.org/wiki/Hash_function
+//! http://en.wikipedia.org/wiki/Hash_table
+//! http://www.gamedev.net/reference/articles/article1941.asp
+//! http://www.codeproject.com/cpp/crc32_large.asp
+//*****************************************************************************
+class CRCCalculator2
+{
+public:
+
+    //Constructor
+    CRCCalculator2();
+
+    //Functions for calculating crc values
+    unsigned int calcCRC(unsigned int crc, void *buffer, unsigned int count);
+    unsigned int calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count);
+
+private:
+
+    //Help function used to build hash table
+    unsigned int _reflect(unsigned int ref, char ch);
+
+private:   
+
+    static unsigned int m_crcTable[256];   //!< Hash table that associates keys with values
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/log/Logger.cpp b/source/mupen64plus-video-arachnoid/src/log/Logger.cpp
new file mode 100755 (executable)
index 0000000..193a8eb
--- /dev/null
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "Logger.h"
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Initializes log with debug callback
+//-----------------------------------------------------------------------------
+bool Logger::initialize(void (*debugCallback)(void*, int, const char*), void *context)
+{
+    m_debugCallback = debugCallback;
+    m_debugCallContext = context;
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+Logger::~Logger()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Dispose
+//! Closes log file
+//-----------------------------------------------------------------------------
+void Logger::dispose()
+{
+    m_debugCallback = NULL;
+    m_debugCallContext = NULL;
+}
+
+//-----------------------------------------------------------------------------
+//* Print Message
+//! Writes a message to log-file and/or console.
+//! @param msg The text message to write to log-file.
+//! @param lml How important the message is. Error message are more important then warnings for example.
+//-----------------------------------------------------------------------------
+void Logger::printMsg(const char* msg, m64p_msg_level lml)
+{
+    if (m_debugCallback != NULL)
+    {
+        (*m_debugCallback)(m_debugCallContext, lml, msg);
+    }    
+}
diff --git a/source/mupen64plus-video-arachnoid/src/log/Logger.h b/source/mupen64plus-video-arachnoid/src/log/Logger.h
new file mode 100755 (executable)
index 0000000..168b44b
--- /dev/null
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+#include <cstdlib>
+#include "m64p_types.h"
+
+//*****************************************************************************
+//*****************************************************************************
+//* Log
+//! Class for sending log messages to M64P
+//*****************************************************************************
+class Logger
+{
+public:
+    //Destructor
+    ~Logger();
+
+    //Singleton Instance
+    static Logger& getSingleton()
+    {
+        static Logger pInstance;
+        return pInstance;
+    }
+
+    //Initialize / Dispose
+    bool initialize(void (*debugCallback)(void*, int, const char*), void *context);  
+    void dispose();
+
+    //Message
+    void printMsg(const char* msg, m64p_msg_level lml=M64MSG_VERBOSE);
+
+protected:
+    //! Constructor
+    Logger() { m_debugCallback = NULL; m_debugCallContext = NULL; }
+
+protected:
+    void (*m_debugCallback)(void *, int, const char *);
+    void *m_debugCallContext;
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/m64p.h b/source/mupen64plus-video-arachnoid/src/m64p.h
new file mode 100755 (executable)
index 0000000..e0ce6c0
--- /dev/null
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef M64P_H
+#define M64P_H
+
+#ifdef WIN32
+       #include <windows.h>
+#else
+    #include <stdlib.h>
+    #include <string.h>
+
+    #define BOOL int
+#endif
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_types.h"
+#include "m64p_plugin.h"
+#include "m64p_config.h"
+#include "m64p_vidext.h"
+
+/* definitions of pointers to Core config functions */
+extern ptr_ConfigOpenSection      ConfigOpenSection;
+extern ptr_ConfigSetParameter     ConfigSetParameter;
+extern ptr_ConfigGetParameter     ConfigGetParameter;
+extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp;
+extern ptr_ConfigSetDefaultInt    ConfigSetDefaultInt;
+extern ptr_ConfigSetDefaultFloat  ConfigSetDefaultFloat;
+extern ptr_ConfigSetDefaultBool   ConfigSetDefaultBool;
+extern ptr_ConfigSetDefaultString ConfigSetDefaultString;
+extern ptr_ConfigGetParamInt      ConfigGetParamInt;
+extern ptr_ConfigGetParamFloat    ConfigGetParamFloat;
+extern ptr_ConfigGetParamBool     ConfigGetParamBool;
+extern ptr_ConfigGetParamString   ConfigGetParamString;
+
+extern ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath;
+extern ptr_ConfigGetUserConfigPath     ConfigGetUserConfigPath;
+extern ptr_ConfigGetUserDataPath       ConfigGetUserDataPath;
+extern ptr_ConfigGetUserCachePath      ConfigGetUserCachePath;
+
+/* definitions of pointers to Core video extension functions */
+extern ptr_VidExt_Init                  CoreVideo_Init;
+extern ptr_VidExt_Quit                  CoreVideo_Quit;
+extern ptr_VidExt_ListFullscreenModes   CoreVideo_ListFullscreenModes;
+extern ptr_VidExt_SetVideoMode          CoreVideo_SetVideoMode;
+extern ptr_VidExt_SetCaption            CoreVideo_SetCaption;
+extern ptr_VidExt_ToggleFullScreen      CoreVideo_ToggleFullScreen;
+extern ptr_VidExt_ResizeWindow          CoreVideo_ResizeWindow;
+extern ptr_VidExt_GL_GetProcAddress     CoreVideo_GL_GetProcAddress;
+extern ptr_VidExt_GL_SetAttribute       CoreVideo_GL_SetAttribute;
+extern ptr_VidExt_GL_SwapBuffers        CoreVideo_GL_SwapBuffers;
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/main.cpp b/source/mupen64plus-video-arachnoid/src/main.cpp
new file mode 100755 (executable)
index 0000000..bc8360e
--- /dev/null
@@ -0,0 +1,453 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+//Includes
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p.h"
+#include "GraphicsPlugin.h"        //Main class
+#include "config/Config.h"         //Configuration   
+#include "Logger.h"                //Debug logger
+#include "MemoryLeakDetector.h"    //For detecting memory leaks
+
+#include "m64p_types.h"
+#include "m64p_common.h"
+#include "m64p_plugin.h"
+#include "m64p_config.h"
+#include "m64p_vidext.h"
+
+#include "osal_dynamiclib.h"
+
+//Definitions
+#define PLUGIN_NAME "Arachnoid Video Plugin"
+#define PLUGIN_VERSION           0x020000
+#define VIDEO_PLUGIN_API_VERSION 0x020200
+#define CONFIG_API_VERSION       0x020000
+#define VIDEXT_API_VERSION       0x030000
+
+#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
+
+#define MI_INTR_DP 0x00000020      //!< RDP Interrupt signal
+#define MI_INTR_SP 0x00000001      //!< RSP Interrupt signal
+
+//-----------------------------------------------------------------------------
+// Global variables
+//-----------------------------------------------------------------------------
+
+char              g_cfgFilename[] = "ConfigGraphicsPlugin.cfg";  //!< Name configuration file
+GFX_INFO          g_graphicsInfo;                                //!< Information about window, memory...
+GraphicsPlugin    g_graphicsPlugin;                              //!< Main class for application
+Config            g_config(&g_graphicsPlugin);                   //!< Handles configuration
+
+void (*renderCallback)(int) = NULL;
+
+
+/* definitions of pointers to Core config functions */
+ptr_ConfigOpenSection      ConfigOpenSection = NULL;
+ptr_ConfigSetParameter     ConfigSetParameter = NULL;
+ptr_ConfigGetParameter     ConfigGetParameter = NULL;
+ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;
+ptr_ConfigSetDefaultInt    ConfigSetDefaultInt = NULL;
+ptr_ConfigSetDefaultFloat  ConfigSetDefaultFloat = NULL;
+ptr_ConfigSetDefaultBool   ConfigSetDefaultBool = NULL;
+ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;
+ptr_ConfigGetParamInt      ConfigGetParamInt = NULL;
+ptr_ConfigGetParamFloat    ConfigGetParamFloat = NULL;
+ptr_ConfigGetParamBool     ConfigGetParamBool = NULL;
+ptr_ConfigGetParamString   ConfigGetParamString = NULL;
+
+ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;
+ptr_ConfigGetUserConfigPath     ConfigGetUserConfigPath = NULL;
+ptr_ConfigGetUserDataPath       ConfigGetUserDataPath = NULL;
+ptr_ConfigGetUserCachePath      ConfigGetUserCachePath = NULL;
+
+/* definitions of pointers to Core video extension functions */
+ptr_VidExt_Init                  CoreVideo_Init = NULL;
+ptr_VidExt_Quit                  CoreVideo_Quit = NULL;
+ptr_VidExt_ListFullscreenModes   CoreVideo_ListFullscreenModes = NULL;
+ptr_VidExt_SetVideoMode          CoreVideo_SetVideoMode = NULL;
+ptr_VidExt_SetCaption            CoreVideo_SetCaption = NULL;
+ptr_VidExt_ToggleFullScreen      CoreVideo_ToggleFullScreen = NULL;
+ptr_VidExt_ResizeWindow          CoreVideo_ResizeWindow = NULL;
+ptr_VidExt_GL_GetProcAddress     CoreVideo_GL_GetProcAddress = NULL;
+ptr_VidExt_GL_SetAttribute       CoreVideo_GL_SetAttribute = NULL;
+ptr_VidExt_GL_SwapBuffers        CoreVideo_GL_SwapBuffers = NULL;
+
+//-----------------------------------------------------------------------------
+// Mupen64plus 2.0 Common Plugin API Functions
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif
+EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
+                                   void (*DebugCallback)(void *, int, const char *))
+{
+    char logMsg[530];
+    Logger::getSingleton().initialize(DebugCallback, Context);
+    Logger::getSingleton().printMsg("PluginStartup");
+
+    /* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */
+    ptr_CoreGetAPIVersions CoreAPIVersionFunc;
+    CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions");
+    if (CoreAPIVersionFunc == NULL)
+    {
+        sprintf(logMsg, "Core emulator broken; no CoreAPIVersionFunc() function found.");
+        Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR);
+        return M64ERR_INCOMPATIBLE;
+    }
+    int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
+    (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);
+    if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000))
+    {
+        sprintf(logMsg, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",
+                VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION));
+        Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR);
+        return M64ERR_INCOMPATIBLE;
+    }
+    if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000))
+    {
+        sprintf(logMsg, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",
+                VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION));
+        Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR);
+        return M64ERR_INCOMPATIBLE;
+    }
+
+    /* Get the core config function pointers from the library handle */
+    ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection");
+    ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter");
+    ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter");
+    ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt");
+    ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat");
+    ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool");
+    ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString");
+    ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt");
+    ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");
+    ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");
+    ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");
+
+    ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath");
+    ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath");
+    ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath");
+    ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath");
+
+    if (!ConfigOpenSection   || !ConfigSetParameter    || !ConfigGetParameter ||
+        !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
+        !ConfigGetParamInt   || !ConfigGetParamFloat   || !ConfigGetParamBool   || !ConfigGetParamString ||
+        !ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath)
+    {
+        Logger::getSingleton().printMsg("Couldn't connect to Core configuration functions", M64MSG_ERROR);
+        return M64ERR_INCOMPATIBLE;
+    }
+
+    /* Get the core Video Extension function pointers from the library handle */
+    CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init");
+    CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit");
+    CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes");
+    CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode");
+    CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption");
+    CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen");
+    CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow");
+    CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress");
+    CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute");
+    CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers");
+
+    if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode ||
+        !CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress ||
+        !CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow)
+    {
+        Logger::getSingleton().printMsg("Couldn't connect to Core video functions", M64MSG_ERROR);
+        return M64ERR_INCOMPATIBLE;
+    }
+
+    //Read configuration
+    if (g_config.initialize())
+    {
+        g_config.load();
+        g_graphicsPlugin.setConfig(g_config.getConfig());
+    }
+
+    return M64ERR_SUCCESS;
+}
+
+EXPORT m64p_error CALL PluginShutdown(void)
+{
+    //Close Logger
+    Logger::getSingleton().printMsg("CloseDLL\n");
+    Logger::getSingleton().dispose();   
+
+    //g_graphicsPlugin.dispose();  
+    return M64ERR_SUCCESS;
+}
+
+EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)
+{
+    /* set version info */
+    if (PluginType != NULL)
+        *PluginType = M64PLUGIN_GFX;
+
+    if (PluginVersion != NULL)
+        *PluginVersion = PLUGIN_VERSION;
+
+    if (APIVersion != NULL)
+        *APIVersion = VIDEO_PLUGIN_API_VERSION;
+    
+    if (PluginNamePtr != NULL)
+        *PluginNamePtr = PLUGIN_NAME;
+
+    if (Capabilities != NULL)
+    {
+        *Capabilities = 0;
+    }
+                    
+    return M64ERR_SUCCESS;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Mupen64plus 2.0 Video Plugin API Functions
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+//* InitiateGFX
+//! This function is called when the DLL is started to give
+//! information from the emulator that the n64 graphics
+//!    uses. This is not called from the emulation thread.
+//! @param[in] Gfx_Info Information about rom and emulator
+//! @return true on success, FALSE on failure to initialise
+//!           
+//! @note on interrupts :
+//!    To generate an interrupt set the appropriate bit in MI_INTR_REG
+//!    and then  the function CheckInterrupts to tell the emulator
+//!    that there is a waiting interrupt.
+//-----------------------------------------------------------------------------
+EXPORT BOOL CALL InitiateGFX(GFX_INFO Gfx_Info)
+{
+    Logger::getSingleton().printMsg("InitiateGFX");
+
+    //Save Graphics Info
+    memcpy(&g_graphicsInfo, &Gfx_Info, sizeof(GFX_INFO));
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Rom Open
+//! This function is called when a rom is open. (from the emulation thread)
+//-----------------------------------------------------------------------------
+EXPORT int CALL RomOpen()
+{
+    Logger::getSingleton().printMsg("RomOpen\n");
+    return g_graphicsPlugin.initialize(&g_graphicsInfo);
+}
+
+//-----------------------------------------------------------------------------
+//* Resize Video Output
+//! This function is called to force us to resize our output OpenGL window.
+//! This is currently unsupported, and should never be called because we do
+//! not pass the RESIZABLE flag to VidExt_SetVideoMode when initializing.
+//-----------------------------------------------------------------------------
+EXPORT void CALL ResizeVideoOutput(int Width, int Height)
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Rom Closed
+//! This function is called when a rom is closed.
+//-----------------------------------------------------------------------------
+EXPORT void CALL RomClosed()
+{
+    //Logger::getSingleton().printMsg("RomClosed\n");
+    //Destroy 
+    g_graphicsPlugin.dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Update Screen
+//! This function is called in response to a vsync of the
+//! screen where the VI bit in MI_INTR_REG has already been set
+//-----------------------------------------------------------------------------
+EXPORT void CALL UpdateScreen()
+{
+    if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_VI)
+        g_graphicsPlugin.drawScreen();
+    else if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_CI)
+        g_graphicsPlugin.setDrawScreenSignal();
+    else
+    {
+        Logger::getSingleton().printMsg("Invalid screen update setting!", M64MSG_WARNING);
+        g_graphicsPlugin.drawScreen();
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//* ProcessDList
+//! This function is called when there is a Dlist to be processed. (High level GFX list)
+//-----------------------------------------------------------------------------
+EXPORT void CALL ProcessDList()
+{
+    Logger::getSingleton().printMsg("ProcessDList\n");
+
+    try
+    {
+        g_graphicsPlugin.viStatusChanged();
+        g_graphicsPlugin.processDisplayList();
+    }
+    catch (...)
+    {
+        Logger::getSingleton().printMsg("Unknown Error processing DisplayList", M64MSG_WARNING); 
+        //MessageBox(0, "Unknown Error processing DisplayList", "Arachnoid Graphics Plugin", MB_OK|MB_SETFOREGROUND); 
+
+        g_graphicsPlugin.dispose();
+        g_graphicsPlugin.initialize(&g_graphicsInfo);
+
+        //Trigger Interupts
+        *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_DP;
+        g_graphicsInfo.CheckInterrupts();
+        *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_SP;
+        g_graphicsInfo.CheckInterrupts();    
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//* ProcessRDPList
+//! This function is called when there is a Dlist to be processed. (Low level GFX list)
+//! @todo ProcessRDPList
+//-----------------------------------------------------------------------------
+EXPORT void CALL ProcessRDPList()
+{
+    Logger::getSingleton().printMsg("ProcessRDPList\n");
+    //TODO
+}
+
+//-----------------------------------------------------------------------------
+//* Show CFB
+//! Usally once Dlists are started being displayed, cfb is
+//! ignored. This function tells the dll to start displaying
+//! them again.
+//-----------------------------------------------------------------------------
+EXPORT void CALL ShowCFB()
+{
+    Logger::getSingleton().printMsg("ShowCFB\n");
+}
+
+//-----------------------------------------------------------------------------
+//* ViStatusChanged
+//! This function is called to notify the dll that the
+//! ViStatus registers value has been changed.
+//-----------------------------------------------------------------------------
+EXPORT void CALL ViStatusChanged()
+{
+    Logger::getSingleton().printMsg("ViStatusChanged");
+
+    //g_graphicsPlugin.viStatusChanged();
+}
+
+//-----------------------------------------------------------------------------
+//* ViWidthChanged
+//! This function is called to notify the dll that the
+//! ViWidth registers value has been changed.
+//-----------------------------------------------------------------------------
+EXPORT void CALL ViWidthChanged()
+{    
+    Logger::getSingleton().printMsg("ViWidthChanged");
+    //g_graphicsPlugin.viStatusChanged();
+}
+
+//-----------------------------------------------------------------------------
+//* MoveScreen
+//! This function is called in response to the emulator
+//! receiving a WM_MOVE passing the xpos and ypos passed
+//! from that message.
+//! @param xpos The x-coordinate of the upper-left corner of the 
+//!             client area of the window.
+//! @param ypos The y-coordinate of the upper-left corner of the
+//!             client area of the window. 
+//! @todo MoveScreen
+//----------------------------------------------------------------------------- 
+EXPORT void CALL MoveScreen(int xpos, int ypos)
+{
+    Logger::getSingleton().printMsg("MoveScreen\n");
+    //TODO
+}
+
+//-----------------------------------------------------------------------------
+//* ChangeWindow
+//! Toggle between fullscreen and window mode
+//-----------------------------------------------------------------------------
+EXPORT void CALL ChangeWindow()
+{
+    Logger::getSingleton().printMsg("ChangeWindow\n");
+    //Toggle Fullscreen
+    g_graphicsPlugin.toggleFullscreen();
+}
+
+//-----------------------------------------------------------------------------
+//* ReadScreen2
+//! This function reads the pixels of the currently displayed screen
+//-----------------------------------------------------------------------------
+EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
+{
+    g_graphicsPlugin.takeScreenshot(dest, width, height, front);
+}
+
+//-----------------------------------------------------------------------------
+//* SetRenderingCallback
+//! Allows the core to register a callback function that will be called by the 
+//! graphics plugin just before the the frame buffers are swapped.
+//-----------------------------------------------------------------------------
+EXPORT void CALL SetRenderingCallback(void (*callback)(int))
+{
+    OpenGLManager::getSingleton().setRenderingCallback(callback);
+}
+
+//-----------------------------------------------------------------------------
+//* FBRead
+//! Read data from frame buffer into emulated RAM space 
+//-----------------------------------------------------------------------------
+EXPORT void CALL FBRead(unsigned int addr)
+{
+    //TODO
+}
+
+//-----------------------------------------------------------------------------
+//* FBWrite
+//! Write data from emulated RAM space into frame buffer
+//-----------------------------------------------------------------------------
+EXPORT void CALL FBWrite(unsigned int addr, unsigned int size)
+{
+    //TODO
+}
+
+//-----------------------------------------------------------------------------
+//* FBWrite
+//! Get some information about the frame buffer 
+//-----------------------------------------------------------------------------
+EXPORT void FBGetFrameBufferInfo(void *p)
+{
+    //TODO
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/math/MathLib.h b/source/mupen64plus-video-arachnoid/src/math/MathLib.h
new file mode 100755 (executable)
index 0000000..cf9e393
--- /dev/null
@@ -0,0 +1,100 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MATH_LIBRARY_H_
+#define MATH_LIBRARY_H_
+
+#include <cmath>     //sqrtf
+#include "m64p.h"  
+
+// Formula: a.b = a0*b0 + a1*b1 + a2*b2
+#define Vec3Dot(a,b)         ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
+
+#define Vec3Normalize(v) { \
+    float lenght = (v)[0]*(v)[0]+(v)[1]*(v)[1]+(v)[2]*(v)[2]; \
+    if ( lenght > 0.00001f ) { \
+        lenght = 1.0f / sqrt(lenght); \
+        (v)[0] *= lenght; \
+        (v)[1] *= lenght; \
+        (v)[2] *= lenght; \
+    } \
+}
+
+
+//-----------------------------------------------------------------------------
+// Transform Vector
+//-----------------------------------------------------------------------------
+
+inline void transformVertex( float* m, float* v, float* out )
+{
+    float x = v[0];
+    float y = v[1];
+    float z = v[2];
+    out[0] = m[0] * x + m[4] * y + m[8]  * z + m[12]; 
+    out[1] = m[1] * x + m[5] * y + m[9]  * z + m[13];
+    out[2] = m[2] * x + m[6] * y + m[10] * z + m[14];
+    out[3] = m[3] * x + m[7] * y + m[11] * z + m[15];
+}
+
+inline void transformVector( float* m, float* v, float* out )
+{
+    float x = v[0];
+    float y = v[1];
+    float z = v[2];
+    out[0] = m[0] * x + m[4] * y + m[8]  * z; 
+    out[1] = m[1] * x + m[5] * y + m[9]  * z;
+    out[2] = m[2] * x + m[6] * y + m[10] * z;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Random Float
+//-----------------------------------------------------------------------------
+inline float randomFloat(float min, float max)
+{
+    return (float)( min + double(max-min)*rand()/RAND_MAX );
+}
+
+inline unsigned int pow2( unsigned int dim )
+{
+    unsigned int i = 1;
+
+    while (i < dim) i <<= 1;
+
+    return i;
+}
+
+inline unsigned int powof( unsigned int dim )
+{
+    unsigned int num = 1;
+    unsigned int i = 0;
+
+    while (num < dim)
+    {
+        num <<= 1;
+        i++;
+    }
+
+    return i;
+}
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp b/source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp
new file mode 100755 (executable)
index 0000000..d3a73ba
--- /dev/null
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "Matrix4.h"
+
+const Matrix4 Matrix4::ZERO( 0, 0, 0, 0,
+                             0, 0, 0, 0,
+                             0, 0, 0, 0,
+                             0, 0, 0, 0 );
+
+const Matrix4 Matrix4::IDENTITY( 1, 0, 0, 0,
+                                 0, 1, 0, 0,
+                                 0, 0, 1, 0,
+                                 0, 0, 0, 1 );
+
+const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE( 0.5,  0,    0,  0.5, 
+                                                0,   -0.5,  0,  0.5, 
+                                                0,    0,    1,    0,
+                                                0,    0,    0,    1);
+
+
+//-----------------------------------------------------------------------
+//! Calclate and returns the deteminant of the matrix
+//-----------------------------------------------------------------------
+float Matrix4::determinant() const
+{
+    return (_m[0]*(_m[4]*_m[8] - _m[7]*_m[5])) - (_m[1]*(_m[3]*_m[8] - _m[6]*_m[5])) + (_m[2]*(_m[3]*_m[7] - _m[6]*_m[4]));
+}
+
+//-----------------------------------------------------------------------
+//! Inverse Matrix
+//-----------------------------------------------------------------------
+Matrix4 Matrix4::inverse() const
+{
+    float m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
+    float m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
+    float m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
+    float m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
+
+    float v0 = m20 * m31 - m21 * m30;
+    float v1 = m20 * m32 - m22 * m30;
+    float v2 = m20 * m33 - m23 * m30;
+    float v3 = m21 * m32 - m22 * m31;
+    float v4 = m21 * m33 - m23 * m31;
+    float v5 = m22 * m33 - m23 * m32;
+
+    float t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
+    float t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
+    float t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
+    float t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
+
+    float invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
+
+    float d00 = t00 * invDet;
+    float d10 = t10 * invDet;
+    float d20 = t20 * invDet;
+    float d30 = t30 * invDet;
+
+    float d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
+    float d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
+    float d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
+    float d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
+
+    v0 = m10 * m31 - m11 * m30;
+    v1 = m10 * m32 - m12 * m30;
+    v2 = m10 * m33 - m13 * m30;
+    v3 = m11 * m32 - m12 * m31;
+    v4 = m11 * m33 - m13 * m31;
+    v5 = m12 * m33 - m13 * m32;
+
+    float d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
+    float d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
+    float d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
+    float d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
+
+    v0 = m21 * m10 - m20 * m11;
+    v1 = m22 * m10 - m20 * m12;
+    v2 = m23 * m10 - m20 * m13;
+    v3 = m22 * m11 - m21 * m12;
+    v4 = m23 * m11 - m21 * m13;
+    v5 = m23 * m12 - m22 * m13;
+
+    float d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
+    float d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
+    float d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
+    float d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
+
+    return Matrix4(
+        d00, d01, d02, d03,
+        d10, d11, d12, d13,
+        d20, d21, d22, d23,
+        d30, d31, d32, d33);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/math/Matrix4.h b/source/mupen64plus-video-arachnoid/src/math/Matrix4.h
new file mode 100755 (executable)
index 0000000..5595479
--- /dev/null
@@ -0,0 +1,252 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MATRIX_4_H_
+#define MATRIX_4_H_
+
+#include <iostream>
+#include <ostream>
+
+//*****************************************************************************
+//* Matrix4
+//! Math class defining a 4x4 matrix or an array of 16 float.
+//! @details Used for viewprojection matrix and vertex transformation.
+//*****************************************************************************
+class Matrix4
+{
+public:
+    
+    //! The matrix entries, indexed by [row][col].
+    union {
+        float m[4][4];
+        float _m[16];
+    };
+
+public:
+
+    //! Default constructor.
+    inline Matrix4() { operator=(IDENTITY);  }
+    inline Matrix4(
+        float m00, float m01, float m02, float m03,
+        float m10, float m11, float m12, float m13,
+        float m20, float m21, float m22, float m23,
+        float m30, float m31, float m32, float m33 )
+    {
+        m[0][0] = m00;
+        m[0][1] = m01;
+        m[0][2] = m02;
+        m[0][3] = m03;
+        m[1][0] = m10;
+        m[1][1] = m11;
+        m[1][2] = m12;
+        m[1][3] = m13;
+        m[2][0] = m20;
+        m[2][1] = m21;
+        m[2][2] = m22;
+        m[2][3] = m23;
+        m[3][0] = m30;
+        m[3][1] = m31;
+        m[3][2] = m32;
+        m[3][3] = m33;
+    }
+
+    //! Matrix multiplication
+    inline Matrix4 operator * ( const Matrix4 &m2 ) const
+    {
+        Matrix4 r;
+        r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
+        r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
+        r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
+        r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
+
+        r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
+        r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
+        r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
+        r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
+
+        r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
+        r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
+        r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
+        r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
+
+        r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
+        r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
+        r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
+        r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
+
+        return r;
+    }
+
+    //Access operators
+    inline float* operator [] ( size_t iRow ) { return m[iRow]; }
+
+    inline const float* const operator [] ( size_t iRow ) const { return m[iRow]; }
+
+    //! Matrix addition.
+    inline Matrix4 operator + ( const Matrix4 &m2 ) const
+    {
+        Matrix4 r;
+
+        r.m[0][0] = m[0][0] + m2.m[0][0];
+        r.m[0][1] = m[0][1] + m2.m[0][1];
+        r.m[0][2] = m[0][2] + m2.m[0][2];
+        r.m[0][3] = m[0][3] + m2.m[0][3];
+
+        r.m[1][0] = m[1][0] + m2.m[1][0];
+        r.m[1][1] = m[1][1] + m2.m[1][1];
+        r.m[1][2] = m[1][2] + m2.m[1][2];
+        r.m[1][3] = m[1][3] + m2.m[1][3];
+
+        r.m[2][0] = m[2][0] + m2.m[2][0];
+        r.m[2][1] = m[2][1] + m2.m[2][1];
+        r.m[2][2] = m[2][2] + m2.m[2][2];
+        r.m[2][3] = m[2][3] + m2.m[2][3];
+
+        r.m[3][0] = m[3][0] + m2.m[3][0];
+        r.m[3][1] = m[3][1] + m2.m[3][1];
+        r.m[3][2] = m[3][2] + m2.m[3][2];
+        r.m[3][3] = m[3][3] + m2.m[3][3];
+
+        return r;
+    }
+
+    //! Matrix subtraction.
+    inline Matrix4 operator - ( const Matrix4 &m2 ) const
+    {
+        Matrix4 r;
+        r.m[0][0] = m[0][0] - m2.m[0][0];
+        r.m[0][1] = m[0][1] - m2.m[0][1];
+        r.m[0][2] = m[0][2] - m2.m[0][2];
+        r.m[0][3] = m[0][3] - m2.m[0][3];
+
+        r.m[1][0] = m[1][0] - m2.m[1][0];
+        r.m[1][1] = m[1][1] - m2.m[1][1];
+        r.m[1][2] = m[1][2] - m2.m[1][2];
+        r.m[1][3] = m[1][3] - m2.m[1][3];
+
+        r.m[2][0] = m[2][0] - m2.m[2][0];
+        r.m[2][1] = m[2][1] - m2.m[2][1];
+        r.m[2][2] = m[2][2] - m2.m[2][2];
+        r.m[2][3] = m[2][3] - m2.m[2][3];
+
+        r.m[3][0] = m[3][0] - m2.m[3][0];
+        r.m[3][1] = m[3][1] - m2.m[3][1];
+        r.m[3][2] = m[3][2] - m2.m[3][2];
+        r.m[3][3] = m[3][3] - m2.m[3][3];
+
+        return r;
+    }
+
+    //! Tests 2 matrices for equality.
+    inline bool operator == ( const Matrix4& m2 ) const
+    {
+        if( 
+            m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
+            m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
+            m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
+            m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
+            return false;
+        return true;
+    }
+
+    //! Tests 2 matrices for inequality.
+    inline bool operator != ( const Matrix4& m2 ) const
+    {
+        if( 
+            m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
+            m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
+            m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
+            m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
+            return true;
+        return false;
+    }
+
+    //!Transpose Matrix (Switch columns with rows)
+    inline Matrix4 transpose() const
+    {
+        return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
+                       m[0][1], m[1][1], m[2][1], m[3][1],
+                       m[0][2], m[1][2], m[2][2], m[3][2],
+                       m[0][3], m[1][3], m[2][3], m[3][3]);
+    }
+
+    //! Set Translation Part of the matrix
+    inline void setTranslationPart(const float v[3] )
+    {
+        m[0][3] = v[0];
+        m[1][3] = v[1];
+        m[2][3] = v[2];
+    }      
+
+    //! Builds a translation matrix
+    inline void setTranslation(float tx, float ty, float tz)
+    {
+        m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
+        m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
+        m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
+        m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
+    }
+
+    //! Set scale part of matrix
+    inline void setScalePart( const float v[3] )
+    {
+        m[0][0] = v[0];
+        m[1][1] = v[1];
+        m[2][2] = v[2];
+    }
+
+    static const Matrix4 ZERO;
+    static const Matrix4 IDENTITY;        
+    static const Matrix4 CLIPSPACE2DTOIMAGESPACE;  //! Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} and inverts the Y. 
+
+
+    inline Matrix4 operator*(float scalar) const
+    {
+        return Matrix4(
+            scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
+            scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
+            scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
+            scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
+    }
+
+    //! Function for writing to a stream.
+    inline friend std::ostream& operator << ( std::ostream& o, const Matrix4& m )
+    {
+        o << "Matrix4(";
+        for (size_t i = 0; i < 4; ++i)
+        {
+            o << " row" << (unsigned)i << "{";
+            for(size_t j = 0; j < 4; ++j)
+            {
+                o << m[i][j] << " ";
+            }
+            o << "}";
+        }
+        o << ")";
+        return o;
+    }
+    
+    float determinant() const;
+    Matrix4 inverse() const;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h
new file mode 100755 (executable)
index 0000000..f94bcda
--- /dev/null
@@ -0,0 +1,41 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   Mupen64plus-core - osal/dynamiclib.h                                  *
+ *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
+ *   Copyright (C) 2009 Richard Goedeken                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   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.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if !defined(OSAL_DYNAMICLIB_H)
+#define OSAL_DYNAMICLIB_H
+
+#include "m64p_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath);
+
+void *     osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
+
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #define OSAL_DYNAMICLIB_H */
diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp
new file mode 100755 (executable)
index 0000000..39df6cb
--- /dev/null
@@ -0,0 +1,66 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   Mupen64plus-core - osal/dynamiclib_unix.c                             *
+ *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
+ *   Copyright (C) 2009 Richard Goedeken                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   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.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include "m64p_types.h"
+#include "osal_dynamiclib.h"
+
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
+{
+    if (pLibHandle == NULL || pccLibraryPath == NULL)
+        return M64ERR_INPUT_ASSERT;
+
+    *pLibHandle = dlopen(pccLibraryPath, RTLD_NOW);
+
+    if (*pLibHandle == NULL)
+    {
+        fprintf(stderr, "dlopen('%s') error: %s\n", pccLibraryPath, dlerror());
+        return M64ERR_INPUT_NOT_FOUND;
+    }
+
+    return M64ERR_SUCCESS;
+}
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
+{
+    if (pccProcedureName == NULL)
+        return NULL;
+
+    return dlsym(LibHandle, pccProcedureName);
+}
+
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
+{
+    int rval = dlclose(LibHandle);
+
+    if (rval != 0)
+    {
+        fprintf(stderr, "dlclose() error: %s\n", dlerror());
+        return M64ERR_INTERNAL;
+    }
+
+    return M64ERR_SUCCESS;
+}
+
+
diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp
new file mode 100755 (executable)
index 0000000..d55b2ae
--- /dev/null
@@ -0,0 +1,74 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Arachnoid Graphics Plugin for Mupen64Plus                               *
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/              *
+ *   Copyright (C) 2009 Richard Goedeken                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   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.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "m64p_types.h"
+#include "osal_dynamiclib.h"
+
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
+{
+    if (pLibHandle == NULL || pccLibraryPath == NULL)
+        return M64ERR_INPUT_ASSERT;
+
+    *pLibHandle = LoadLibrary(pccLibraryPath);
+
+    if (*pLibHandle == NULL)
+    {
+        char *pchErrMsg;
+        DWORD dwErr = GetLastError(); 
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+        fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
+        LocalFree(pchErrMsg);
+        return M64ERR_INPUT_NOT_FOUND;
+    }
+
+    return M64ERR_SUCCESS;
+}
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
+{
+    if (pccProcedureName == NULL)
+        return NULL;
+
+    return (void *)GetProcAddress(LibHandle, pccProcedureName);
+}
+
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
+{
+    int rval = FreeLibrary(LibHandle);
+
+    if (rval == 0)
+    {
+        char *pchErrMsg;
+        DWORD dwErr = GetLastError(); 
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+        fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg);
+        LocalFree(pchErrMsg);
+        return M64ERR_INTERNAL;
+    }
+
+    return M64ERR_SUCCESS;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp
new file mode 100755 (executable)
index 0000000..dc63652
--- /dev/null
@@ -0,0 +1,350 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "OpenGL2DRenderer.h"
+#include "VI.h"
+#include "m64p.h"
+#include "OpenGL.h"
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Saves pointer to video interface
+//-----------------------------------------------------------------------------
+bool OpenGL2DRenderer::initialize(VI* vi)
+{
+    m_vi = vi;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Render Quad
+//! Renders a 2D rectangle in HUD.
+//! @todo Set Viewport
+//! @todo Reset Viewport
+//-----------------------------------------------------------------------------
+void OpenGL2DRenderer::renderQuad( const float color[4], 
+                                   float x0, float y0, 
+                                   float x1, float y1,            
+                                   float depth )
+{
+    //Get States
+    GLboolean scissor = glIsEnabled(GL_SCISSOR_TEST);
+    GLboolean cull    = glIsEnabled(GL_CULL_FACE);
+
+    //Set States
+    glDisable( GL_SCISSOR_TEST );
+    glDisable( GL_CULL_FACE );
+
+    //Set Othographic Projection Matrix
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f);
+
+    //TODO Set Viewport
+    //glViewport(0, glheightOffset, glwidth, glheight);
+    //glDepthRange( 0.0f, 1.0f );
+
+    //Render Quad
+    glColor4fv(color);
+#ifdef HAVE_GLES
+               GLfloat vtx[] = {
+                       x0, y0, depth,
+                       x1, y0, depth,
+                       x1, y1, depth,
+                       x0, y1, depth
+               };
+               
+               GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
+               if (glcol) glDisableClientState(GL_COLOR_ARRAY);
+               GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);         
+               if (!glvtx)
+                       glEnableClientState(GL_VERTEX_ARRAY);
+               glVertexPointer(3,GL_FLOAT, 0,&vtx);
+               glActiveTexture( GL_TEXTURE1 );
+               GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex1) glDisable(GL_TEXTURE_2D);
+               glActiveTexture( GL_TEXTURE0 );
+               GLboolean gltex = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex) glDisable(GL_TEXTURE_2D);
+               // draw
+               glDrawArrays(GL_TRIANGLE_FAN,0,4);
+               // restaure
+               if (glcol) glEnableClientState(GL_COLOR_ARRAY);
+               glActiveTexture( GL_TEXTURE1 );
+               if (gltex1) glEnable(GL_TEXTURE_2D);
+               glActiveTexture( GL_TEXTURE0 );
+               if (gltex) glEnable(GL_TEXTURE_2D);
+               if (!glvtx)
+                       glDisableClientState(GL_VERTEX_ARRAY);
+               else
+                       glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
+
+#else
+    glBegin(GL_QUADS);
+        glVertex3f(x0, y0, depth);
+        glVertex3f(x1, y0, depth);
+        glVertex3f(x1, y1, depth);
+        glVertex3f(x0, y1, depth);
+    glEnd();
+#endif
+    //Reset Projection Matrix
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+
+    //Reset States
+    if ( scissor ) glEnable(GL_SCISSOR_TEST);
+    if ( cull ) glEnable(GL_CULL_FACE);
+    
+    //TODO Reset viewport?    
+}
+
+
+//-----------------------------------------------------------------------------
+//* Render Textured Quad
+//! Renders a textured 2D rectangle in HUD.
+//! @todo Set Viewport
+//! @todo Reset Viewport
+//-----------------------------------------------------------------------------
+void OpenGL2DRenderer::renderTexturedQuad( const float color[4], 
+                                           const float secondaryColor[4],
+                                           float x0, float y0,            
+                                           float x1, float y1, 
+                                           float depth,
+                                           float t0s0, float t0t0,  
+                                           float t0s1, float t0t1,
+                                           float t1s0, float t1t0, 
+                                           float t1s1, float t1t1 )
+{
+    //Get States
+    GLboolean cull = glIsEnabled(GL_CULL_FACE);
+    GLboolean fog  = glIsEnabled(GL_FOG);
+
+    //Set States
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_FOG);
+
+    //Set Orthographic Projection
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f);
+
+    //TODO Set Viewport
+    //glViewport(0, glheightOffset, glwidth, glheight);
+    //glDepthRange( 0.0f, 1.0f );
+
+    //Set Color
+    glColor4fv( color );
+#ifdef HAVE_GLES
+               GLfloat tex[] = {
+                       t0s0, t0t0,
+                       t0s1, t0t0,
+                       t0s1, t0t1,
+                       t0s0, t0t1
+               };
+               GLfloat tex1[] = {
+                       t1s0, t1t0,
+                       t1s1, t1t0,
+                       t1s1, t1t1,
+                       t1s0, t1t1
+               };
+               GLfloat vtx[] = {
+                       x0, y0, depth,
+                       x1, y0, depth,
+                       x1, y1, depth,
+                       x0, y1, depth
+               };
+               
+               GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
+               if (glcol) glDisableClientState(GL_COLOR_ARRAY);
+               GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);         
+               if (!glvtx)
+                       glEnableClientState(GL_VERTEX_ARRAY);
+               glVertexPointer(3,GL_FLOAT, 0,&vtx);
+/*             glActiveTexture( GL_TEXTURE1 );
+               GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex1) glDisable(GL_TEXTURE_2D);*/
+               glClientActiveTexture( GL_TEXTURE1 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex1);
+               glClientActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+               // draw
+               glDrawArrays(GL_TRIANGLE_FAN,0,4);
+               // restaure
+               if (glcol) glEnableClientState(GL_COLOR_ARRAY);
+//             if (gltex1) glEnable(GL_TEXTURE_2D);
+               if (!glvtx)
+                       glDisableClientState(GL_VERTEX_ARRAY);
+               if (glsav_vtx_type==GL_FLOAT) glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
+               glClientActiveTexture( GL_TEXTURE1 );
+               if (glsav_tex1_type==GL_FLOAT) glTexCoordPointer( glsav_tex1_size, glsav_tex1_type, glsav_tex1_stride, glsav_tex1_array );
+               glClientActiveTexture( GL_TEXTURE0 );
+               if (glsav_tex_type==GL_FLOAT) glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
+#else
+    //Render Rectangle
+    glBegin(GL_QUADS);
+    {    
+        //Vertex 00
+        glTexCoord2f(t0s0, t0t0);    
+        glVertex3f(x0, y0, depth);   
+
+        //Vertex 10
+        glTexCoord2f(t0s1, t0t0);    
+        glVertex3f(x1, y0, depth);
+
+        //Vertex 11
+        glTexCoord2f(t0s1, t0t1 );   
+        glVertex3f(x1, y1, depth);
+
+        //Vertex 01
+        glTexCoord2f(t0s0, t0t1 );   
+        glVertex3f(x0, y1, depth);
+    }
+    glEnd();
+#endif
+    //Reset Projection Matrix
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+
+    //Reset States
+    if ( cull ) glEnable(GL_CULL_FACE);
+    if ( fog ) glEnable(GL_FOG);
+
+    //TODO Reset viewport?    
+}
+
+
+//-----------------------------------------------------------------------------
+//Render Flipped Textured Quad
+//! Renders a flipped textured 2D rectangle in HUD.
+//! @todo Set Viewport
+//! @todo Reset Viewport
+//-----------------------------------------------------------------------------
+void OpenGL2DRenderer::renderFlippedTexturedQuad( const float color[4], 
+                                const float secondaryColor[4],
+                                float x0, float y0,            
+                                float x1, float y1,    
+                                float depth,
+                                float t0s0, float t0t0,  
+                                float t0s1, float t0t1,
+                                float t1s0, float t1t0, 
+                                float t1s1, float t1t1 )
+{
+    //Get States
+    GLboolean cull = glIsEnabled(GL_CULL_FACE);
+    GLboolean fog  = glIsEnabled(GL_FOG);
+
+    //Set States
+    glDisable(GL_CULL_FACE);
+    glDisable(GL_FOG);
+
+    //Set Orthographic Projection
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f);
+
+    //TODO
+    //glViewport(0, glheightOffset, glwidth, glheight);
+    //glDepthRange( 0.0f, 1.0f );
+
+    //Set Color
+    glColor4fv( color );
+
+#ifdef HAVE_GLES
+               GLfloat tex[] = {
+                       t0s0, t0t0,
+                       t0s0, t0t1,
+                       t0s1, t0t1,
+                       t0s1, t0t0
+               };
+               GLfloat tex1[] = {
+                       t1s0, t1t0,
+                       t1s0, t1t1,
+                       t1s1, t1t1,
+                       t1s1, t1t0
+               };
+               GLfloat vtx[] = {
+                       x0, y0, depth,
+                       x1, y0, depth,
+                       x1, y1, depth,
+                       x0, y1, depth
+               };
+               
+               GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
+               if (glcol) glDisableClientState(GL_COLOR_ARRAY);
+               GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);         
+               if (!glvtx)
+                       glEnableClientState(GL_VERTEX_ARRAY);
+               glVertexPointer(3,GL_FLOAT, 0,&vtx);
+/*             glActiveTexture( GL_TEXTURE1 );
+               GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
+               if (gltex1) glDisable(GL_TEXTURE_2D);*/
+               glClientActiveTexture( GL_TEXTURE1 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex1);
+               glClientActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+               // draw
+               glDrawArrays(GL_TRIANGLE_FAN,0,4);
+               // restaure
+               if (glcol) glEnableClientState(GL_COLOR_ARRAY);
+//             if (gltex1) glEnable(GL_TEXTURE_2D);
+               glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
+               glClientActiveTexture( GL_TEXTURE1 );
+               glTexCoordPointer( glsav_tex1_size, glsav_tex1_type, glsav_tex1_stride, glsav_tex1_array );
+               glClientActiveTexture( GL_TEXTURE0 );
+               glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
+#else    //Render Rectangle
+    glBegin(GL_QUADS);
+    {    
+        //Vertex 00
+        glTexCoord2f(t0s0, t0t0);        //00
+        glVertex3f(x0, y0, depth);   
+
+        //Vertex 10
+        glTexCoord2f(t0s0, t0t1);        //01 !
+        glVertex3f(x1, y0, depth);
+
+        //Vertex 11
+        glTexCoord2f(t0s1, t0t1);        //11
+        glVertex3f(x1, y1, depth);
+
+        //Vertex 01
+        glTexCoord2f(t0s1, t0t0);        //10  !
+        glVertex3f(x0, y1, depth);
+    }
+    glEnd();
+#endif
+    //Reset Projection Matrix
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+
+    //Reset States
+    if ( cull ) glEnable(GL_CULL_FACE);
+    if ( fog ) glEnable(GL_FOG);
+
+    //TODO Reset viewport?    
+}
+
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h
new file mode 100755 (executable)
index 0000000..6d37661
--- /dev/null
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef OPEN_GL_2D_RENDERER_H_
+#define OPEN_GL_2D_RENDERER_H_
+
+//Forward declarations
+class VI;
+
+//*****************************************************************************
+//* OpenGL 2D Renderer
+//! Class used to render HUD objects.
+//! @details Renders 2D quads, textured 2D quads and flipped textures 2D quads.
+//*****************************************************************************
+class OpenGL2DRenderer
+{
+public:
+
+    //Initialize
+    bool initialize(VI* vi);
+
+    //Render Quad
+    void renderQuad( const float color[4], 
+                     float x0, float y0, 
+                     float x1, float y1,            
+                     float depth );
+
+
+    //Render Textured Quad
+    void renderTexturedQuad( const float color[4], 
+                             const float secondaryColor[4],
+                             float x0, float y0,            
+                             float x1, float y1,    
+                             float depth,
+                             float t0s0, float t0t0,  
+                             float t0s1, float t0t1,
+                             float t1s0, float t1t0, 
+                             float t1s1, float t1t1 );
+    
+    //Render Flipped Textured Quad
+    void renderFlippedTexturedQuad( const float color[4], 
+                                    const float secondaryColor[4],
+                                    float x0, float y0,            
+                                    float x1, float y1,    
+                                    float depth,
+                                    float t0s0, float t0t0,  
+                                    float t0s1, float t0t1,
+                                    float t1s0, float t1t0, 
+                                    float t1s1, float t1t1 );
+
+
+private:
+
+    VI* m_vi;  //!< Video interface
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp
new file mode 100755 (executable)
index 0000000..9392d95
--- /dev/null
@@ -0,0 +1,531 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2009 Jon Ring
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "m64p.h"
+
+#include <cmath>
+#include <algorithm>
+#include "OpenGLRenderer.h"
+#include "OpenGLManager.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "TextureCache.h"
+#include "VI.h"
+#include "Logger.h"
+//#include "CombinerManager.h"
+#include "AdvancedCombinerManager.h"
+#include "FogManager.h"
+#include "ExtensionChecker.h"
+#include "MultiTexturingExt.h"
+#include "SecondaryColorExt.h"
+
+#ifdef HAVE_GLES
+// save of arrays
+GLint  glsav_col_size;
+GLenum glsav_col_type;
+GLsizei        glsav_col_stride;
+GLvoid*        glsav_col_array;
+
+GLint  glsav_vtx_size;
+GLenum glsav_vtx_type;
+GLsizei        glsav_vtx_stride;
+GLvoid*        glsav_vtx_array;
+
+GLint  glsav_tex_size;
+GLenum glsav_tex_type;
+GLsizei        glsav_tex_stride;
+GLvoid*        glsav_tex_array;
+
+GLint  glsav_tex1_size;
+GLenum glsav_tex1_type;
+GLsizei        glsav_tex1_stride;
+GLvoid*        glsav_tex1_array;
+#endif
+
+using std::max;
+
+#ifndef GL_CLAMP_TO_EDGE
+    #define GL_CLAMP_TO_EDGE  0x812F
+#endif
+
+bool ARB_multitexture = false;
+bool EXT_secondary_color = false;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+OpenGLRenderer::OpenGLRenderer()
+{
+    m_numVertices = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+OpenGLRenderer::~OpenGLRenderer()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Saves pointers and setup render OpenGl pointers to vertex data.
+//-----------------------------------------------------------------------------
+bool OpenGLRenderer::initialize(RSP* rsp, RDP* rdp, TextureCache* textureCache, VI* vi, FogManager* fogMgr)
+{
+    m_rsp          = rsp;
+    m_rdp          = rdp;
+    m_textureCache = textureCache;
+    m_vi           = vi;
+    m_fogMgr       = fogMgr;
+
+    m_numVertices  = 0;
+    m_numTriangles = 0;
+
+    //Init multitexturing
+    ARB_multitexture    = initializeMultiTexturingExtensions();
+    EXT_secondary_color = initializeSecondaryColorExtension();
+
+    //Vertices
+    glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x );
+    glEnableClientState( GL_VERTEX_ARRAY );
+
+    //Colors
+    glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r);
+    glEnableClientState( GL_COLOR_ARRAY );
+
+    //Secondary Color
+    if ( EXT_secondary_color)
+    {
+        glSecondaryColorPointerEXT( 3, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].secondaryColor.r );
+        glEnableClientState( GL_SECONDARY_COLOR_ARRAY_EXT );
+    }
+
+    //Textureing 0
+    glClientActiveTextureARB( GL_TEXTURE0_ARB ); 
+    glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 );
+    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+    //Textureing 1
+    glClientActiveTextureARB( GL_TEXTURE1_ARB );
+    glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 );
+    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+    //Fog
+    m_fogMgr->setFogCoordPointer(GL_FLOAT, sizeof(GLVertex), &m_vertices[0].fog);
+    m_fogMgr->enableFogCoordArray();
+    m_fogMgr->setLinearFog();
+       
+#ifdef HAVE_GLES
+       // save of arrays
+       glsav_col_size = 4;
+       glsav_col_type = GL_FLOAT;
+       glsav_col_stride = sizeof(GLVertex);
+       glsav_col_array = &m_vertices[0].color.r;
+
+       glsav_vtx_size = 4;
+       glsav_vtx_type = GL_FLOAT;
+       glsav_vtx_stride = sizeof(GLVertex);
+       glsav_vtx_array = &m_vertices[0].x;
+
+       glsav_tex_size = 2;
+       glsav_tex_type = GL_FLOAT;
+       glsav_tex_stride = sizeof(GLVertex);
+       glsav_tex_array = &m_vertices[0].s0;
+
+       glsav_tex1_size = 2;
+       glsav_tex1_type = GL_FLOAT;
+       glsav_tex1_stride = sizeof(GLVertex);
+       glsav_tex1_array = &m_vertices[0].s1;
+#endif
+
+
+    return true;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Add triangle
+//-----------------------------------------------------------------------------
+void OpenGLRenderer::addTriangle( SPVertex *vertices, int v0, int v1, int v2 )
+{
+    int v[] = { v0, v1, v2 };
+
+    //Update States
+    m_rdp->updateStates();
+
+    //For each vertex in triangle
+    for (int i=0; i<3; ++i)
+    {
+        //Set Vertex
+        m_vertices[m_numVertices].x = vertices[v[i]].x;
+        m_vertices[m_numVertices].y = vertices[v[i]].y;
+        m_vertices[m_numVertices].z = m_rdp->getDepthSource() == G_ZS_PRIM ? m_rdp->getPrimitiveZ() * vertices[v[i]].w : vertices[v[i]].z; 
+        m_vertices[m_numVertices].w = vertices[v[i]].w;
+
+        //Set Color
+        m_vertices[m_numVertices].color.r = vertices[v[i]].r;
+        m_vertices[m_numVertices].color.g = vertices[v[i]].g;
+        m_vertices[m_numVertices].color.b = vertices[v[i]].b;
+        m_vertices[m_numVertices].color.a = vertices[v[i]].a;
+        m_rdp->getCombinerMgr()->getCombinerColor( &m_vertices[m_numVertices].color.r );
+
+        if ( EXT_secondary_color )
+        {
+            m_vertices[m_numVertices].secondaryColor.r = 0.0f;//lod_fraction; //vertices[v[i]].r;
+            m_vertices[m_numVertices].secondaryColor.g = 0.0f;//lod_fraction; //vertices[v[i]].g;
+            m_vertices[m_numVertices].secondaryColor.b = 0.0f;//lod_fraction; //vertices[v[i]].b;
+            m_vertices[m_numVertices].secondaryColor.a = 1.0f;
+            m_rdp->getCombinerMgr()->getSecondaryCombinerColor( &m_vertices[m_numVertices].secondaryColor.r );
+        }
+
+        //Set Fog
+        if ( OpenGLManager::getSingleton().getFogEnabled()  )
+        {
+            if (vertices[v[i]].z < -vertices[v[i]].w)
+            {
+                m_vertices[m_numVertices].fog = max(0.0f, -m_fogMgr->getMultiplier() + m_fogMgr->getOffset() );
+            }
+            else
+            {
+                m_vertices[m_numVertices].fog = max(0.0f, vertices[v[i]].z / vertices[v[i]].w * m_fogMgr->getMultiplier() + m_fogMgr->getOffset());
+            }
+        }
+
+        //Set TexCoords
+        if ( m_rdp->getCombinerMgr()->getUsesTexture0()  )
+        {
+            RSPTexture& rspTexture      = m_rsp->getTexture();
+            CachedTexture* cacheTexture = m_textureCache->getCurrentTexture(0);
+            RDPTile* rspTile            = m_rsp->getTile(0);            
+            if ( cacheTexture ) 
+            {
+                m_vertices[m_numVertices].s0 = (vertices[v[i]].s * cacheTexture->shiftScaleS * rspTexture.scaleS  - rspTile->fuls + cacheTexture->offsetS) * cacheTexture->scaleS; 
+                m_vertices[m_numVertices].t0 = (vertices[v[i]].t * cacheTexture->shiftScaleT * rspTexture.scaleT  - rspTile->fult + cacheTexture->offsetT) * cacheTexture->scaleT;
+            }
+            else
+            {
+                m_vertices[m_numVertices].s0 = (vertices[v[i]].s * rspTexture.scaleS  - rspTile->fuls ); 
+                m_vertices[m_numVertices].t0 = (vertices[v[i]].t * rspTexture.scaleT  - rspTile->fult );
+            }            
+        }
+
+        if ( m_rdp->getCombinerMgr()->getUsesTexture1() )
+        {
+            RSPTexture& rspTexture      = m_rsp->getTexture();
+            CachedTexture* cache = m_textureCache->getCurrentTexture(1);
+            RDPTile* rspTile            = m_rsp->getTile(1);    
+            if ( cache && rspTile ) 
+            {
+                m_vertices[m_numVertices].s1 = (vertices[v[i]].s * cache->shiftScaleS * rspTexture.scaleS - rspTile->fuls + cache->offsetS) * cache->scaleS; 
+                m_vertices[m_numVertices].t1 = (vertices[v[i]].t * cache->shiftScaleT * rspTexture.scaleT - rspTile->fult + cache->offsetT) * cache->scaleT;    
+            }
+        }
+
+        m_numVertices++;
+    }
+    m_numTriangles++;
+
+    if ( m_numVertices >= 255 ) 
+    {    
+        
+        Logger::getSingleton().printMsg("RENDER VERTICES!!! :)", M64MSG_ERROR);
+        OpenGLRenderer::getSingleton().render();
+    }    
+}
+
+//-----------------------------------------------------------------------------
+// Render
+//-----------------------------------------------------------------------------
+void OpenGLRenderer::render()
+{        
+    glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
+    m_numTriangles = m_numVertices = 0;  
+}
+
+//-----------------------------------------------------------------------------
+// Render Texture Rectangle
+//-----------------------------------------------------------------------------
+void OpenGLRenderer::renderTexRect( float ulx, float uly,   //Upper left vertex
+                                    float lrx, float lry,   //Lower right vertex
+                                    float uls, float ult,   //Upper left texcoord
+                                    float lrs, float lrt,   //Lower right texcoord 
+                                    bool flip)              //Flip
+{
+    //Initialize first vertex (upper left vertex)
+    GLVertex rect[2];
+    rect[0].x = ulx;
+    rect[0].y = uly;
+    rect[0].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f;   //FIXME: Use viewport.nearz?
+    rect[0].w = 1.0f;
+    rect[0].color.r = 1.0f;   
+    rect[0].color.g = 1.0f;
+    rect[0].color.b = 1.0f;
+    rect[0].color.a = 0.0f;
+    rect[0].secondaryColor.r = 1.0f;   
+    rect[0].secondaryColor.g = 1.0f;
+    rect[0].secondaryColor.b = 1.0f;
+    rect[0].secondaryColor.a = 1.0f;
+    rect[0].s0 = uls;
+    rect[0].t0 = ult;
+    rect[0].s1 = uls;
+    rect[0].t1 = ult;
+    rect[0].fog = 0.0f;
+
+    //Initialize second vertex (lower right vertex)
+    rect[1].x = lrx;
+    rect[1].y = lry;
+    rect[1].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f;   //FIXME: Use viewport.nearz? 
+    rect[1].w = 1.0f;
+    rect[1].color.r = 1.0f;   
+    rect[1].color.g = 1.0f;
+    rect[1].color.b = 1.0f;
+    rect[1].color.a = 0.0f;
+    rect[1].secondaryColor.r = 1.0f;   
+    rect[1].secondaryColor.g = 1.0f;
+    rect[1].secondaryColor.b = 1.0f;
+    rect[1].secondaryColor.a = 1.0f;
+    rect[1].s0 = lrs;
+    rect[1].t0 = lrt;
+    rect[1].s1 = lrs;
+    rect[1].t1 = lrt;
+    rect[1].fog = 0.0f;
+
+    glDisable( GL_CULL_FACE );
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity();
+
+    //glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f );
+    glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f );
+    //glOrtho( 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight(), 0, 1.0f, -1.0f );
+    //glViewport( 0, 0, m_vi->getWidth(), m_vi->getHeight() );
+    //glViewport( 0, 0, 320, 240 );
+    //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight());
+
+    if ( m_rdp->getCombinerMgr()->getUsesTexture0() )
+    {
+        rect[0].s0 = rect[0].s0 * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls;
+        rect[0].t0 = rect[0].t0 * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult;
+        rect[1].s0 = (rect[1].s0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls;
+        rect[1].t0 = (rect[1].t0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult;
+
+        if ((m_textureCache->getCurrentTexture(0)->maskS) && (fmod( rect[0].s0, m_textureCache->getCurrentTexture(0)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorS))
+        {
+            rect[1].s0 -= rect[0].s0;
+            rect[0].s0 = 0.0f;
+        }
+
+        if ((m_textureCache->getCurrentTexture(0)->maskT) && (fmod( rect[0].t0, m_textureCache->getCurrentTexture(0)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorT))
+        {
+            rect[1].t0 -= rect[0].t0;
+            rect[0].t0 = 0.0f;
+        }
+//
+//        if (OGL.ARB_multitexture)
+            glActiveTextureARB( GL_TEXTURE0_ARB );
+//
+        if ((rect[0].s0 >= 0.0f) && (rect[1].s0 <= m_textureCache->getCurrentTexture(0)->width))
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+
+        if ((rect[0].t0 >= 0.0f) && (rect[1].t0 <= m_textureCache->getCurrentTexture(0)->height))
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+
+//
+        rect[0].s0 *= m_textureCache->getCurrentTexture(0)->scaleS;
+        rect[0].t0 *= m_textureCache->getCurrentTexture(0)->scaleT;
+        rect[1].s0 *= m_textureCache->getCurrentTexture(0)->scaleS;
+        rect[1].t0 *= m_textureCache->getCurrentTexture(0)->scaleT;
+    }
+
+    if ( m_rdp->getCombinerMgr()->getUsesTexture1() )
+    {
+        rect[0].s1 = rect[0].s1 * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls;
+        rect[0].t1 = rect[0].t1 * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult;
+        rect[1].s1 = (rect[1].s1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls;
+        rect[1].t1 = (rect[1].t1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult;
+
+        if ((m_textureCache->getCurrentTexture(1)->maskS) && (fmod( rect[0].s1, m_textureCache->getCurrentTexture(1)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorS))
+        {
+            rect[1].s1 -= rect[0].s1;
+            rect[0].s1 = 0.0f;
+        }
+
+        if ((m_textureCache->getCurrentTexture(1)->maskT) && (fmod( rect[0].t1, m_textureCache->getCurrentTexture(1)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorT))
+        {
+            rect[1].t1 -= rect[0].t1;
+            rect[0].t1 = 0.0f;
+        }
+
+        glActiveTextureARB( GL_TEXTURE1_ARB );
+
+        if ((rect[0].s1 == 0.0f) && (rect[1].s1 <= m_textureCache->getCurrentTexture(1)->width))
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+
+        if ((rect[0].t1 == 0.0f) && (rect[1].t1 <= m_textureCache->getCurrentTexture(1)->height))
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+
+        rect[0].s1 *= m_textureCache->getCurrentTexture(1)->scaleS;
+        rect[0].t1 *= m_textureCache->getCurrentTexture(1)->scaleT;
+        rect[1].s1 *= m_textureCache->getCurrentTexture(1)->scaleS;
+        rect[1].t1 *= m_textureCache->getCurrentTexture(1)->scaleT;
+    }
+
+
+    if ( m_rdp->m_otherMode.cycleType == G_CYC_COPY ) /*&& !OGL.forceBilinear  )*/
+    {
+        //if (OGL.ARB_multitexture)
+        glActiveTextureARB( GL_TEXTURE0_ARB );
+
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+    }
+
+//    SetConstant( rect[0].color, combiner.vertex.color, combiner.vertex.alpha );
+    //rdp.updateStates();
+    m_rdp->getCombinerMgr()->getCombinerColor(&rect[0].color.r);
+
+    //if (OGL.EXT_secondary_color)
+    m_rdp->getCombinerMgr()->getSecondaryCombinerColor(&rect[0].secondaryColor.r);
+    //    SetConstant( rect[0].secondaryColor, combiner.vertex.secondaryColor, combiner.vertex.alpha );
+
+#ifdef HAVE_GLES
+       GLfloat col[] = {
+               rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a,
+               rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a,
+               rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a,
+               rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a
+       };
+       
+       GLfloat tex[] = {
+               rect[0].s0, rect[0].t0,
+               rect[1].s0, rect[0].t0,
+               rect[1].s0, rect[1].t0,
+               rect[0].s0, rect[1].t0
+       };
+       GLfloat tex1[] = {
+               rect[0].s1, rect[0].t1,
+               rect[1].s1, rect[0].t1,
+               rect[1].s1, rect[1].t1,
+               rect[0].s1, rect[1].t1
+       };
+       
+       GLfloat vtx[] = {
+               rect[0].x, rect[0].y, rect[0].z, 1.0f,
+               rect[1].x, rect[0].y, rect[0].z, 1.0f,
+               rect[1].x, rect[1].y, rect[0].z, 1.0f,
+               rect[0].x, rect[1].y, rect[0].z, 1.0f
+       };
+       // Setup pointer array
+    glColorPointer(4, GL_FLOAT, 0, &col );
+    glVertexPointer(4,GL_FLOAT, 0,&vtx);
+    glClientActiveTexture( GL_TEXTURE1 );
+    glTexCoordPointer(2, GL_FLOAT, 0, &tex1);
+    glClientActiveTexture( GL_TEXTURE0 );
+    glTexCoordPointer(2, GL_FLOAT, 0, &tex);
+       // Draw
+    glDrawArrays(GL_TRIANGLE_FAN,0,4);
+       // Restaure default pointer
+    glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x );
+    glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r);
+    glClientActiveTexture( GL_TEXTURE1 );
+    glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 );
+    glClientActiveTexture( GL_TEXTURE0 ); 
+    glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 );
+#else
+    glBegin( GL_QUADS );
+
+        glColor4f( rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a );
+
+        //if (OGL.EXT_secondary_color)
+            glSecondaryColor3fEXT( rect[0].secondaryColor.r, rect[0].secondaryColor.g, rect[0].secondaryColor.b );
+
+        //if (OGL.ARB_multitexture)
+        //{
+        //    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[0].t0 );
+        //    glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[0].t1 );
+        //    glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f );
+
+        //    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[0].t0 );
+        //    glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[0].t1 );
+        //    glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f );
+
+        //    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[1].t0 );
+        //    glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[1].t1 );
+        //    glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f );
+
+        //    glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[1].t0 );
+        //    glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[1].t1 );
+        //    glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f );
+        //}
+//        else
+        {
+
+            /*
+            Logger::getSingleton() << "\n\nTexRect x0=" << rect[0].x << " y0=" << rect[0].y << 
+                                                 " x1=" << rect[1].x <<  "y1=" << rect[1].y <<
+                                                    " t0u0=" << rect[0].s0 << " t0v0=" << rect[0].t0 << 
+                                                 " t0u1=" << rect[1].s0 << " t0v1=" << rect[1].t0 << "\n";
+            */
+            glTexCoord2f(rect[0].s0, rect[0].t0 );
+            //glTexCoord2f(rect[0].s1, rect[0].t1 );
+            glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f );
+
+            glTexCoord2f(rect[1].s0, rect[0].t0 );
+            //glTexCoord2f(rect[1].s1, rect[0].t1 );
+            glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f );
+
+            glTexCoord2f(rect[1].s0, rect[1].t0 );
+            //glTexCoord2f(rect[1].s1, rect[1].t1 );
+            glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f );
+
+            glTexCoord2f(rect[0].s0, rect[1].t0 );
+            //glTexCoord2f(rect[0].s1, rect[1].t1 );
+            glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f );
+
+
+
+    /*        glTexCoord2f( rect[0].s0, rect[0].t0 );
+            glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f );
+
+            if (flip)
+                glTexCoord2f( rect[1].s0, rect[0].t0 );
+            else
+                glTexCoord2f( rect[0].s0, rect[1].t0 );
+
+            glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f );
+
+            glTexCoord2f( rect[1].s0, rect[1].t0 );
+            glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f );
+
+            if (flip)
+                glTexCoord2f( rect[1].s0, rect[0].t0 );
+            else
+                glTexCoord2f( rect[1].s0, rect[0].t0 );
+            glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f );*/
+        }
+    glEnd();
+#endif
+    glLoadIdentity();
+    //OGL_UpdateCullFace();
+    //OGL_UpdateViewport();
+}
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h
new file mode 100755 (executable)
index 0000000..b5082ae
--- /dev/null
@@ -0,0 +1,112 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef OPEN_GL_RENDERER_H_
+#define OPEN_GL_RENDERER_H_
+
+#include "m64p.h"
+#include "OpenGL.h"
+
+//Forward Declarations
+struct SPVertex;
+class RSP;
+class RDP;
+class TextureCache;
+class VI;
+class FogManager;
+
+#include "MultiTexturingExt.h"
+
+
+//*****************************************************************************
+//* OpenGL Vertex
+//! Used in vertex buffer by OpenGLRenderer.
+//*****************************************************************************
+struct GLVertex
+{
+    float x, y, z, w;          //!< Vertex position
+    struct
+    {
+        float r, g, b, a;
+    } color, secondaryColor;   //!< Color and secondary color
+    float s0, t0, s1, t1;      //!< Texture coordinats
+    float fog;                 //!< Vertex fog variable
+};
+
+//*****************************************************************************
+//* OpenGL Renderer
+//! Class for rendering using OpenGL
+//*****************************************************************************
+class OpenGLRenderer
+{
+public:
+
+    //Get Singleton Instance
+    static OpenGLRenderer& getSingleton()
+    {
+        static OpenGLRenderer instance;
+        return instance;
+    }
+
+    //Destructor
+    ~OpenGLRenderer();
+
+    //Initialize
+    bool initialize(RSP* rsp, RDP* rdp, TextureCache* textureCache, VI* vi, FogManager* fogMgr);
+
+    //Flush Vertex buffer
+    void render();
+
+    //Add triangle
+    void addTriangle( SPVertex *vertices, int v0, int v1, int v2 );
+
+    //Get number of vertices
+    int getNumVertices() { return m_numVertices; }
+
+    //Render Tex Rect
+    void renderTexRect( float ulx, float uly,   //Upper left vertex
+                        float lrx, float lry,   //Lower right vertex
+                        float uls, float ult,   //Upper left texcoord
+                        float lrs, float lrt,   //Lower right texcoord 
+                        bool flip);             //Flip  
+    
+private:
+
+    //Constructor
+    OpenGLRenderer();
+
+private:
+
+    GLVertex m_vertices[256];              //!< Vertex buffer
+    unsigned char m_triangles[300][3];     //!< Triangles used to index vertices
+
+    int m_numVertices;                     //!< Number of vertices in vertex buffer
+    int m_numTriangles;                    //!< Number of triangles
+
+    RSP* m_rsp;                            //!< Pointer to Reality Signal Processor
+    RDP* m_rdp;                            //!< Pointer to Reality Drawing Processor
+    VI* m_vi;                              //!< Pointer to Video Interface
+    TextureCache* m_textureCache;          //!< Pointer to texture cache
+    FogManager* m_fogMgr;                  //!< Pointer to Fog Manager used to render fog. 
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/eglport.c b/source/mupen64plus-video-arachnoid/src/renderer/eglport.c
new file mode 100755 (executable)
index 0000000..9db7809
--- /dev/null
@@ -0,0 +1,706 @@
+/**
+ *
+ *  EGLPORT.C
+ *  Copyright (C) 2011-2013 Scott R. Smith
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ */
+
+#include "eglport.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define USE_EGL_SDL 1
+#define USE_GLES1      1
+
+#if defined(USE_EGL_SDL)
+#include "SDL.h"
+#include "SDL_syswm.h"
+SDL_SysWMinfo sysWmInfo;      /** Holds our X Display/Window information */
+#endif /* USE_EGL_SDL */
+
+#if defined(PANDORA) /* Pandora VSync Support */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#endif
+int fbdev = -1;
+
+#elif defined(RPI)
+#include "bcm_host.h"
+#endif /* PANDORA */
+
+enum EGL_RENDER_T {
+    RENDER_RAW=0,           /** Sets render mode to raw or framebuffer mode. */
+    RENDER_SDL,             /** Sets render mode to X11/SDL mode. */
+    RENDER_TOTAL
+};
+
+enum EGL_SETTINGS_T {
+    CFG_MODE=0,             /** Render mode for EGL 0=RAW 1=SDL. */
+    CFG_VSYNC,              /** Controls system vsync if available. */
+    CFG_FSAA,               /** Number of samples for full screen AA. 0 is off, 2/4 samples. */
+    CFG_FPS,                /** Calculate and report frame per second. */
+    CFG_RED_SIZE,           /** Number of bits of Red in the color buffer. */
+    CFG_GREEN_SIZE,         /** Number of bits of Green in the color buffer. */
+    CFG_BLUE_SIZE,          /** Number of bits of Blue in the color buffer. */
+    CFG_ALPHA_SIZE,         /** Number of bits of Alpha in the color buffer. */
+    CFG_DEPTH_SIZE,         /** Number of bits of Z in the depth buffer. */
+    CFG_BUFFER_SIZE,        /** The total color component bits in the color buffer. */
+    CFG_STENCIL_SIZE,       /** Number of bits of Stencil in the stencil buffer. */
+    CFG_TOTAL               /** Total number of settings. */
+};
+
+NativeDisplayType   nativeDisplay = 0;      /** Reference to the systems native display */
+NativeWindowType    nativeWindow  = 0;      /** Reference to the systems native window */
+EGLint              eglSettings[CFG_TOTAL]; /** Stores setting values. */
+EGLDisplay          eglDisplay    = NULL;   /** Reference to the EGL display */
+EGLConfig           eglConfig     = NULL;   /** Reference to the EGL config */
+EGLContext          eglContext    = NULL;   /** Reference to the EGL context */
+EGLSurface          eglSurface    = NULL;   /** Reference to the EGL surface */
+
+#define     totalConfigsIn 5                /** Total number of configurations to request */
+EGLint      totalConfigsFound = 0;          /** Total number of configurations matching attributes */
+EGLConfig   eglConfigs[totalConfigsIn];     /** Structure containing references to matching configurations */
+
+uint32_t    fpsCount    = 0;                /** Total number of frames counted */
+uint32_t    fpsTime     = 0;                /** Start time of frame count measurment */
+
+int8_t eglColorbits    = 0;
+int8_t eglDepthbits    = 0;
+int8_t eglStencilbits  = 0;
+
+
+/** Private API */
+void        OpenCfg                 ( const char* file );
+int8_t      ConfigureEGL            ( EGLConfig config );
+int8_t      FindEGLConfigs          ( void );
+int8_t      CheckEGLErrors          ( const char* file, uint16_t line );
+
+int8_t      GetNativeDisplay        ( void );
+int8_t      GetNativeWindow         ( uint16_t width, uint16_t height );
+void        FreeNativeDisplay       ( void );
+void        FreeNativeWindow        ( void );
+
+void        Platform_Open           ( void );
+void        Platform_Close          ( void );
+void        Platform_VSync          ( void );
+uint32_t    Platform_GetTicks       ( void );
+
+/** @brief Release all EGL and system resources
+ */
+void EGL_Close( void )
+{
+    /* Release EGL resources */
+    if (eglDisplay != NULL)
+    {
+        peglMakeCurrent( eglDisplay, NULL, NULL, EGL_NO_CONTEXT );
+        if (eglContext != NULL) {
+            peglDestroyContext( eglDisplay, eglContext );
+        }
+        if (eglSurface != NULL) {
+            peglDestroySurface( eglDisplay, eglSurface );
+        }
+        peglTerminate( eglDisplay );
+    }
+
+    eglSurface = NULL;
+    eglContext = NULL;
+    eglDisplay = NULL;
+       
+       eglColorbits = 0;
+       eglDepthbits = 0;
+       eglStencilbits = 0;
+
+    /* Release platform resources */
+    FreeNativeWindow();
+    FreeNativeDisplay();
+    Platform_Close();
+
+    CheckEGLErrors( __FILE__, __LINE__ );
+
+    printf( "EGLport: Closed\n" );
+}
+
+/** @brief Swap the surface buffer onto the display
+ */
+void EGL_SwapBuffers( void )
+{
+    if (eglSettings[CFG_VSYNC] != 0) {
+        Platform_VSync();
+    }
+
+    peglSwapBuffers( eglDisplay, eglSurface );
+
+    if (eglSettings[CFG_FPS] != 0) {
+        fpsCount++;
+
+        if (fpsTime - Platform_GetTicks() >= 1000)
+        {
+            printf( "EGLport: %d fps\n", fpsCount );
+            fpsTime = Platform_GetTicks();
+            fpsCount = 0;
+        }
+    }
+}
+
+/** @brief Obtain the system display and initialize EGL
+ * @param width : desired pixel width of the window (not used by all platforms)
+ * @param height : desired pixel height of the window (not used by all platforms)
+ * @return : 0 if the function passed, else 1
+ */
+int8_t EGL_Open( uint16_t width, uint16_t height )
+{
+    EGLint eglMajorVer, eglMinorVer;
+    EGLBoolean result;
+    uint32_t configIndex = 0;
+    const char* output;
+
+    static const EGLint contextAttribs[] =
+    {
+#if defined(USE_GLES2)
+          EGL_CONTEXT_CLIENT_VERSION,     2,
+#endif
+          EGL_NONE
+    };
+
+#if defined(DEBUG)
+    printf( "EGLport Warning: DEBUG is enabled which may effect performance\n" );
+#endif
+
+    /* Check that system is not open */
+    if (eglDisplay != NULL || eglContext != NULL || eglSurface != NULL)
+    {
+        printf( "EGLport ERROR: EGL system is already open!\n" );
+        return 1;
+    }
+
+    /* Check for the cfg file to alternative settings */
+    OpenCfg( "eglport.cfg" );
+
+    /* Setup any platform specific bits */
+    Platform_Open();
+
+    printf( "EGLport: Opening EGL display\n" );
+    if (GetNativeDisplay() != 0)
+    {
+        printf( "EGLport ERROR: Unable to obtain native display!\n" );
+        return 1;
+    }
+
+    eglDisplay = peglGetDisplay( nativeDisplay );
+    if (eglDisplay == EGL_NO_DISPLAY)
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to create EGL display.\n" );
+        return 1;
+    }
+
+    printf( "EGLport: Initializing\n" );
+    result = peglInitialize( eglDisplay, &eglMajorVer, &eglMinorVer );
+    if (result != EGL_TRUE )
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to initialize EGL display.\n" );
+        return 1;
+    }
+
+    /* Get EGL Library Information */
+    printf( "EGL Implementation Version: Major %d Minor %d\n", eglMajorVer, eglMinorVer );
+    output = peglQueryString( eglDisplay, EGL_VENDOR );
+    printf( "EGL_VENDOR: %s\n", output );
+    output = peglQueryString( eglDisplay, EGL_VERSION );
+    printf( "EGL_VERSION: %s\n", output );
+    output = peglQueryString( eglDisplay, EGL_EXTENSIONS );
+    printf( "EGL_EXTENSIONS: %s\n", output );
+
+    if (FindEGLConfigs() != 0)
+    {
+        printf( "EGLport ERROR: Unable to configure EGL. See previous error.\n" );
+        return 1;
+    }
+
+    printf( "EGLport: Using Config %d\n", configIndex );
+#if defined(EGL_VERSION_1_2)
+    /* Bind GLES and create the context */
+    printf( "EGLport: Binding API\n" );
+    result = peglBindAPI( EGL_OPENGL_ES_API );
+    if ( result == EGL_FALSE )
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Could not bind EGL API.\n" );
+        return 1;
+    }
+#endif /* EGL_VERSION_1_2 */
+
+    printf( "EGLport: Creating Context\n" );
+    eglContext = peglCreateContext( eglDisplay, eglConfigs[configIndex], NULL, contextAttribs );
+    if (eglContext == EGL_NO_CONTEXT)
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to create GLES context!\n");
+        return 1;
+    }
+
+    printf( "EGLport: Creating window surface\n" );
+    if (GetNativeWindow( width, height ) != 0)
+    {
+        printf( "EGLport ERROR: Unable to obtain native window!\n" );
+        return 1;
+    }
+
+    eglSurface = peglCreateWindowSurface( eglDisplay, eglConfigs[configIndex], nativeWindow, 0 );
+    if (eglSurface == EGL_NO_SURFACE)
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to create EGL surface!\n" );
+        return 1;
+    }
+
+    printf( "EGLport: Making Current\n" );
+    result = peglMakeCurrent( eglDisplay,  eglSurface,  eglSurface, eglContext );
+    if (result != EGL_TRUE)
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to make GLES context current\n" );
+        return 1;
+    }
+
+       {
+         EGLint color, depth, stencil;
+         eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_BUFFER_SIZE, &color);
+         eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_DEPTH_SIZE, &depth);
+         eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_STENCIL_SIZE, &stencil);
+         eglColorbits = (color==16)?5:8; //quick hack
+         eglDepthbits = depth;
+         eglStencilbits = stencil;
+       }
+
+    printf( "EGLport: Setting swap interval\n" );
+    peglSwapInterval( eglDisplay, (eglSettings[CFG_VSYNC] > 0) ? 1 : 0 );
+
+    printf( "EGLport: Complete\n" );
+
+    CheckEGLErrors( __FILE__, __LINE__ );
+       
+    return 0;
+}
+
+/** @brief Read settings that configure how to use EGL
+ * @param file : name of the config file
+ */
+void OpenCfg ( const char* file )
+{
+    #define MAX_STRING 20
+    #define MAX_SIZE 100
+    uint8_t i;
+    FILE* fp = NULL;
+    char* location = NULL;
+    char eglStrings[CFG_TOTAL][MAX_STRING];
+    char buffer[MAX_SIZE];
+
+    strncpy( eglStrings[CFG_MODE], "egl_mode=", MAX_STRING );
+    strncpy( eglStrings[CFG_VSYNC], "use_vsync=", MAX_STRING );
+    strncpy( eglStrings[CFG_FSAA], "use_fsaa=", MAX_STRING );
+    strncpy( eglStrings[CFG_RED_SIZE], "size_red=", MAX_STRING );
+    strncpy( eglStrings[CFG_GREEN_SIZE], "size_green=", MAX_STRING );
+    strncpy( eglStrings[CFG_BLUE_SIZE], "size_blue=", MAX_STRING );
+    strncpy( eglStrings[CFG_ALPHA_SIZE], "size_alpha=", MAX_STRING );
+    strncpy( eglStrings[CFG_DEPTH_SIZE], "size_depth=", MAX_STRING );
+    strncpy( eglStrings[CFG_BUFFER_SIZE], "size_buffer=", MAX_STRING );
+    strncpy( eglStrings[CFG_STENCIL_SIZE], "size_stencil=", MAX_STRING );
+
+    /* Set defaults */
+#if defined(USE_EGL_SDL)
+    eglSettings[CFG_MODE]           = RENDER_SDL;
+#else
+    eglSettings[CFG_MODE]           = RENDER_RAW;
+#endif
+    eglSettings[CFG_VSYNC]          = 0;
+    eglSettings[CFG_FSAA]           = 0;
+    eglSettings[CFG_FPS]            = 0;
+    eglSettings[CFG_RED_SIZE]       = 5;
+    eglSettings[CFG_GREEN_SIZE]     = 6;
+    eglSettings[CFG_BLUE_SIZE]      = 5;
+    eglSettings[CFG_ALPHA_SIZE]     = 0;
+    eglSettings[CFG_DEPTH_SIZE]     = 16;
+    eglSettings[CFG_BUFFER_SIZE]    = 16;
+    eglSettings[CFG_STENCIL_SIZE]   = 0;
+
+    /* Parse INI file */
+    fp = fopen( file, "r");
+    if (fp != NULL)
+    {
+        while (fgets( buffer, MAX_SIZE, fp ) != NULL)
+        {
+            for (i=0; i<CFG_TOTAL; i++)
+            {
+                location = strstr( buffer, eglStrings[i] );
+                if (location != NULL)
+                {
+                    eglSettings[i] = atol( location+strlen( eglStrings[i] ) );
+                    printf( "EGLport: %s set to %d.\n", eglStrings[i], eglSettings[i] );
+                    break;
+                }
+            }
+        }
+
+        fclose( fp );
+    }
+    else
+    {
+        printf( "EGL ERROR: Unable to read ini settings from file '%s'. Using defaults\n", file );
+    }
+}
+
+/** @brief Find a EGL configuration tht matches the defined attributes
+ * @return : 0 if the function passed, else 1
+ */
+int8_t FindEGLConfigs( void )
+{
+    EGLBoolean result;
+    int attrib = 0;
+    EGLint ConfigAttribs[23];
+
+    ConfigAttribs[attrib++] = EGL_RED_SIZE;                         /* 1 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_RED_SIZE];            /* 2 */
+    ConfigAttribs[attrib++] = EGL_GREEN_SIZE;                       /* 3 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_GREEN_SIZE];          /* 4 */
+    ConfigAttribs[attrib++] = EGL_BLUE_SIZE;                        /* 5 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_BLUE_SIZE];           /* 6 */
+    ConfigAttribs[attrib++] = EGL_ALPHA_SIZE;                       /* 7 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_ALPHA_SIZE];          /* 8 */
+    ConfigAttribs[attrib++] = EGL_DEPTH_SIZE;                       /* 9 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_DEPTH_SIZE];          /* 10 */
+    ConfigAttribs[attrib++] = EGL_BUFFER_SIZE;                      /* 11 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_BUFFER_SIZE];         /* 12 */
+    ConfigAttribs[attrib++] = EGL_STENCIL_SIZE;                     /* 13 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_STENCIL_SIZE];        /* 14 */
+    ConfigAttribs[attrib++] = EGL_SURFACE_TYPE;                     /* 15 */
+    ConfigAttribs[attrib++] = EGL_WINDOW_BIT;                       /* 16 */
+#if defined(EGL_VERSION_1_2)
+    ConfigAttribs[attrib++] = EGL_RENDERABLE_TYPE;                  /* 17 */
+#if defined(USE_GLES1)
+    ConfigAttribs[attrib++] = EGL_OPENGL_ES_BIT;
+#elif defined(USE_GLES2)
+    ConfigAttribs[attrib++] = EGL_OPENGL_ES2_BIT;                   /* 18 */
+#endif /* USE_GLES1 */
+#endif /* EGL_VERSION_1_2 */
+    ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS;                   /* 19 */
+    ConfigAttribs[attrib++] = (eglSettings[CFG_FSAA] > 0) ? 1 : 0;  /* 20 */
+    ConfigAttribs[attrib++] = EGL_SAMPLES;                          /* 21 */
+    ConfigAttribs[attrib++] = eglSettings[CFG_FSAA];                /* 22 */
+    ConfigAttribs[attrib++] = EGL_NONE;                             /* 23 */
+
+    result = peglChooseConfig( eglDisplay, ConfigAttribs, eglConfigs, totalConfigsIn, &totalConfigsFound );
+    if (result != EGL_TRUE || totalConfigsFound == 0)
+    {
+        CheckEGLErrors( __FILE__, __LINE__ );
+        printf( "EGLport ERROR: Unable to query for available configs, found %d.\n", totalConfigsFound );
+        return 1;
+    }
+    printf( "EGLport: Found %d available configs\n", totalConfigsFound );
+
+    return 0;
+}
+
+/** @brief Error checking function
+ * @param file : string reference that contains the source file that the check is occuring in
+ * @param line : numeric reference that contains the line number that the check is occuring in
+ * @return : 0 if the function passed, else 1
+ */
+int8_t CheckEGLErrors( const char* file, uint16_t line )
+{
+    EGLenum error;
+    const char* errortext;
+    const char* description;
+
+    error = eglGetError();
+
+    if (error != EGL_SUCCESS && error != 0)
+    {
+        switch (error)
+        {
+            case EGL_NOT_INITIALIZED:
+                errortext   = "EGL_NOT_INITIALIZED.";
+                description = "EGL is not or could not be initialized, for the specified display.";
+                break;
+            case EGL_BAD_ACCESS:
+                errortext   = "EGL_BAD_ACCESS EGL";
+                description = "cannot access a requested resource (for example, a context is bound in another thread).";
+                break;
+            case EGL_BAD_ALLOC:
+                errortext   = "EGL_BAD_ALLOC EGL";
+                description = "failed to allocate resources for the requested operation.";
+                break;
+            case EGL_BAD_ATTRIBUTE:
+                errortext   = "EGL_BAD_ATTRIBUTE";
+                description = "An unrecognized attribute or attribute value was passed in anattribute list.";
+                break;
+            case EGL_BAD_CONFIG:
+                errortext   = "EGL_BAD_CONFIG";
+                description = "An EGLConfig argument does not name a valid EGLConfig.";
+                break;
+            case EGL_BAD_CONTEXT:
+                errortext   = "EGL_BAD_CONTEXT";
+                description = "An EGLContext argument does not name a valid EGLContext.";
+                break;
+            case EGL_BAD_CURRENT_SURFACE:
+                errortext   = "EGL_BAD_CURRENT_SURFACE";
+                description = "The current surface of the calling thread is a window, pbuffer,or pixmap that is no longer valid.";
+                break;
+            case EGL_BAD_DISPLAY:
+                errortext   = "EGL_BAD_DISPLAY";
+                description = "An EGLDisplay argument does not name a valid EGLDisplay.";
+                break;
+            case EGL_BAD_MATCH:
+                errortext   = "EGL_BAD_MATCH";
+                description = "Arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.";
+                break;
+            case EGL_BAD_NATIVE_PIXMAP:
+                errortext   = "EGL_BAD_NATIVE_PIXMAP";
+                description = "An EGLNativePixmapType argument does not refer to a validnative pixmap.";
+                break;
+            case EGL_BAD_NATIVE_WINDOW:
+                errortext   = "EGL_BAD_NATIVE_WINDOW";
+                description = "An EGLNativeWindowType argument does not refer to a validnative window.";
+                break;
+            case EGL_BAD_PARAMETER:
+                errortext   = "EGL_BAD_PARAMETER";
+                description = "One or more argument values are invalid.";
+                break;
+            case EGL_BAD_SURFACE:
+                errortext   = "EGL_BAD_SURFACE";
+                description = "An EGLSurface argument does not name a valid surface (window,pbuffer, or pixmap) configured for rendering";
+                break;
+            case EGL_CONTEXT_LOST:
+                errortext   = "EGL_CONTEXT_LOST";
+                description = "A power management event has occurred. The application mustdestroy all contexts and reinitialise client API state and objects to continue rendering.";
+                break;
+            default:
+                errortext   = "Unknown EGL Error";
+                description = "";
+                break;
+        }
+
+        printf( "EGLport ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n  Description: %s\n", file, line, errortext, error, description );
+        return 1;
+    }
+
+    return 0;
+}
+
+/** @brief Obtain a reference to the system's native display
+ * @param window : pointer to save the display reference
+ * @return : 0 if the function passed, else 1
+ */
+int8_t GetNativeDisplay( void )
+{
+    if (eglSettings[CFG_MODE] == RENDER_RAW)        /* RAW FB mode */
+    {
+        printf( "EGLport: Using EGL_DEFAULT_DISPLAY\n" );
+        nativeDisplay = EGL_DEFAULT_DISPLAY;
+    }
+    else if (eglSettings[CFG_MODE] == RENDER_SDL)   /* SDL/X11 mode */
+    {
+#if defined(USE_EGL_SDL)
+        printf( "EGLport: Opening SDL/X11 display\n" );
+        SDL_VERSION(&sysWmInfo.version);
+        SDL_GetWMInfo(&sysWmInfo);
+        nativeDisplay = (EGLNativeDisplayType)sysWmInfo.info.x11.display;
+
+        if (nativeDisplay == 0)
+        {
+            printf( "EGLport ERROR: unable to get display!\n" );
+            return 1;
+        }
+#else
+        printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
+#endif
+    }
+
+    return 0;
+}
+
+/** @brief Obtain a reference to the system's native window
+ * @param width : desired pixel width of the window (not used by all platforms)
+ * @param height : desired pixel height of the window (not used by all platforms)
+ * @return : 0 if the function passed, else 1
+ */
+int8_t GetNativeWindow( uint16_t width, uint16_t height )
+{
+    nativeWindow = 0;
+
+#if defined(WIZ) || defined(CAANOO)
+
+    nativeWindow = (NativeWindowType)malloc(16*1024);
+
+    if(nativeWindow == NULL) {
+        printf( "EGLport ERROR: Memory for window Failed\n" );
+        return 1;
+    }
+
+#elif defined(RPI)
+
+    EGLBoolean result;
+    uint32_t screen_width, screen_height;
+    static EGL_DISPMANX_WINDOW_T nativewindow;
+    DISPMANX_ELEMENT_HANDLE_T dispman_element;
+    DISPMANX_DISPLAY_HANDLE_T dispman_display;
+    DISPMANX_UPDATE_HANDLE_T dispman_update;
+    VC_RECT_T dst_rect;
+    VC_RECT_T src_rect;
+
+    /* create an EGL window surface */
+    result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
+    if(result < 0) {
+        printf( "EGLport ERROR: RPi graphicget_display_size failed\n" );
+        return 1;
+    }
+
+    dst_rect.x = 0;
+    dst_rect.y = 0;
+    dst_rect.width = screen_width;
+    dst_rect.height = screen_height;
+
+    src_rect.x = 0;
+    src_rect.y = 0;
+    src_rect.width = width << 16;
+    src_rect.height = height << 16;
+
+    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
+    dispman_update  = vc_dispmanx_update_start( 0 );
+    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
+      0 /*layer*/, &dst_rect, 0 /*src*/,
+      &src_rect, DISPMANX_PROTECTION_NONE,  (VC_DISPMANX_ALPHA_T*)0 /*alpha*/,  (DISPMANX_CLAMP_T*)0 /*clamp*/,  (DISPMANX_TRANSFORM_T)0 /*transform*/);
+
+    nativewindow.element = dispman_element;
+    nativewindow.width = screen_width;
+    nativewindow.height = screen_height;
+    vc_dispmanx_update_submit_sync( dispman_update );
+
+    nativeWindow = (NativeWindowType)&nativewindow;
+
+#else /* default */
+
+    if (eglSettings[CFG_MODE] == RENDER_RAW)        /* RAW FB mode */
+    {
+        nativeWindow = 0;
+    }
+    else if(eglSettings[CFG_MODE] == RENDER_SDL)    /* SDL/X11 mode */
+    {
+#if defined(USE_EGL_SDL)
+        /* SDL_GetWMInfo is populated when display was opened */
+        nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window;
+
+        if (nativeWindow == 0)
+        {
+            printf( "EGLport ERROR: unable to get window!\n" );
+            return 1;
+        }
+#else
+        printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
+#endif
+    }
+    else
+    {
+        printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] );
+        return 1;
+    }
+
+#endif /* WIZ / CAANOO */
+
+    return 0;
+}
+
+/** @brief Release the system's native display
+ */
+void FreeNativeDisplay( void )
+{
+}
+
+/** @brief Release the system's native window
+ */
+void FreeNativeWindow( void )
+{
+#if defined(WIZ) || defined(CAANOO)
+    if (nativeWindow != NULL) {
+        free( nativeWindow );
+    }
+    nativeWindow = NULL;
+#endif /* WIZ / CAANOO */
+}
+
+/** @brief Open any system specific resources
+ */
+void Platform_Open( void )
+{
+#if defined(PANDORA)
+    /* Pandora VSync */
+    fbdev = open( "/dev/fb0", O_RDONLY /* O_RDWR */ );
+    if ( fbdev < 0 ) {
+        printf( "EGLport ERROR: Couldn't open /dev/fb0 for Pandora Vsync\n" );
+    }
+#elif defined(RPI)
+    bcm_host_init();
+#endif /* PANDORA */
+}
+
+/** @brief Release any system specific resources
+ */
+void Platform_Close( void )
+{
+#if defined(PANDORA)
+    /* Pandora VSync */
+    close( fbdev );
+    fbdev = -1;
+#endif /* PANDORA */
+}
+
+/** @brief Check the systems vsync state
+ */
+void Platform_VSync( void )
+{
+#if defined(PANDORA)
+    /* Pandora VSync */
+    if (fbdev >= 0) {
+        int arg = 0;
+        ioctl( fbdev, FBIO_WAITFORVSYNC, &arg );
+    }
+#endif /* PANDORA */
+}
+
+/** @brief Get the system tick time (ms)
+ */
+uint32_t Platform_GetTicks( void )
+{
+    uint32_t ticks = 0;
+#if defined(USE_EGL_SDL)
+    ticks = SDL_GetTicks();
+#else
+    printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
+#endif
+    return ticks;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/renderer/eglport.h b/source/mupen64plus-video-arachnoid/src/renderer/eglport.h
new file mode 100755 (executable)
index 0000000..736456c
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ *
+ *  EGLPORT.H
+ *  Copyright (C) 2011-2013 Scott R. Smith
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ */
+
+#ifndef EGLPORT_H
+#define EGLPORT_H
+
+#include <stdint.h>
+#include "EGL/egl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Defines (in every case choose only one) */
+/**     Common: */
+/**         DEBUG : enable additional error monitoring per EGL function call */
+/**     Native display and window system for use with EGL */
+/**         USE_EGL_SDL : used for access to a SDL X11 window */
+/**     Platform: settings that are specific to that device */
+/**         PANDORA (USE_GLES1 or USE_GLES2) */
+/**         WIZ     (USE_GLES1) */
+/**         CAANOO  (USE_GLES1) */
+/**         RPI     (USE_GLES1 or USE_GLES2) */
+/**     GLES Version */
+/**         USE_GLES1 : EGL for use with OpenGL-ES 1.X contexts */
+/**         USE_GLES2 : EGL for use with OpenGL-ES 2.0 contexts */
+
+/** Public API */
+void    EGL_Close                   ( void );
+int8_t  EGL_Open                    ( uint16_t width, uint16_t height );
+void    EGL_SwapBuffers             ( void );
+
+extern int8_t  eglColorbits;
+extern int8_t  eglDepthbits;
+extern int8_t  eglStencilbits;
+
+/** Simple Examples  */
+/**     Raw mode:
+            EGL_Open( window_width, window_height );
+            do while(!quit) {
+                ... run app
+                EGL_SwapBuffers();
+            }
+            EGL_Close();
+*/
+/**     X11/SDL mode:
+            SDL_Init( SDL_INIT_VIDEO );
+            SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE|SDL_FULLSCREEN);
+            EGL_Open( window_width, window_height );
+            do while(!quit) {
+                ... run app
+                EGL_SwapBuffers();
+            }
+            EGL_Close();
+            SDL_Quit();
+*/
+
+#if defined(DEBUG)
+#define GET_EGLERROR(FUNCTION)               \
+    FUNCTION;                                \
+    {                                        \
+        CheckEGLErrors(__FILE__, __LINE__);  \
+    }
+#else
+#define GET_EGLERROR(FUNCTION) FUNCTION;
+#endif
+
+#define peglQueryString(A,B)                    GET_EGLERROR(eglQueryString(A,B))
+#define peglDestroyContext(A,B)                 GET_EGLERROR(eglDestroyContext(A,B))
+#define peglDestroySurface(A,B)                 GET_EGLERROR(eglDestroySurface(A,B))
+#define peglTerminate(A)                        GET_EGLERROR(eglTerminate(A))
+#define peglSwapBuffers(A,B)                    GET_EGLERROR(eglSwapBuffers(A,B))
+#define peglGetDisplay(A)                       GET_EGLERROR(eglGetDisplay(A))
+#define peglBindAPI(A)                          GET_EGLERROR(eglBindAPI(A))
+#define peglCreateContext(A,B,C,D)              GET_EGLERROR(eglCreateContext(A,B,C,D))
+#define peglCreateWindowSurface(A,B,C,D)        GET_EGLERROR(eglCreateWindowSurface(A,B,C,D))
+#define peglInitialize(A,B,C)                   GET_EGLERROR(eglInitialize(A,B,C))
+#define peglMakeCurrent(A,B,C,D)                GET_EGLERROR(eglMakeCurrent(A,B,C,D))
+#define peglChooseConfig(A,B,C,D,E)             GET_EGLERROR(eglChooseConfig(A,B,C,D,E))
+#define peglSwapInterval(A,B)                   GET_EGLERROR(eglSwapInterval(A,B))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EGLPORT_H */
diff --git a/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp
new file mode 100755 (executable)
index 0000000..ed8e700
--- /dev/null
@@ -0,0 +1,129 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "CachedTexture.h"
+
+#include "m64p.h"
+#include "OpenGL.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+CachedTexture::CachedTexture()
+{
+    m_id = 0;                //!< id used by OpenGL to identify texture
+    m_textureSize = 0;       //!< Size of texture in bytes
+    address = 0;
+    crc  = 0;
+    offsetS = offsetT  = 0;
+    maskS = maskT  = 0;
+    clampS = clampT  = 0;
+    mirrorS = mirrorT  = 0;
+    line = 0;
+    size = 0;
+    format = 0;                    //!< Texture format
+    tMem = 0;
+    palette = 0;                   //!< What Texture Look Up Table to use
+    width  = height = 0;           // N64 width and height
+    clampWidth = clampHeight = 0;  // Size to clamp to
+    realWidth = realHeight = 0;    // Actual texture size
+    scaleS = scaleT  = 0;          // Scale to map to 0.0-1.0
+    shiftScaleS = shiftScaleT = 0; // Scale to shift
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+CachedTexture::~CachedTexture()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Activate texture
+//-----------------------------------------------------------------------------
+void CachedTexture::activate()
+{
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture( GL_TEXTURE_2D, m_id );
+}
+
+//-----------------------------------------------------------------------------
+//! Deactivate texture
+//-----------------------------------------------------------------------------
+void CachedTexture::deactivate()
+{
+    glDisable(GL_TEXTURE_2D);
+    glBindTexture( GL_TEXTURE_2D, 0 );    
+}
+
+//-----------------------------------------------------------------------------
+//! Equal operator
+//-----------------------------------------------------------------------------
+bool CachedTexture::operator == (const CachedTexture& t) const
+{
+    return( crc         == t.crc &&
+            width       == t.width &&
+            height      == t.height &&
+            clampWidth  == t.clampWidth &&
+            clampHeight == t.clampHeight &&
+            maskS       == t.maskS &&
+            maskT       == t.maskT &&
+            mirrorS     == t.mirrorS &&
+            mirrorT     == t.mirrorT &&
+            clampS      == t.clampS &&
+            clampT      == t.clampT &&
+            format      == t.format /* &&
+            size        == t.size */ );
+}
+
+//-----------------------------------------------------------------------------
+//! Assign operator
+//-----------------------------------------------------------------------------
+CachedTexture& CachedTexture::operator = (const CachedTexture& v)
+{     
+    address = v.address;
+    crc     = v.crc;
+    format  = v.format;
+    size    = v.size;
+    width   = v.width;
+    height  = v.height;
+    clampWidth  = v.clampWidth;
+    clampHeight = v.clampHeight;
+    palette = v.palette;
+/*    cache.current[tile]->fulS = gSP.textureTile[tile]->fulS;
+    cache.current[tile]->fulT = gSP.textureTile[tile]->fulT;
+    cache.current[tile]->ulS = gSP.textureTile[tile]->ulS;
+    cache.current[tile]->ulT = gSP.textureTile[tile]->ulT;
+    cache.current[tile]->lrS = gSP.textureTile[tile]->lrS;
+    cache.current[tile]->lrT = gSP.textureTile[tile]->lrT;*/
+    maskS = v.maskS;
+    maskT = v.maskT;
+    mirrorS = v.mirrorS;
+    mirrorT = v.mirrorT;
+    clampS = v.clampS;
+    clampT = v.clampT;
+    line = v.line;
+    tMem = v.tMem;
+    //lastDList = RSP.DList;
+    //frameBufferTexture = FALSE;
+    return *this;     
+}
diff --git a/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h
new file mode 100755 (executable)
index 0000000..1efbad7
--- /dev/null
@@ -0,0 +1,78 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef CACHED_TEXTURE_H_
+#define CACHED_TEXTURE_H_
+
+//*****************************************************************************
+//* Cached Texture
+//! Struct used by Texture Cache to store used textures.
+//*****************************************************************************
+class CachedTexture
+{
+public:
+
+    //Constructor / Destrucotr
+    CachedTexture();
+    ~CachedTexture();
+
+    //Activate / Deactivate
+    void activate();
+    void deactivate();
+
+    //Get texture size
+    unsigned int getTextureSize() { return m_textureSize; }
+
+    //Assignment operator
+    CachedTexture& operator = (const CachedTexture& v);
+
+    //Equal operator
+    bool operator == (const CachedTexture& t) const;
+
+public:
+
+    unsigned int  m_id;                      //!< id used by OpenGL to identify texture
+    unsigned int  m_textureSize;             //!< Size of texture in bytes
+
+    unsigned int  address;
+    unsigned int  crc;                       //!< A CRC "checksum" (Cyclic redundancy check)
+//    float          fulS, fulT;
+//    unsigned short ulS, ulT, lrS, lrT;
+    float         offsetS, offsetT;
+    unsigned int  maskS, maskT;
+    unsigned int  clampS, clampT;
+    unsigned int  mirrorS, mirrorT;
+    unsigned int  line;
+    unsigned int  size;
+    unsigned int  format;                    //!< Texture format
+    unsigned int  tMem;
+    unsigned int  palette;                   //!< What Texture Look Up Table to use
+    unsigned int  width, height;             //!< N64 width and height
+    unsigned int  clampWidth, clampHeight;   //!< Size to clamp to
+    unsigned int  realWidth, realHeight;     //!< Actual texture size
+    float         scaleS, scaleT;            //!< Scale to map to 0.0-1.0
+    float         shiftScaleS, shiftScaleT;  //!< Scale to shift
+//    unsigned int lastDList;
+//    unsigned int frameBufferTexture;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp
new file mode 100755 (executable)
index 0000000..c834712
--- /dev/null
@@ -0,0 +1,314 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+//*****************************************************************************
+// 
+// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64.
+// http://gln64.emulation64.com/
+//
+//*****************************************************************************
+
+#include "ImageFormatSelector.h"
+#include "CachedTexture.h"
+#include "assembler.h"
+#include "GBIDefs.h"
+#include "m64p.h"
+#include "OpenGL.h"
+#include "Memory.h"
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels                 1
+    #define GL_UNSIGNED_BYTE_3_3_2_EXT           0x8032
+    #define GL_UNSIGNED_SHORT_4_4_4_4_EXT        0x8033
+    #define GL_UNSIGNED_SHORT_5_5_5_1_EXT        0x8034
+    #define GL_UNSIGNED_INT_8_8_8_8_EXT          0x8035
+    #define GL_UNSIGNED_INT_10_10_10_2_EXT       0x8036
+#endif /* GL_EXT_packed_pixels */
+
+unsigned long long* TMEM = Memory::getTextureMemory();
+
+
+inline unsigned int GetNone( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return 0x00000000;
+}
+
+inline unsigned int GetCI4IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    if (x & 1)
+        return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
+    else
+        return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
+}
+
+inline unsigned int GetCI4IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    if (x & 1)
+        return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
+    else
+        return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
+}
+
+inline unsigned int GetCI4RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    if (x & 1)
+        return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
+    else
+        return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
+}
+
+inline unsigned int GetCI4RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    if (x & 1)
+        return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
+    else
+        return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
+}
+
+inline unsigned int GetIA31_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
+}
+
+inline unsigned int GetIA31_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
+}
+
+inline unsigned int GetI4_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
+}
+
+inline unsigned int GetI4_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    unsigned char color4B;
+
+    color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
+
+    return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
+}
+
+inline unsigned int GetCI8IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
+}
+
+inline unsigned int GetCI8IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
+}
+
+inline unsigned int GetCI8RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
+}
+
+inline unsigned int GetCI8RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
+}
+
+inline unsigned int GetIA44_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA44_RGBA8888(((unsigned char*)src)[x^(i<<1)]);
+}
+
+inline unsigned int GetIA44_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA44_RGBA4444(((unsigned char*)src)[x^(i<<1)]);
+}
+
+inline unsigned int GetI8_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return I8_RGBA8888(((unsigned char*)src)[x^(i<<1)]);
+}
+
+inline unsigned int GetI8_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return I8_RGBA4444(((unsigned char*)src)[x^(i<<1)]);
+}
+
+inline unsigned int GetRGBA5551_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return RGBA5551_RGBA8888( ((unsigned short*)src)[x^i] );
+}
+
+inline unsigned int GetRGBA5551_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return RGBA5551_RGBA5551( ((unsigned short*)src)[x^i] );
+}
+
+inline unsigned int GetIA88_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA88_RGBA8888(((unsigned short*)src)[x^i]);
+}
+
+inline unsigned int GetIA88_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return IA88_RGBA4444(((unsigned short*)src)[x^i]);
+}
+
+inline unsigned int GetRGBA8888_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return ((unsigned int*)src)[x^i];
+}
+
+inline unsigned int GetRGBA8888_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
+{
+    return RGBA8888_RGBA4444(((unsigned int*)src)[x^i]);
+}
+
+/*
+const struct
+{
+    GetTexelFunc    Get16;
+    unsigned int    glType16;
+    int              glInternalFormat16;
+    GetTexelFunc    Get32;
+    unsigned int     glType32;
+    int                glInternalFormat32;
+    unsigned int   autoFormat, lineShift, maxTexels;
+} 
+*/
+ImageFormat ImageFormatSelector::imageFormats[4][5]  =
+{ //        Get16                    glType16                        glInternalFormat16    Get32                   glType32             glInternalFormat32   autoFormat
+    { // 4-bit
+        {    GetCI4RGBA_RGBA5551,    GL_UNSIGNED_SHORT_5_5_5_1_EXT,  GL_RGB5_A1,           GetCI4RGBA_RGBA8888,    GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...)
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 4, 8192 }, // YUV
+        {    GetCI4RGBA_RGBA5551,    GL_UNSIGNED_SHORT_5_5_5_1_EXT,  GL_RGB5_A1,           GetCI4RGBA_RGBA8888,    GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGB5_A1, 4, 4096 }, // CI
+        {    GetIA31_RGBA4444,       GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetIA31_RGBA8888,       GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 4, 8192 }, // IA
+        {    GetI4_RGBA4444,         GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetI4_RGBA8888,         GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 4, 8192 }, // I
+    },
+    { // 8-bit
+        {    GetCI8RGBA_RGBA5551,    GL_UNSIGNED_SHORT_5_5_5_1_EXT,  GL_RGB5_A1,           GetCI8RGBA_RGBA8888,    GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGB5_A1, 3, 2048 }, // RGBA
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 4096 }, // YUV
+        {    GetCI8RGBA_RGBA5551,    GL_UNSIGNED_SHORT_5_5_5_1_EXT,  GL_RGB5_A1,           GetCI8RGBA_RGBA8888,    GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGB5_A1, 3, 2048 }, // CI
+        {    GetIA44_RGBA4444,       GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetIA44_RGBA8888,       GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 3, 4096 }, // IA
+        {    GetI8_RGBA4444,         GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetI8_RGBA8888,         GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA8, 3, 4096 }, // I
+    },
+    { // 16-bit
+        {    GetRGBA5551_RGBA5551,   GL_UNSIGNED_SHORT_5_5_5_1_EXT,  GL_RGB5_A1,           GetRGBA5551_RGBA8888,   GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGB5_A1, 2, 2048 }, // RGBA
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 2, 2048 }, // YUV
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 2048 }, // CI
+        {    GetIA88_RGBA4444,       GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetIA88_RGBA8888,       GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA8, 2, 2048 }, // IA
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 2048 }, // I
+    },
+    { // 32-bit
+        {    GetRGBA8888_RGBA4444,   GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetRGBA8888_RGBA8888,   GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA8, 2, 1024 }, // RGBA
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 1024 }, // YUV
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 1024 }, // CI
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 1024 }, // IA
+        {    GetNone,                GL_UNSIGNED_SHORT_4_4_4_4_EXT,  GL_RGBA4,             GetNone,                GL_UNSIGNED_BYTE,    GL_RGBA8,            GL_RGBA4, 0, 1024 }, // I
+    }
+};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+ImageFormatSelector::ImageFormatSelector()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+ImageFormatSelector::~ImageFormatSelector()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Detect Image Format
+//-----------------------------------------------------------------------------
+void ImageFormatSelector::detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT)
+{
+    if (((imageFormats[texture->size][texture->format].autoFormat == GL_RGBA8) || 
+        ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) || 
+        (textureBitDepth == 2)) && (textureBitDepth != 0))
+    {
+         texture->m_textureSize = (texture->realWidth * texture->realHeight) << 2;
+        if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16))
+        {
+            if (texture->size == G_IM_SIZ_4b)
+                getTexelFunc = GetCI4IA_RGBA8888;
+            else
+                getTexelFunc = GetCI8IA_RGBA8888;
+
+            internalFormat = GL_RGBA8;
+            imageType = GL_UNSIGNED_BYTE;
+        }
+        else
+        {
+            getTexelFunc = imageFormats[texture->size][texture->format].Get32;
+            internalFormat = imageFormats[texture->size][texture->format].glInternalFormat32;
+            imageType = imageFormats[texture->size][texture->format].glType32;
+        }
+    }
+    else
+    {
+        texture->m_textureSize = (texture->realWidth * texture->realHeight) << 1;
+        if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16))
+        {
+            if (texture->size == G_IM_SIZ_4b)
+                getTexelFunc = GetCI4IA_RGBA4444;
+            else
+                getTexelFunc = GetCI8IA_RGBA4444;
+
+            internalFormat = GL_RGBA4;
+            imageType = GL_UNSIGNED_SHORT_4_4_4_4_EXT;
+        }
+        else
+        {
+            getTexelFunc = imageFormats[texture->size][texture->format].Get16;
+            internalFormat = imageFormats[texture->size][texture->format].glInternalFormat16;
+            imageType = imageFormats[texture->size][texture->format].glType16;
+        }
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h
new file mode 100755 (executable)
index 0000000..3ab1552
--- /dev/null
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef IMAGE_FORMAT_SELECTOR_H_
+#define IMAGE_FORMAT_SELECTOR_H_
+
+//Function pointer for image decoding
+typedef unsigned int (*GetTexelFunc)( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette );
+
+//Forward declarations
+class CachedTexture;
+
+//*****************************************************************************
+//* ImageFormat
+//! Struct used when diffining image formats and how to convert/decode/interperite them.
+//*****************************************************************************
+struct ImageFormat
+{
+    GetTexelFunc    Get16;
+    unsigned int    glType16;
+    int             glInternalFormat16;
+    GetTexelFunc    Get32;
+    unsigned int    glType32;
+    int             glInternalFormat32;
+    unsigned int    autoFormat, lineShift, maxTexels;
+};
+
+//*****************************************************************************
+//* ImageFormatSelector
+//! Class for selecting image format decoding functions depending on image format. 
+//*****************************************************************************
+class ImageFormatSelector
+{
+public:
+
+    //Constructor / Destructor
+    ImageFormatSelector();
+    ~ImageFormatSelector();
+
+    //Detect image format
+    void detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT);
+
+public:
+
+    //Static variables
+    static ImageFormat imageFormats[4][5];    //!< Defines how to decode diffrent formats
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp
new file mode 100755 (executable)
index 0000000..c30e7f1
--- /dev/null
@@ -0,0 +1,627 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "TextureCache.h"
+
+#include "RDP.h"
+#include "RSP.h"
+#include "CachedTexture.h"
+#include "MathLib.h"
+#include <algorithm>
+    using std::min;
+#include "m64p.h"
+#include "OpenGL.h"
+#include "Memory.h"
+#include "OpenGLRenderer.h"
+#include "MultiTexturingExt.h"    
+    //gSPBgRect1Cyc
+//gSPBgRectCopy
+#define GL_CLAMP_TO_EDGE                  0x812F
+#define GL_GENERATE_MIPMAP                0x8191
+
+#include "Logger.h"
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+TextureCache::TextureCache()
+{
+    m_currentTextures[0] = 0;
+    m_currentTextures[1] = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+TextureCache::~TextureCache()
+{   
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool TextureCache::initialize(RSP* rsp, RDP* rdp, Memory* memory, unsigned int textureBitDepth, unsigned int cacheSize)
+{
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory   = memory;
+    m_bitDepth = textureBitDepth;
+    m_maxBytes = cacheSize;
+    
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Update
+//-----------------------------------------------------------------------------
+void TextureCache::update(unsigned int tile)
+{
+    //if (cache.bitDepth != OGL.textureBitDepth)
+    //{
+    //    TextureCache_Destroy();
+    //    TextureCache_Init();
+    //}
+
+    //Special textures?
+    if ( m_rdp->getTextureMode() == TM_BGIMAGE )
+    {
+        return;
+    }
+    else if ( m_rdp->getTextureMode() == TM_FRAMEBUFFER )
+    {
+        return;
+    }
+
+
+    CachedTexture temp;    
+    unsigned int maskWidth = 0, maskHeight = 0;
+    _calculateTextureSize(tile, &temp, maskWidth, maskHeight);
+
+    static int hits = 0;
+    static int misses = 0;
+
+    //For each texture in texture cache
+    for (TextureList::iterator it=m_cachedTextures.begin(); it!=m_cachedTextures.end(); ++it)
+      {
+        CachedTexture* temp2 = (*it);
+
+        if ( *temp2 == temp )
+        {
+            _activateTexture( tile, (*it) );
+            hits++;
+            return;
+        }
+    }
+    misses++;
+
+    // If multitexturing, set the appropriate texture
+    //if (OGL.ARB_multitexture)
+    glActiveTextureARB( GL_TEXTURE0_ARB + tile );
+
+    //Add new texture to cache
+    m_currentTextures[tile] = addTop();
+    m_currentTextures[tile]->activate();
+
+    m_currentTextures[tile]->address     = m_rdp->getTextureImage()->address;
+    m_currentTextures[tile]->crc         = temp.crc;
+    m_currentTextures[tile]->width       = temp.width;
+    m_currentTextures[tile]->height      = temp.height;
+    m_currentTextures[tile]->clampWidth  = temp.clampWidth;
+    m_currentTextures[tile]->clampHeight = temp.clampHeight;
+
+    m_currentTextures[tile]->format = m_rsp->getTile(tile)->format;
+    m_currentTextures[tile]->size =  m_rsp->getTile(tile)->size;
+
+    m_currentTextures[tile]->palette = m_rsp->getTile(tile)->palette;
+/*    m_currentTextures[tile]->fulS = rsp.getTile(tile)->fulS;
+    m_currentTextures[tile]->fulT = rsp.getTile(tile)->fulT;
+    m_currentTextures[tile]->ulS = rsp.getTile(tile)->ulS;
+    m_currentTextures[tile]->ulT = rsp.getTile(tile)->ulT;
+    m_currentTextures[tile]->lrS = rsp.getTile(tile)->lrS;
+    m_currentTextures[tile]->lrT = rsp.getTile(tile)->lrT;*/
+    m_currentTextures[tile]->maskS   = m_rsp->getTile(tile)->masks;
+    m_currentTextures[tile]->maskT   = m_rsp->getTile(tile)->maskt;
+    m_currentTextures[tile]->mirrorS = m_rsp->getTile(tile)->mirrors;
+    m_currentTextures[tile]->mirrorT = m_rsp->getTile(tile)->mirrort;
+    m_currentTextures[tile]->clampS  = m_rsp->getTile(tile)->clamps;
+    m_currentTextures[tile]->clampT  = m_rsp->getTile(tile)->clampt;
+    m_currentTextures[tile]->line    = m_rsp->getTile(tile)->line;
+    m_currentTextures[tile]->tMem    = m_rsp->getTile(tile)->tmem;
+
+
+    
+//    cache.current[tile]->lastDList = RSP.DList;
+//    cache.current[tile]->frameBufferTexture = FALSE;
+
+    //Calculate Real Width
+    if (m_currentTextures[tile]->clampS) 
+    {
+        m_currentTextures[tile]->realWidth = pow2( temp.clampWidth );
+    }
+    else if (m_currentTextures[tile]->mirrorS)
+    {
+        m_currentTextures[tile]->realWidth = maskWidth << 1;
+    }
+    else
+    {
+        m_currentTextures[tile]->realWidth = pow2( temp.width );
+    }
+
+    //Calculate Real Height
+    if (m_currentTextures[tile]->clampT)
+    {
+        m_currentTextures[tile]->realHeight = pow2( temp.clampHeight );
+    }
+    else if (m_currentTextures[tile]->mirrorT)
+    {
+        m_currentTextures[tile]->realHeight = maskHeight << 1;
+    }
+    else
+    {
+        m_currentTextures[tile]->realHeight = pow2( temp.height );
+    }
+
+    //Calculate Scale
+    m_currentTextures[tile]->scaleS = 1.0f / (float)(m_currentTextures[tile]->realWidth);
+    m_currentTextures[tile]->scaleT = 1.0f / (float)(m_currentTextures[tile]->realHeight);
+    m_currentTextures[tile]->shiftScaleS = 1.0f;
+    m_currentTextures[tile]->shiftScaleT= 1.0f;
+    #if 0
+        //m_currentTextures[tile]->offsetS = OGL.enable2xSaI ? 0.25f : 0.5f;
+        //m_currentTextures[tile]->offsetT = OGL.enable2xSaI ? 0.25f : 0.5f;
+    #else
+        m_currentTextures[tile]->offsetS = 0.5f;
+        m_currentTextures[tile]->offsetT = 0.5f;    
+    #endif
+
+    if (m_rsp->getTile(tile)->shifts > 10)
+        m_currentTextures[tile]->shiftScaleS = (float)(1 << (16 - m_rsp->getTile(tile)->shifts));
+    else if (m_rsp->getTile(tile)->shifts > 0)
+        m_currentTextures[tile]->shiftScaleS /= (float)(1 << m_rsp->getTile(tile)->shifts);
+
+    if (m_rsp->getTile(tile)->shiftt > 10)
+        m_currentTextures[tile]->shiftScaleT = (float)(1 << (16 - m_rsp->getTile(tile)->shiftt));
+    else if (m_rsp->getTile(tile)->shiftt > 0)
+        m_currentTextures[tile]->shiftScaleT /= (float)(1 << m_rsp->getTile(tile)->shiftt);
+
+
+
+
+
+    _loadTexture( m_currentTextures[tile] );
+    _activateTexture( tile, m_currentTextures[tile] );
+
+    m_cachedBytes += m_currentTextures[tile]->getTextureSize();
+
+}
+
+//-----------------------------------------------------------------------------
+//* Add Top
+//! Adds a texture to cache
+//-----------------------------------------------------------------------------
+CachedTexture* TextureCache::addTop()
+{
+    //If no memory left, remove old textures from cache
+    while ( m_cachedBytes > m_maxBytes )
+    {
+        this->removeBottom();
+    }
+
+    //Allocate memory
+    CachedTexture* newTexture = new CachedTexture();
+
+    //Generate a texture
+    glGenTextures(1, &newTexture->m_id);
+
+    //Add Texture to cache
+    m_cachedTextures.push_front(newTexture);
+
+    return newTexture;
+}
+
+//-----------------------------------------------------------------------------
+// Remove Bottom
+//-----------------------------------------------------------------------------
+void TextureCache::removeBottom() 
+{
+    //Get Last Texture in list
+    CachedTexture* lastTexture = *(--m_cachedTextures.end());
+
+    //Remove Texture
+    m_cachedTextures.pop_back();
+    m_cachedBytes -= lastTexture->getTextureSize();
+
+    //if (cache.bottom->frameBufferTexture)
+    //    FrameBuffer_RemoveBuffer( cache.bottom->address );
+
+    //Delete texture
+    glDeleteTextures(1, &lastTexture->m_id);
+
+    delete lastTexture;
+}
+
+//-----------------------------------------------------------------------------
+// Remove
+//-----------------------------------------------------------------------------
+void TextureCache::remove( CachedTexture *texture ) 
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//Move Texture to top
+//-----------------------------------------------------------------------------
+void TextureCache::moveToTop( CachedTexture *newtop ) 
+{
+    //Get Texture
+    TextureList::iterator it = std::find( m_cachedTextures.begin(), m_cachedTextures.end(), newtop);
+
+    //Erase Texture
+    if ( it != m_cachedTextures.end() )
+    {
+        m_cachedTextures.erase(it);
+    }
+
+    //Add texture to the front of the list
+    m_cachedTextures.push_front(newtop);
+}
+
+//-----------------------------------------------------------------------------
+// Dispose
+//-----------------------------------------------------------------------------
+void TextureCache::dispose()
+{
+    //For each texture
+    for (TextureList::iterator it=m_cachedTextures.begin(); it!=m_cachedTextures.end(); ++it )
+    {
+        delete (*it);
+    }
+    m_cachedTextures.clear();
+}
+
+//-----------------------------------------------------------------------------
+// Load Texture
+//-----------------------------------------------------------------------------
+void TextureCache::_loadTexture(CachedTexture* texture)
+{
+    //Select Image Type
+    GetTexelFunc getTexelFunc;
+    unsigned int internalFormat;
+    int             imageType;
+    m_formatSelector.detectImageFormat(texture, m_bitDepth, getTexelFunc, internalFormat, imageType, m_rdp->getTextureLUT());
+
+    //Allocate memory
+    unsigned int* dest = new unsigned int[ texture->getTextureSize() ];
+
+    //Get Line Size
+    unsigned short line = (unsigned short)texture->line;
+    if (texture->size == G_IM_SIZ_32b)
+        line <<= 1;
+
+    //
+    //Work Your magic
+    //
+
+    unsigned short mirrorSBit, maskSMask, clampSClamp;
+    unsigned short mirrorTBit, maskTMask, clampTClamp;
+
+    if (texture->maskS)
+    {
+        clampSClamp = (unsigned short)(texture->clampS ? texture->clampWidth - 1 : (texture->mirrorS ? (texture->width << 1) - 1 : texture->width - 1));
+        maskSMask = (1 << texture->maskS) - 1;
+        mirrorSBit = texture->mirrorS ? 1 << texture->maskS : 0;
+    }
+    else
+    {
+        clampSClamp = (unsigned short)min( texture->clampWidth, texture->width ) - 1;
+        maskSMask = 0xFFFF;
+        mirrorSBit = 0x0000;
+    }
+
+    if (texture->maskT)
+    {
+        clampTClamp = (unsigned short)(texture->clampT ? texture->clampHeight - 1 : (texture->mirrorT ? (texture->height << 1) - 1: texture->height - 1));
+        maskTMask = (1 << texture->maskT) - 1;
+        mirrorTBit = texture->mirrorT ?    1 << texture->maskT : 0;
+    }
+    else
+    {
+        clampTClamp = (unsigned short)min( texture->clampHeight, texture->height ) - 1;
+        maskTMask = 0xFFFF;
+        mirrorTBit = 0x0000;
+    }
+
+    // Hack for Zelda warp texture
+    if (((texture->tMem << 3) + (texture->width * texture->height << texture->size >> 1)) > 4096)
+        texture->tMem = 0;
+
+    // limit clamp values to min-0 (Perfect Dark has height=0 textures, making negative clamps)
+    if (clampTClamp & 0x8000)
+        clampTClamp = 0;
+    if (clampSClamp & 0x8000)
+        clampSClamp = 0;
+
+    //
+    //Retrive texture from source (TMEM) and copy it to dest
+    //
+
+    unsigned short x, y, i, j, tx, ty;
+
+    unsigned long long* src;
+
+    j = 0;
+    for (y = 0; y < texture->realHeight; y++)
+    {
+        ty = min(y, clampTClamp) & maskTMask;
+
+        if (y & mirrorTBit) {
+            ty ^= maskTMask;
+        }
+
+        //TODO: remove old if new works
+        //src = m_memory->getTextureMemory(texture->tMem) + line * ty;
+        src = m_memory->getTextureMemory((texture->tMem + line * ty) & 511);
+        
+
+        i = (ty & 1) << 1;
+        for (x = 0; x < texture->realWidth; x++)
+        {
+            tx = min(x, clampSClamp) & maskSMask;
+
+            if (x & mirrorSBit)
+                tx ^= maskSMask;
+
+            if (internalFormat == GL_RGBA8)
+                ((unsigned int*)dest)[j++] = getTexelFunc( src, tx, i, texture->palette );
+            else
+                ((unsigned short*)dest)[j++] = getTexelFunc( src, tx, i, texture->palette );
+        }
+    }
+
+    //Send Texture to OpenGL
+#ifdef HAVE_GLES
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texture->realWidth, texture->realHeight, 0, GL_RGBA, imageType, dest );
+#else
+    glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, texture->realWidth, texture->realHeight, 0, GL_RGBA, imageType, dest );
+#endif
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    delete[] dest;
+}
+
+
+void TextureCache::_calculateTextureSize(unsigned int tile, CachedTexture* out, unsigned int& maskWidth, unsigned int& maskHeight )
+{
+    RDPTile* rspTile = m_rsp->getTile(tile);
+
+    //Calculate Tile Size
+    unsigned int tileWidth =  rspTile->getWidth();
+    unsigned int tileHeight = rspTile->getHeight();
+
+    //Get Mask Size
+    maskWidth = 1 << rspTile->masks;
+    maskHeight = 1 << rspTile->maskt;
+
+    //Get Current Tile Size
+    unsigned int loadWidth = m_rdp->getCurrentTile()->getWidth();
+    unsigned int loadHeight = m_rdp->getCurrentTile()->getHeight();
+
+    unsigned int maxTexels = ImageFormatSelector::imageFormats[rspTile->size][rspTile->format].maxTexels;
+
+    //Get Line Width (depending on imageformat)
+    unsigned int lineWidth = rspTile->line << ImageFormatSelector::imageFormats[rspTile->size][rspTile->format].lineShift;
+    unsigned int lineHeight; 
+    if ( lineWidth ) // Don't allow division by zero
+        lineHeight = min( maxTexels / lineWidth, tileHeight );
+    else
+        lineHeight = 0;
+
+    unsigned int width;
+    unsigned int height;
+
+    if ( m_rdp->getTextureMode() == TM_TEXRECT )
+    {
+        unsigned short texRectWidth = (unsigned short)(m_rdp->getTexRectWidth() - rspTile->uls);
+        unsigned short texRectHeight = (unsigned short)(m_rdp->getTexRectHeight() - rspTile->ult);
+
+        if (rspTile->masks && ((maskWidth * maskHeight) <= maxTexels))
+            width = maskWidth;
+        else if ((tileWidth * tileHeight) <= maxTexels)
+            width = tileWidth;
+        else if ((tileWidth * texRectHeight) <= maxTexels)
+            width = tileWidth;
+        else if ((texRectWidth * tileHeight) <= maxTexels)
+            width = m_rdp->getTexRectWidth();
+        else if ((texRectWidth * texRectHeight) <= maxTexels)
+            width = m_rdp->getTexRectWidth();
+        else if (m_rdp->getLoadType() == LOADTYPE_TILE)
+            width = loadWidth;
+        else
+            width = lineWidth;
+
+        if (rspTile->maskt && ((maskWidth * maskHeight) <= maxTexels))
+            height = maskHeight;
+        else if ((tileWidth * tileHeight) <= maxTexels)
+            height = tileHeight;
+        else if ((tileWidth * texRectHeight) <= maxTexels)
+            height = m_rdp->getTexRectHeight();
+        else if ((texRectWidth * tileHeight) <= maxTexels)
+            height = tileHeight;
+        else if ((texRectWidth * texRectHeight) <= maxTexels)
+            height = m_rdp->getTexRectHeight();
+        else if (m_rdp->getLoadType() == LOADTYPE_TILE)
+            height = loadHeight;
+        else
+            height = lineHeight;
+    }
+    else
+    {
+        if (rspTile->masks && ((maskWidth * maskHeight) <= maxTexels))
+            width = maskWidth; // Use mask width if set and valid
+        else if ((tileWidth * tileHeight) <= maxTexels)
+            width = tileWidth; // else use tile width if valid
+        else if (m_rdp->getLoadType() == LOADTYPE_TILE)
+            width = loadWidth; // else use load width if load done with LoadTile
+        else
+            width = lineWidth; // else use line-based width
+
+        if (rspTile->maskt && ((maskWidth * maskHeight) <= maxTexels))
+            height = maskHeight;
+        else if ((tileWidth * tileHeight) <= maxTexels)
+            height = tileHeight;
+        else if (m_rdp->getLoadType() == LOADTYPE_TILE)
+            height = loadHeight;
+        else
+            height = lineHeight;
+    }
+
+     unsigned int clampWidth = rspTile->clamps ? tileWidth : width;
+    unsigned int clampHeight = rspTile->clampt ? tileHeight : height;
+
+    if (clampWidth > 256)
+        rspTile->clamps = 0;
+    if (clampHeight > 256)
+        rspTile->clampt = 0;
+
+    // Make sure masking is valid
+    if (maskWidth > width) 
+    {
+        rspTile->masks = powof( width );
+        maskWidth = 1 << rspTile->masks;
+    }
+
+    if (maskHeight > height)
+    {
+        rspTile->maskt = powof( height );
+        maskHeight = 1 << rspTile->maskt;
+    }
+
+    //Set output data
+    out->width       = width;
+    out->height      = height;
+    out->clampWidth  = clampWidth;
+    out->clampHeight = clampHeight;
+    out->maskS       = m_rsp->getTile(tile)->masks;
+    out->maskT       = m_rsp->getTile(tile)->maskt;
+    out->mirrorS     = m_rsp->getTile(tile)->mirrors;
+    out->mirrorT     = m_rsp->getTile(tile)->mirrort;
+    out->clampS      = m_rsp->getTile(tile)->clamps;
+    out->clampT      = m_rsp->getTile(tile)->clampt;
+    out->format      = m_rsp->getTile(tile)->format;
+    out->size        = m_rsp->getTile(tile)->size; 
+    out->crc         = _calculateCRC(tile, width, height );
+}
+
+unsigned int TextureCache::_calculateCRC(unsigned int t, unsigned int width, unsigned int height)
+{
+    RDPTile* tile = m_rsp->getTile(t);
+
+    unsigned int crc;
+    unsigned int y, bpl, line;
+    unsigned long long *src;
+
+    //TODO: remove if new works
+    //src = m_memory->getTextureMemory(tile->tmem);
+    bpl = width << tile->size >> 1;
+
+    line = tile->line;
+     if (tile->size == G_IM_SIZ_32b)
+        line <<= 1;
+
+    crc = 0xFFFFFFFF;
+     for (y=0; y<height; ++y)
+    {
+        src = m_memory->getTextureMemory((tile->tmem + (y * line)) & 511);
+        crc = m_crcCalculator.calcCRC( crc, src, bpl );
+        //TODO: remove if new works
+        //src += line;
+    }
+
+       if ( tile->format == G_IM_FMT_CI )
+    {
+        if ( tile->size == G_IM_SIZ_4b )
+            crc = m_crcCalculator.calcCRC( crc, &m_rdp->m_paletteCRC16[tile->palette], 4 );
+        else if (tile->size == G_IM_SIZ_8b)
+            crc = m_crcCalculator.calcCRC( crc, &m_rdp->m_paletteCRC256, 4 );
+    }
+    return crc;
+}
+
+void TextureCache::_activateTexture( unsigned int t, CachedTexture *texture )
+{
+    // If multitexturing, set the appropriate texture
+    //if (OGL.ARB_multitexture)
+        glActiveTextureARB( GL_TEXTURE0_ARB + t );
+
+    // Bind the cached texture
+    texture->activate();
+
+    // Set filter mode. Almost always bilinear, but check anyways
+    unsigned int textureFiltering = m_rdp->getTextureFiltering();
+    if ( textureFiltering == G_TF_BILERP || textureFiltering == G_TF_AVERAGE )
+    {
+        if( m_mipmap > 0 )
+        {
+            // Set Mipmap
+            if(m_mipmap == 1)    // nearest
+            {
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+            }
+            else if(m_mipmap == 2)    // bilinear
+            {
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+            }
+            else if(m_mipmap == 3)    // trilinear
+            {
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+            }
+            
+            // Tell to hardware to generate mipmap (himself) when glTexImage2D is called
+            glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+        }
+        else    // no mipmapping
+        {
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+            glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE );
+        }
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+        
+    }
+    else
+    {
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+    }
+
+    
+
+    // Set clamping modes
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture->clampS ? GL_CLAMP_TO_EDGE : GL_REPEAT );
+    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture->clampT ? GL_CLAMP_TO_EDGE : GL_REPEAT );
+
+    //texture->lastDList = RSP.DList;
+
+    moveToTop( texture );
+
+    m_currentTextures[t] = texture;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureCache.h b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.h
new file mode 100755 (executable)
index 0000000..9712f89
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef TEXTURE_CACHE_H_
+#define TEXTURE_CACHE_H_
+
+#include "CachedTexture.h"
+#include "CRCCalculator2.h"
+#include "ImageFormatSelector.h"
+#include <list>
+
+//Forward declarations
+class Memory;
+class RSP;
+class RDP;
+
+//*****************************************************************************
+//* Texture Cache
+//! Class used to activate textures and store used textures for reuse.
+//! @details Nintendo64 has a texture cache of 4 KiB
+//*****************************************************************************
+class TextureCache
+{
+public:
+
+    //Constructor / Destructor
+    TextureCache();
+    ~TextureCache();
+
+    //Functions
+    bool initialize(RSP* rsp, RDP* rdp, Memory* memory, unsigned int textureBitDepth, unsigned int cacheSize=(32 * 1048576));
+    void update(unsigned int tile);
+    void dispose();
+
+    void setMipmap( int value ) { m_mipmap = value; } 
+
+    //Add and Remove
+    CachedTexture* addTop();
+    void removeBottom();
+    void remove( CachedTexture *texture );
+
+    //Move Texture to top
+    void moveToTop( CachedTexture *newtop );
+
+    //Get Current Texture
+    CachedTexture* getCurrentTexture(int index) { return m_currentTextures[index]; }
+    
+private:
+
+    void _loadTexture(CachedTexture* texture);
+    void _calculateTextureSize(unsigned int tile, CachedTexture* out, unsigned int& maskWidth, unsigned int& maskHeight);
+    void _activateTexture( unsigned int t, CachedTexture *texture );
+    unsigned int _calculateCRC(unsigned int t, unsigned int width, unsigned int height);
+
+private:
+//public:
+
+    RSP*    m_rsp;                         //!< Pointer to Reality Signal Processor 
+    RDP*    m_rdp;                         //!< Pointer to Reality Drawing Processor 
+    Memory* m_memory;                      //!< Pointer to Memory manager (handles RDRAM, Texture Memory...)
+
+    ImageFormatSelector m_formatSelector;  //!< Image Format Selector used when decoding textures
+    CRCCalculator2      m_crcCalculator;   //!< Hash value calculator for textures
+
+    unsigned int m_maxBytes;              //!< Maximum number of bytes this cache have
+    unsigned int m_cachedBytes;           //!< Current number of bytes in cache
+    unsigned int m_bitDepth;              //!<
+    int m_mipmap;
+
+    //Cached textures
+    typedef std::list<CachedTexture*> TextureList;
+    TextureList m_cachedTextures;          //!< List of cached textures
+
+    //Pointers to current textures
+    CachedTexture* m_currentTextures[2];   //!< Two textures for multi-texturing.
+    
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp
new file mode 100755 (executable)
index 0000000..4de0af3
--- /dev/null
@@ -0,0 +1,267 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "TextureLoader.h"
+#include "Memory.h"
+#include "TextureCache.h"
+#include "GBIDefs.h"
+#include "assembler.h"
+#include "Logger.h"
+#include "RDP.h"
+#include "CRCCalculator2.h"
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+TextureLoader::TextureLoader()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+TextureLoader::~TextureLoader()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Saves pointers to objects
+//-----------------------------------------------------------------------------
+bool TextureLoader::initialize(RDP* rdp, Memory* memory)
+{
+    m_rdp    = rdp;
+    m_memory = memory;
+
+    m_currentTile        = &m_tiles[7];
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Texture Image
+//! Stores information about texture image.
+//-----------------------------------------------------------------------------
+void TextureLoader::setTextureImage(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
+{
+    m_textureImage.address = m_memory->getRDRAMAddress( segmentAddress );  
+    m_textureImage.format  = format; 
+    m_textureImage.size    = size;   
+    m_textureImage.width   = width + 1;  //Note: add plus one, glN64 does it outside of function
+    m_textureImage.bpl     = m_textureImage.width << m_textureImage.size >> 1;
+}
+
+//-----------------------------------------------------------------------------
+//* Set Tile
+//! Stores information about an rdp tile.
+//-----------------------------------------------------------------------------
+void TextureLoader::setTile( int format, int size, int line, int tmem, int tile, int palette, 
+                             int clampS, int clampT, int mirrorS, int mirrorT, int maskS, 
+                             int maskT, int shiftS, int shiftT )
+{
+    m_tiles[tile].format  = format;
+    m_tiles[tile].size    = size;
+    m_tiles[tile].line    = line;
+    m_tiles[tile].tmem    = tmem;
+    m_tiles[tile].palette = palette;
+    m_tiles[tile].clamps  = clampS;
+    m_tiles[tile].clampt  = clampT;
+    m_tiles[tile].mirrors = mirrorS;
+    m_tiles[tile].mirrort = mirrorT;
+    m_tiles[tile].masks   = maskS;
+    m_tiles[tile].maskt   = maskT;
+    m_tiles[tile].shiftt  = shiftT;
+    m_tiles[tile].shifts  = shiftS;
+    
+    if ( !m_tiles[tile].masks ) 
+        m_tiles[tile].clamps = 1;
+    if ( !m_tiles[tile].maskt ) 
+        m_tiles[tile].clampt = 1;
+
+    //
+    if (((size == G_IM_SIZ_4b) || (size == G_IM_SIZ_8b)) && (format == G_IM_FMT_RGBA)) {
+        m_tiles[tile].format = G_IM_FMT_CI;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Set Tile Size
+//! Stores size information for a rdp tile.
+//-----------------------------------------------------------------------------
+void TextureLoader::setTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1)
+{
+    m_tiles[tile].uls = _SHIFTR( s0, 2, 10 );
+    m_tiles[tile].ult = _SHIFTR( t0, 2, 10 );
+    m_tiles[tile].lrs = _SHIFTR( s1, 2, 10 );
+    m_tiles[tile].lrt = _SHIFTR( t1, 2, 10 );
+    m_tiles[tile].fuls = _FIXED2FLOAT( s0, 2 );
+    m_tiles[tile].fult = _FIXED2FLOAT( t0, 2 );
+    m_tiles[tile].flrs = _FIXED2FLOAT( s1, 2 );
+    m_tiles[tile].flrt = _FIXED2FLOAT( t1, 2 );
+}
+
+//-----------------------------------------------------------------------------
+//* Load Tile (to texture memory)
+//! Kopies texture data from RDRAM to Texture Memory
+//-----------------------------------------------------------------------------
+void TextureLoader::loadTile(int tile, int s0, int t0, int s1, int t1)
+{
+    void (*Interleave)( void *mem, unsigned int numDWords );
+
+
+    //unsigned int tile   = _SHIFTR( ucode->w1, 24, 3 );
+
+    unsigned int address, height, bpl, line, y;
+    unsigned long long *dest;
+    unsigned char *src;
+
+    //Set new Tile Size
+    this->setTileSize(tile, s0, t0, s1, t1);
+    m_currentTile = &m_tiles[tile];
+
+    if (m_currentTile->line == 0)
+        return;
+
+    address = m_textureImage.address + m_currentTile->ult * m_textureImage.bpl + (m_currentTile->uls << m_textureImage.size >> 1);
+    dest = m_memory->getTextureMemory( m_currentTile->tmem );
+    bpl = (m_currentTile->lrs - m_currentTile->uls + 1) << m_currentTile->size >> 1;
+    height = m_currentTile->lrt - m_currentTile->ult + 1;
+    src = m_memory->getRDRAM(address);
+
+    if (((address + height * bpl) > m_memory->getRDRAMSize()) || (((m_currentTile->tmem << 3) + bpl * height) > 4096)) // Stay within TMEM
+    {
+        return;
+    }
+
+    // Line given for 32-bit is half what it seems it should since they split the
+    // high and low words. I'm cheating by putting them together.
+    if (m_currentTile->size == G_IM_SIZ_32b)
+    {
+        line = m_currentTile->line << 1;
+        Interleave = QWordInterleave;
+    }
+    else
+    {
+        line = m_currentTile->line;
+        Interleave = DWordInterleave;
+    }
+
+    for (y = 0; y < height; y++)
+    {
+        UnswapCopy( src, dest, bpl );
+        if (y & 1) Interleave( dest, line );
+
+        src += m_textureImage.bpl;
+         dest += line;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* Load Block (to texture memory)
+//! Kopies texture data from RDRAM to Texture Memory
+//-----------------------------------------------------------------------------
+void TextureLoader::loadBlock(int tile, int s0, int t0, int s1, int t1)
+{
+    unsigned int dxt = t1; 
+
+    //Set new Tile Size
+    this->setTileSize(tile, s0, t0, s1, t1);
+    m_currentTile = &m_tiles[tile];
+
+
+    unsigned int bytes = (s1 + 1) << m_currentTile->size >> 1;
+    unsigned int address = m_textureImage.address + t0 * m_textureImage.bpl + (s0 << m_textureImage.size >> 1);
+
+    if ((bytes == 0) || ((address + bytes) > m_memory->getRDRAMSize()) || (((m_currentTile->tmem << 3) + bytes) > 4096))
+    {
+        return;
+    }
+
+    unsigned long long* src = (unsigned long long*)m_memory->getRDRAM(address);
+    unsigned long long* dest = m_memory->getTextureMemory(m_currentTile->tmem);
+
+    unsigned int line = 0;
+
+    if (dxt > 0)
+    {
+        void (*Interleave)( void *mem, unsigned int numDWords );
+
+        line = (2047 + dxt) / dxt;
+        unsigned int bpl = line << 3;
+        unsigned int height = bytes / bpl;
+
+        if (m_currentTile->size == G_IM_SIZ_32b)
+            Interleave = QWordInterleave;
+        else
+            Interleave = DWordInterleave;
+
+        for (unsigned int y = 0; y < height; y++)
+        {
+            UnswapCopy( src, dest, bpl );
+            if (y & 1) Interleave( dest, line );
+
+            src += line;
+            dest += line;
+        }
+    }
+    else
+        UnswapCopy( src, dest, bytes );
+}
+
+//-----------------------------------------------------------------------------
+//* Load Texture Look up table (to texture memory)
+//! Kopies texture data from RDRAM to Texture Memory
+//-----------------------------------------------------------------------------
+void TextureLoader::loadTLUT(int tile, int s0, int t0, int s1, int t1)
+{
+    CRCCalculator2 crcCalculator;
+
+    //Set new Tile Size
+    this->setTileSize(tile, s0, t0, s1, t1);
+
+
+    unsigned short count   = (m_tiles[tile].lrs - m_tiles[tile].uls + 1) * (m_tiles[tile].lrt - m_tiles[tile].ult + 1);
+    unsigned int  address = m_textureImage.address + m_tiles[tile].ult * m_textureImage.bpl + (m_tiles[tile].uls << m_textureImage.size >> 1);
+
+    //Copy from rdram to texture memory
+    unsigned short *src = (unsigned short*)m_memory->getRDRAM(address);
+    unsigned short *dest = (unsigned short*)m_memory->getTextureMemory(m_tiles[tile].tmem);     
+
+    unsigned short pal = (m_tiles[tile].tmem - 256) >> 4;
+
+    int i = 0;
+    while (i < count)
+    {
+        for (unsigned short j = 0; (j < 16) && (i < count); j++, i++)
+        {
+            unsigned short color = swapword( src[i^1] );
+            *dest = color;
+            dest += 4;
+        }
+        
+
+        m_rdp->m_paletteCRC16[pal] = crcCalculator.calcPaletteCRC(0xFFFFFFFF, m_memory->getTextureMemory(256 + (pal << 4)), 16);
+        pal++;
+    }
+
+    m_rdp->m_paletteCRC256 = crcCalculator.calcCRC(0xFFFFFFFF, m_rdp->m_paletteCRC16, 64);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h
new file mode 100755 (executable)
index 0000000..78ad1c2
--- /dev/null
@@ -0,0 +1,154 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef TEXTURE_LOADER_H_
+#define TEXTURE_LOADER_H_
+
+#include "GBIDefs.h"
+
+//Forward declarations
+class Memory;
+class RDP;
+
+//*****************************************************************************
+//* TextureImage
+//! Used to store information about texture image
+//*****************************************************************************
+struct TextureImage
+{
+    unsigned int format;
+    unsigned int size;
+    unsigned int width;
+    unsigned int bpl;
+    unsigned int address;
+
+    //! Constructor
+    TextureImage()
+    {
+        format = size = width = bpl = 0;
+        address = 0;
+    }
+};
+
+//*****************************************************************************
+//* RDP Tile
+//! Struct used to store information used then loading textures.
+//*****************************************************************************
+struct RDPTile
+{
+    unsigned int format, size, line, tmem, palette;
+
+    union
+    {
+        struct
+        {
+            unsigned int mirrort : 1;
+            unsigned int clampt  : 1;
+            unsigned int pad0    : 30;
+            unsigned int mirrors : 1;
+            unsigned int clamps  : 1;
+            unsigned int pad1    : 30;
+        };
+        struct
+        {
+            unsigned int cmt, cms;
+        };
+    };
+
+    //FrameBuffer *frameBuffer;
+    unsigned int maskt, masks;   
+    unsigned int shiftt, shifts;
+    float fuls, fult, flrs, flrt; 
+    unsigned int uls, ult, lrs, lrt;   
+
+    unsigned int getWidth() { return lrs - uls + 1; }
+    unsigned int getHeight() { return lrt - ult + 1; }
+
+    //! Constructor
+    RDPTile()
+    {
+        format = size = line = tmem = palette = 0;
+        maskt = masks = 0;   
+        shiftt = shifts = 0;
+        fuls = fult = flrs = flrt = 0; 
+        uls = ult = lrs = lrt = 0;  
+    }
+};
+
+//*****************************************************************************
+//* Texture Loader
+//! Class for loading texturs from RDRAM to Texture Memory
+//*****************************************************************************
+class TextureLoader
+{
+public:
+
+    //Constructor / Destructor
+    TextureLoader();
+    ~TextureLoader();
+
+    bool initialize(RDP* rdp, Memory* memory);
+
+    //Set Texture Image
+    void setTextureImage(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress);
+
+    //Set Tile
+    void setTile(int format, int size, int line, int tmem, int tile, int palette, 
+                          int clampS, int clampT, int mirrorS, int mirrorT, int maskS, 
+                          int maskT, int shiftS, int shiftT);
+
+    //Set Tile Size
+    void setTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1);
+
+    //Load Tile
+    void loadTile(int tile, int s0, int t0, int s1, int t1);
+
+    //Load Block
+    void loadBlock(int tile, int s0, int t0, int s1, int t1);
+
+    //Load Texture Look up table
+    void loadTLUT(int tile, int s0, int t0, int s1, int t1);
+
+public:
+
+    //! Returns information about current texture image
+    TextureImage* getTextureImage()          { return &m_textureImage; }
+
+    //! Returns previusly loaded tile
+    RDPTile*      getCurrentTile()           { return m_currentTile;   }
+
+    //! Returns a tile
+    //! @param tile which of the eight tiles to return. 
+    RDPTile*      getTile(unsigned int tile) { return &m_tiles[tile];  }
+
+private:
+
+    Memory* m_memory;                //!< Pointer to Memory Manager
+    RDP*    m_rdp;                   //!< Pointer to Reality Signal Processor    
+
+    //Tiles
+    RDPTile      m_tiles[8];         //!< Eight tiles
+    RDPTile*     m_currentTile;      //!< Previusly loaded tile
+    TextureImage m_textureImage;     //!< Texture Image
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp
new file mode 100755 (executable)
index 0000000..a0d9c3b
--- /dev/null
@@ -0,0 +1,553 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+#include "DisplayListParser.h"
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP* UCode0::m_rsp = 0;   //!< Pointer to Reality Signal Processor 
+RDP* UCode0::m_rdp = 0;   //!< Pointer to Reality Drawing Processor 
+DisplayListParser* UCode0::m_displayListParser = 0;
+Memory* UCode0::m_memory = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode0::UCode0()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode0::~UCode0()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Initialize 
+//-----------------------------------------------------------------------------
+void UCode0::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
+{
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+    m_displayListParser = dlp;
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize GBI
+//! Assigns functions to the GBI
+//-----------------------------------------------------------------------------
+void UCode0::initializeGBI(GBI* gbi)
+{
+    // Set GeometryMode flags
+    GBI_InitFlags( F3D );    
+    
+    //GBI Command                            Command Value         Target          Command Function
+    GBI_SetGBI( GBI::G_SPNOOP,               F3D_SPNOOP,           gbi->m_cmds,    F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_MTX,                  F3D_MTX,              gbi->m_cmds,    F3D_Mtx );
+    GBI_SetGBI( GBI::G_RESERVED0,            F3D_RESERVED0,        gbi->m_cmds,    F3D_Reserved0 );
+    GBI_SetGBI( GBI::G_MOVEMEM,              F3D_MOVEMEM,          gbi->m_cmds,    F3D_MoveMem );
+    GBI_SetGBI( GBI::G_VTX,                  F3D_VTX,              gbi->m_cmds,    F3D_Vtx );
+    GBI_SetGBI( GBI::G_RESERVED1,            F3D_RESERVED1,        gbi->m_cmds,    F3D_Reserved1 );
+    GBI_SetGBI( GBI::G_DL,                   F3D_DL,               gbi->m_cmds,    F3D_DList );
+    GBI_SetGBI( GBI::G_RESERVED2,            F3D_RESERVED2,        gbi->m_cmds,    F3D_Reserved2 );
+    GBI_SetGBI( GBI::G_RESERVED3,            F3D_RESERVED3,        gbi->m_cmds,    F3D_Reserved3 );
+    GBI_SetGBI( GBI::G_SPRITE2D_BASE,        F3D_SPRITE2D_BASE,    gbi->m_cmds,    F3D_Sprite2D_Base );
+    GBI_SetGBI( GBI::G_MOVEWORD,             F3D_MOVEWORD,         gbi->m_cmds,    F3D_MoveWord );
+    GBI_SetGBI( GBI::G_TRI1,                 F3D_TRI1,             gbi->m_cmds,    F3D_Tri1 );
+    GBI_SetGBI( GBI::G_CULLDL,               F3D_CULLDL,           gbi->m_cmds,    F3D_CullDL );
+    GBI_SetGBI( GBI::G_POPMTX,               F3D_POPMTX,           gbi->m_cmds,    F3D_PopMtx );
+    GBI_SetGBI( GBI::G_TEXTURE,              F3D_TEXTURE,          gbi->m_cmds,    F3D_Texture );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,       F3D_SETOTHERMODE_H,   gbi->m_cmds,    F3D_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,       F3D_SETOTHERMODE_L,   gbi->m_cmds,    F3D_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_ENDDL,                F3D_ENDDL,            gbi->m_cmds,    F3D_EndDL );
+    GBI_SetGBI( GBI::G_SETGEOMETRYMODE,      F3D_SETGEOMETRYMODE,  gbi->m_cmds,    F3D_SetGeometryMode );
+    GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,    F3D_CLEARGEOMETRYMODE,gbi->m_cmds,    F3D_ClearGeometryMode );
+    GBI_SetGBI( GBI::G_QUAD,                 F3D_QUAD,             gbi->m_cmds,    F3D_Quad );
+    GBI_SetGBI( GBI::G_RDPHALF_1,            F3D_RDPHALF_1,        gbi->m_cmds,    F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_RDPHALF_2,            F3D_RDPHALF_2,        gbi->m_cmds,    F3D_RDPHalf_2 );
+    GBI_SetGBI( GBI::G_RDPHALF_CONT,         F3D_RDPHALF_CONT,     gbi->m_cmds,    F3D_RDPHalf_Cont );
+    GBI_SetGBI( GBI::G_TRI4,                 F3D_TRI4,             gbi->m_cmds,    F3D_Tri4 );
+}
+
+//*****************************************************************************
+// Matrix Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Add Matrix
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Mtx(MicrocodeArgument* ucode)
+{    
+    Logger::getSingleton().printMsg("F3D_Mtx", M64MSG_VERBOSE);
+    RSPUCodeAddMatrix0* temp = (RSPUCodeAddMatrix0*)ucode;
+
+    //Add matrix
+    m_rsp->RSP_Matrix( temp->segmentAddress, //Segment adress 
+                       temp->projection,     //Projection or view matrix?
+                       temp->push,           //Save Current Matrix?
+                       temp->load );         //Replace aka Load or Mult  
+}
+
+//-----------------------------------------------------------------------------
+//* Pop Matrix
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_PopMtx(MicrocodeArgument* ucode)
+{ 
+    Logger::getSingleton().printMsg("F3D_PopMtx", M64MSG_VERBOSE);
+
+    //Pop Matrix
+    m_rsp->RSP_PopMatrix();
+}
+
+//*****************************************************************************
+// Vertex Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Add Vertex
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Vtx(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Vtx", M64MSG_VERBOSE);
+    RSPUCodeAddVertices0* temp = (RSPUCodeAddVertices0*)ucode;
+
+    //Add vertex
+    m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices + 1, temp->firstVertex); 
+}
+
+//-----------------------------------------------------------------------------
+//* F3D Render 1 Triangle
+//! @param ucode instruction from displaylist with input data
+//! @todo Triangle flag?
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Tri1(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Tri1", M64MSG_VERBOSE);
+    RSPUCodeAddOneTriangleF3D* temp = (RSPUCodeAddOneTriangleF3D*)ucode;
+
+    //Add one triangle  //TODO Flag?
+    m_rsp->RSP_1Triangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10);
+}
+
+//-----------------------------------------------------------------------------
+//* F3D Render 4 Triangles
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Tri4(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Tri4", M64MSG_VERBOSE);
+    RSPUCodeAddFourTrianglesF3D* temp = (RSPUCodeAddFourTrianglesF3D*)ucode;
+
+    //Add four triangles
+    m_rsp->RSP_4Triangles( temp->v0, temp->v1, temp->v2,
+                           temp->v3, temp->v4, temp->v5,
+                           temp->v6, temp->v7, temp->v8,
+                           temp->v9, temp->v10, temp->v11);
+}
+
+//-----------------------------------------------------------------------------
+//* F3D Render 1 Quad
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Quad(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Quad", M64MSG_VERBOSE);
+    RSPUCodeAddOneQuadF3D* temp = (RSPUCodeAddOneQuadF3D*)ucode;
+
+    //Add one Quad
+    m_rsp->RSP_1Quadrangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10, temp->index3 / 10);
+}
+
+//*****************************************************************************
+// Display List Functions
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Display List
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_DList(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_DList", M64MSG_VERBOSE);
+    RSPUCodeDisplayList* temp = (RSPUCodeDisplayList*)ucode;
+
+    switch ( temp->param )
+    {
+        case G_DL_PUSH   : m_rsp->RSP_DisplayList( temp->segmentAddress ); break;
+        case G_DL_NOPUSH : m_rsp->RSP_BranchList( temp->segmentAddress );  break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* End Display List
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_EndDL(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_EndDL", M64MSG_VERBOSE);
+
+    //End Display List
+    m_rsp->RSP_EndDisplayList();    
+}
+
+//-----------------------------------------------------------------------------
+// Cull Display List
+//! @todo Cull Display List
+//-----------------------------------------------------------------------------
+void UCode0::F3D_CullDL(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_CullDL", M64MSG_VERBOSE);
+    //TODO
+}
+
+//*****************************************************************************
+// Texturing
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Texture
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Texture(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Texture", M64MSG_VERBOSE);
+    RSPUCodeTexture* temp = (RSPUCodeTexture*)ucode;
+
+    float scaleS  = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 ); 
+    float scaleT  = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 ); 
+    int on       = _SHIFTR( ucode->w0, 0, 8 );
+
+    m_rsp->RSP_Texture(scaleS, scaleT, (int)temp->level, (int)temp->tile, on);
+}
+
+//*****************************************************************************
+// Half
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Half 1
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_RDPHalf_1(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_RDPHalf_1", M64MSG_VERBOSE);
+    m_rdp->setHalf1( ucode->w1 );
+}
+
+//-----------------------------------------------------------------------------
+//* Half 2
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode0::F3D_RDPHalf_2(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_RDPHalf_2", M64MSG_VERBOSE);
+    m_rdp->setHalf2( ucode->w1 );
+}
+//-----------------------------------------------------------------------------
+// Half Cont
+//-----------------------------------------------------------------------------
+void UCode0::F3D_RDPHalf_Cont(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_RDPHalf_Cont", M64MSG_VERBOSE);
+    //Ignore
+}
+
+//*****************************************************************************
+// Geometry Mode
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Set Geometry Mode
+//-----------------------------------------------------------------------------
+void UCode0::F3D_SetGeometryMode(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_SetGeometryMode", M64MSG_VERBOSE);
+    m_rsp->RSP_SetGeometryMode(ucode->w1);
+}
+
+//-----------------------------------------------------------------------------
+// Clear Geometry Mode
+//-----------------------------------------------------------------------------
+void UCode0::F3D_ClearGeometryMode(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_ClearGeometryMode", M64MSG_VERBOSE);
+    m_rsp->RSP_ClearGeometryMode(ucode->w1);
+}
+
+//*****************************************************************************
+// Set Other Modes
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Set Other Mode H
+//-----------------------------------------------------------------------------
+void UCode0::F3D_SetOtherMode_H(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_SetOtherMode_H", M64MSG_VERBOSE);
+
+    unsigned int otherModeType = _SHIFTR(ucode->w0, 8, 8);
+    unsigned int w1             = ucode->w1;
+
+    switch ( otherModeType )
+    {
+        case G_MDSFT_PIPELINE:
+            //gDPPipelineMode( w1 >> G_MDSFT_PIPELINE );
+            break;
+        case G_MDSFT_CYCLETYPE:
+            m_rdp->setCycleType( G_CYCLE_TYPE(w1 >> G_MDSFT_CYCLETYPE) );
+            break;
+        
+        case G_MDSFT_TEXTPERSP:
+            //gDPSetTexturePersp( w1 >> G_MDSFT_TEXTPERSP );
+            break;
+        case G_MDSFT_TEXTDETAIL:
+            //gDPSetTextureDetail( w1 >> G_MDSFT_TEXTDETAIL );
+            break;
+        case G_MDSFT_TEXTLOD:
+            //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD );
+            break;        
+        case G_MDSFT_TEXTLUT:
+            m_rdp->setTextureLUT( w1 >> G_MDSFT_TEXTLUT );
+            break;
+        case G_MDSFT_TEXTFILT:
+            m_rdp->setTextureFiltering(w1 >> G_MDSFT_TEXTFILT);
+            break;
+        case G_MDSFT_TEXTCONV:
+            //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV );
+            break;
+        case G_MDSFT_COMBKEY:
+            //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY );
+            break;
+        case G_MDSFT_RGBDITHER:
+            //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER );
+            break;
+        case G_MDSFT_ALPHADITHER:
+            //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER );
+            break;
+        default:
+            unsigned int shift = _SHIFTR( ucode->w0, 8, 8 );
+            unsigned int length = _SHIFTR( ucode->w0, 0, 8 );
+            unsigned int mask = ((1 << length) - 1) << shift;
+            m_rdp->m_otherMode.h &= ~mask;
+            m_rdp->m_otherMode.h |= w1 & mask;
+            m_rdp->setUpdateCombiner(true);
+            break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Set Other Mode L
+//-----------------------------------------------------------------------------
+void UCode0::F3D_SetOtherMode_L(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_SetOtherMode_L", M64MSG_VERBOSE);
+    
+    switch (_SHIFTR( ucode->w0, 8, 8 ))
+    {
+        case G_MDSFT_ALPHACOMPARE:
+            m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE);
+            break;
+        case G_MDSFT_ZSRCSEL:
+            m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL );
+            break;
+        case G_MDSFT_RENDERMODE:
+            m_rdp->setRenderMode(ucode->w1);
+            break;
+        default:
+            unsigned int shift = _SHIFTR( ucode->w0, 8, 8 );
+            unsigned int length = _SHIFTR( ucode->w0, 0, 8 );
+            unsigned int mask = ((1 << length) - 1) << shift;
+
+            m_rdp->m_otherMode.l &= ~mask;
+            m_rdp->m_otherMode.l |= ucode->w1 & mask;
+            break;
+    }
+}
+
+
+//*****************************************************************************
+// Other
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//* Move Mem
+//! @todo Add more case in switch, Like Force Matrix
+//-----------------------------------------------------------------------------
+void UCode0::F3D_MoveMem(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_MoveMem", M64MSG_VERBOSE);
+
+    unsigned int type    = ((ucode->w0)>>16)&0xFF;
+    unsigned int segmentAddress = ucode->w1;
+
+    switch (type) 
+    {
+        //Viewport
+        case F3D_MV_VIEWPORT:               
+            m_rsp->moveMemViewport(segmentAddress);
+            break;
+
+        case G_MV_MATRIX_1:
+            m_rsp->RSP_ForceMatrix(segmentAddress);    
+            m_displayListParser->increasePC(24); //// force matrix takes four commands
+            break;
+
+        //Lights
+        case G_MV_L0: m_rsp->RSP_Light(0, segmentAddress); break;
+        case G_MV_L1: m_rsp->RSP_Light(1, segmentAddress); break;
+        case G_MV_L2: m_rsp->RSP_Light(2, segmentAddress); break;
+        case G_MV_L3: m_rsp->RSP_Light(3, segmentAddress); break;
+        case G_MV_L4: m_rsp->RSP_Light(4, segmentAddress); break;
+        case G_MV_L5: m_rsp->RSP_Light(5, segmentAddress); break;
+        case G_MV_L6: m_rsp->RSP_Light(6, segmentAddress); break;
+        case G_MV_L7: m_rsp->RSP_Light(7, segmentAddress); break;
+
+        //Look at
+        case G_MV_LOOKATX:
+            //IGNORE
+            break;
+        //Look at
+        case G_MV_LOOKATY:
+            //IGNORE
+            break;
+
+        //case RSP_GBI1_MV_MEM_LOOKATY:
+        //    //IGNORE
+        //    break;
+        //case RSP_GBI1_MV_MEM_LOOKATX:
+        //    //IGNORE
+        //    break;
+
+        //TODO?
+        //case RSP_GBI1_MV_MEM_TXTATT:    break;
+        //case RSP_GBI1_MV_MEM_MATRIX_1:  
+        //  RSP_GFX_Force_Matrix(addr);
+        //    break;    
+        //case RSP_GBI1_MV_MEM_MATRIX_2: break;
+        //case RSP_GBI1_MV_MEM_MATRIX_3: break;
+        //case RSP_GBI1_MV_MEM_MATRIX_4: break;
+        
+        default:
+            Logger::getSingleton().printMsg("F3D_MoveMem: Unknown type", M64MSG_WARNING); 
+            break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//* F3D Sprite2D Base
+//! @todo F3D Sprite2D Base
+//-----------------------------------------------------------------------------
+void UCode0::F3D_Sprite2D_Base(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_Sprite2D_Base - Unimplemented", M64MSG_WARNING);
+    //TODO
+}
+
+//-----------------------------------------------------------------------------
+// Move Word
+//-----------------------------------------------------------------------------
+void UCode0::F3D_MoveWord(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3D_MoveWord");
+    RSPUCodeMoveWordF3D* temp = (RSPUCodeMoveWordF3D*)ucode;
+
+    switch ( temp->type ) 
+    {
+        case G_MW_MATRIX: 
+            m_rsp->RSP_InsertMatrix(temp->offset, temp->value); 
+            break;
+
+        case G_MW_FOG:              
+            m_rsp->RSP_FogFactor( (short)temp->fm, (short)temp->fo );
+            break;
+
+        case G_MW_NUMLIGHT: 
+            m_rsp->RSP_NumLights( (unsigned int)(((ucode->w1 - 0x80000000) >> 5) - 1) );            
+            break;
+
+        case G_MW_SEGMENT:                                
+            m_rsp->moveSegment((temp->offset >> 2) & 0xF, temp->value);              
+            break;
+
+        case G_MW_LIGHTCOL: 
+            if ( (temp->offset & 0x7) == 0 ) 
+            {
+                m_rsp->RSP_LightColor(temp->offset / 0x20, temp->value);
+            }
+            break;
+
+        case G_MW_POINTS:    
+            m_rsp->RSP_ModifyVertex( _SHIFTR( ucode->w0, 8, 16 ) / 40, _SHIFTR( ucode->w0, 0, 8 ) % 40, ucode->w1);
+            break;
+
+        case G_MW_CLIP: 
+            //gSPClipRatio( w1 );
+            break;
+
+        case G_MW_PERSPNORM: 
+            //gSPPerspNormalize( w1 ); 
+            break;
+    }    
+}
+
+//*****************************************************************************
+// Non important functions
+//*****************************************************************************
+
+void UCode0::F3D_SPNoOp(MicrocodeArgument* ucode){ 
+    Logger::getSingleton().printMsg("F3D_SPNoOp", M64MSG_VERBOSE);   
+
+    //If next command is a no-operation then skip displaylist for some ucodes. 
+    //if( (ucode+1)->words.cmd == 0x00 && gRSP.ucode >= 17 )
+    //{
+    //  m_rsp->RSP_EndDisplayList();       
+    //}
+}
+
+void UCode0::F3D_Reserved0(MicrocodeArgument* ucode) {
+    Logger::getSingleton().printMsg("F3D_Reserved0", M64MSG_VERBOSE);
+}
+
+void UCode0::F3D_Reserved1(MicrocodeArgument* ucode){
+    Logger::getSingleton().printMsg("F3D_Reserved1", M64MSG_VERBOSE);
+}
+
+void UCode0::F3D_Reserved2(MicrocodeArgument* ucode){
+    Logger::getSingleton().printMsg("F3D_Reserved2", M64MSG_VERBOSE);
+}
+
+void UCode0::F3D_Reserved3(MicrocodeArgument* ucode){
+    Logger::getSingleton().printMsg("F3D_Reserved3", M64MSG_VERBOSE);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h
new file mode 100755 (executable)
index 0000000..f802fe7
--- /dev/null
@@ -0,0 +1,168 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_0_H_
+#define UCODE_0_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+class DisplayListParser;
+
+//Definitions
+#define F3D_MTX_STACKSIZE       10
+
+#define F3D_MTX_MODELVIEW       0x00
+#define F3D_MTX_PROJECTION      0x01
+#define F3D_MTX_MUL             0x00
+#define F3D_MTX_LOAD            0x02
+#define F3D_MTX_NOPUSH          0x00
+#define F3D_MTX_PUSH            0x04
+
+#define F3D_TEXTURE_ENABLE      0x00000002
+#define F3D_SHADING_SMOOTH      0x00000200
+#define F3D_CULL_FRONT          0x00001000
+#define F3D_CULL_BACK           0x00002000
+#define F3D_CULL_BOTH           0x00003000
+#define F3D_CLIPPING            0x00000000
+
+#define F3D_MV_VIEWPORT         0x80
+
+#define F3D_MWO_aLIGHT_1        0x00
+#define F3D_MWO_bLIGHT_1        0x04
+#define F3D_MWO_aLIGHT_2        0x20
+#define F3D_MWO_bLIGHT_2        0x24
+#define F3D_MWO_aLIGHT_3        0x40
+#define F3D_MWO_bLIGHT_3        0x44
+#define F3D_MWO_aLIGHT_4        0x60
+#define F3D_MWO_bLIGHT_4        0x64
+#define F3D_MWO_aLIGHT_5        0x80
+#define F3D_MWO_bLIGHT_5        0x84
+#define F3D_MWO_aLIGHT_6        0xa0
+#define F3D_MWO_bLIGHT_6        0xa4
+#define F3D_MWO_aLIGHT_7        0xc0
+#define F3D_MWO_bLIGHT_7        0xc4
+#define F3D_MWO_aLIGHT_8        0xe0
+#define F3D_MWO_bLIGHT_8        0xe4
+
+// FAST3D commands
+#define F3D_SPNOOP              0x00
+#define F3D_MTX                 0x01
+#define F3D_RESERVED0           0x02
+#define F3D_MOVEMEM             0x03
+#define F3D_VTX                 0x04
+#define F3D_RESERVED1           0x05
+#define F3D_DL                  0x06
+#define F3D_RESERVED2           0x07
+#define F3D_RESERVED3           0x08
+#define F3D_SPRITE2D_BASE       0x09
+
+#define F3D_TRI1                0xBF
+#define F3D_CULLDL              0xBE
+#define F3D_POPMTX              0xBD
+#define F3D_MOVEWORD            0xBC
+#define F3D_TEXTURE             0xBB
+#define F3D_SETOTHERMODE_H      0xBA
+#define F3D_SETOTHERMODE_L      0xB9
+#define F3D_ENDDL               0xB8
+#define F3D_SETGEOMETRYMODE     0xB7
+#define F3D_CLEARGEOMETRYMODE   0xB6
+//#define F3D_LINE3D              0xB5 // Only used in Line3D
+#define F3D_QUAD                0xB5
+#define F3D_RDPHALF_1           0xB4
+#define F3D_RDPHALF_2           0xB3
+#define F3D_RDPHALF_CONT        0xB2
+#define F3D_TRI4                0xB1
+
+//*****************************************************************************
+//! UCode0 (aka F3D - Fast 3D)
+//! Microcode used for Super Mario 64!!!
+//*****************************************************************************
+class UCode0
+{
+public:
+
+    UCode0();
+    ~UCode0();
+
+    static void initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp);
+    static void initializeGBI(GBI* gbi);
+
+public:
+
+    // Matrix Functions
+    static void F3D_Mtx(MicrocodeArgument* ucode);
+    static void F3D_PopMtx(MicrocodeArgument* ucode);
+
+    //Vertex and indices
+    static void F3D_Vtx(MicrocodeArgument* ucode);
+    static void F3D_Tri1(MicrocodeArgument* ucode);
+    static void F3D_Tri4(MicrocodeArgument* ucode);
+    static void F3D_Quad(MicrocodeArgument* ucode);
+
+    //Display list
+    static void F3D_DList(MicrocodeArgument* ucode);
+    static void F3D_EndDL(MicrocodeArgument* ucode);
+    static void F3D_CullDL(MicrocodeArgument* ucode);  //Unimplemented
+
+    // Texture
+    static void F3D_Texture(MicrocodeArgument* ucode);
+
+    // Half
+    static void F3D_RDPHalf_1(MicrocodeArgument* ucode);
+    static void F3D_RDPHalf_2(MicrocodeArgument* ucode);
+    static void F3D_RDPHalf_Cont(MicrocodeArgument* ucode);  //Unimplmeneted
+
+    // Geometry Mode
+    static void F3D_SetGeometryMode(MicrocodeArgument* ucode);
+    static void F3D_ClearGeometryMode(MicrocodeArgument* ucode);
+
+    // Set Other Modes
+    static void F3D_SetOtherMode_H(MicrocodeArgument* ucode);
+    static void F3D_SetOtherMode_L(MicrocodeArgument* ucode);
+    
+    // Other
+    static void F3D_MoveMem(MicrocodeArgument* ucode);
+    static void F3D_MoveWord(MicrocodeArgument* ucode);
+    static void F3D_Sprite2D_Base(MicrocodeArgument* ucode);  //Unimplemented
+
+    //Unimportant
+    static void F3D_SPNoOp(MicrocodeArgument* ucode);    
+    static void F3D_Reserved0(MicrocodeArgument* ucode);    
+    static void F3D_Reserved1(MicrocodeArgument* ucode);
+    static void F3D_Reserved2(MicrocodeArgument* ucode);
+    static void F3D_Reserved3(MicrocodeArgument* ucode);
+
+private:
+
+    static RSP* m_rsp;                              //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;                              //!< Pointer to Reality Drawing Processor  
+    static Memory* m_memory;                        //!< Pointer to Memory Manager
+    static DisplayListParser* m_displayListParser;  //!< Pointer to Display List Parser
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp
new file mode 100755 (executable)
index 0000000..303ebd0
--- /dev/null
@@ -0,0 +1,238 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode1.h"
+#include "UCode0.h"
+
+//Forward declaration
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP*    UCode1::m_rsp    = 0;   //!< Pointer to Reality Signal Processor 
+RDP*    UCode1::m_rdp    = 0;   //!< Pointer to Reality Drawing Processor 
+Memory* UCode1::m_memory = 0;
+GBI*    UCode1::m_gbi    = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode1::UCode1()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode1::~UCode1()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode1::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory)
+{
+    m_gbi = gbi;
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode1::initializeGBI()
+{
+    // Set GeometryMode flags
+    GBI_InitFlags( F3DEX );
+
+    //          GBI Command              Command Value            //Target          Command Function
+    GBI_SetGBI( GBI::G_SPNOOP,           F3D_SPNOOP,              m_gbi->m_cmds,    UCode0::F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_MTX,              F3D_MTX,                 m_gbi->m_cmds,    UCode0::F3D_Mtx );
+    GBI_SetGBI( GBI::G_RESERVED0,        F3D_RESERVED0,           m_gbi->m_cmds,    UCode0::F3D_Reserved0 );
+    GBI_SetGBI( GBI::G_MOVEMEM,          F3D_MOVEMEM,             m_gbi->m_cmds,    UCode0::F3D_MoveMem );
+    GBI_SetGBI( GBI::G_VTX,              F3D_VTX,                 m_gbi->m_cmds,    F3DEX_Vtx );
+    GBI_SetGBI( GBI::G_RESERVED1,        F3D_RESERVED1,           m_gbi->m_cmds,    UCode0::F3D_Reserved1 );
+    GBI_SetGBI( GBI::G_DL,               F3D_DL,                  m_gbi->m_cmds,    UCode0::F3D_DList );
+    GBI_SetGBI( GBI::G_RESERVED2,        F3D_RESERVED2,           m_gbi->m_cmds,    UCode0::F3D_Reserved2 );
+    GBI_SetGBI( GBI::G_RESERVED3,        F3D_RESERVED3,           m_gbi->m_cmds,    UCode0::F3D_Reserved3 );
+    GBI_SetGBI( GBI::G_SPRITE2D_BASE,    F3D_SPRITE2D_BASE,       m_gbi->m_cmds,    UCode0::F3D_Sprite2D_Base );
+    GBI_SetGBI( GBI::G_TRI1,             F3D_TRI1,                m_gbi->m_cmds,    F3DEX_Tri1 );
+    GBI_SetGBI( GBI::G_CULLDL,           F3D_CULLDL,              m_gbi->m_cmds,    F3DEX_CullDL );
+    GBI_SetGBI( GBI::G_POPMTX,           F3D_POPMTX,              m_gbi->m_cmds,    UCode0::F3D_PopMtx );
+    GBI_SetGBI( GBI::G_MOVEWORD,         F3D_MOVEWORD,            m_gbi->m_cmds,    UCode0::F3D_MoveWord );
+    GBI_SetGBI( GBI::G_TEXTURE,          F3D_TEXTURE,             m_gbi->m_cmds,    UCode0::F3D_Texture );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,   F3D_SETOTHERMODE_H,      m_gbi->m_cmds,    UCode0::F3D_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,   F3D_SETOTHERMODE_L,      m_gbi->m_cmds,    UCode0::F3D_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_ENDDL,            F3D_ENDDL,               m_gbi->m_cmds,    UCode0::F3D_EndDL );
+    GBI_SetGBI( GBI::G_SETGEOMETRYMODE,  F3D_SETGEOMETRYMODE,     m_gbi->m_cmds,    UCode0::F3D_SetGeometryMode );
+    GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE,   m_gbi->m_cmds,    UCode0::F3D_ClearGeometryMode );
+    GBI_SetGBI( GBI::G_QUAD,             F3D_QUAD,                m_gbi->m_cmds,    F3DEX_Quad );
+    GBI_SetGBI( GBI::G_RDPHALF_1,        F3D_RDPHALF_1,           m_gbi->m_cmds,    UCode0::F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_RDPHALF_2,        F3D_RDPHALF_2,           m_gbi->m_cmds,    UCode0::F3D_RDPHalf_2 );
+    GBI_SetGBI( GBI::G_MODIFYVTX,        F3DEX_MODIFYVTX,         m_gbi->m_cmds,    F3DEX_ModifyVtx );
+    GBI_SetGBI( GBI::G_TRI2,             F3DEX_TRI2,              m_gbi->m_cmds,    F3DEX_Tri2 );
+    GBI_SetGBI( GBI::G_BRANCH_Z,         F3DEX_BRANCH_Z,          m_gbi->m_cmds,    F3DEX_Branch_Z );
+    GBI_SetGBI( GBI::G_LOAD_UCODE,       F3DEX_LOAD_UCODE,        m_gbi->m_cmds,    F3DEX_Load_uCode );
+}
+
+//-----------------------------------------------------------------------------
+//! Load UCode
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Load_uCode(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_Load_uCode - experimental", M64MSG_WARNING);
+    RSPUCodeLoadUCode* temp = (RSPUCodeLoadUCode*)ucode;
+
+    //unsigned int ucodeDataStart1 = m_memory->getRDRAMAddress( (*(unsigned int*)( m_memory->getRDRAM(pc-12))  );
+    unsigned int ucodeDataStart2 = m_rdp->getHalf1();
+
+    //if ( ucodeDataStart1 != ucodeDataStart2 )
+    //{
+    //    Logger::getSingleton().printMsg("Warning - UCode Data Start differs", M64MSG_INFO);
+    //}
+
+    //Select UCode
+    m_gbi->selectUCode( temp->ucodeStart,        //UCodeStart 
+                        ucodeDataStart2,         //UCodeDataStart
+                        temp->ucodeSize+1,       //UCodeSize
+                        8);                      //UCodeDataSize  //Always 8 ???                  
+}
+
+//-----------------------------------------------------------------------------
+//! Add Vertices
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Vtx(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_Vtx", M64MSG_VERBOSE);
+    RSPUCodeAddVertices1* temp = (RSPUCodeAddVertices1*)ucode;
+
+    //Add Vertices
+    m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->firstVertex);
+}
+
+//-----------------------------------------------------------------------------
+//! Modify Vertex
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_ModifyVtx(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_ModifyVtx", M64MSG_VERBOSE);
+    RSPUCodeModifyVertex* temp = (RSPUCodeModifyVertex*)ucode;
+
+    switch ( temp->modifyType )
+    {
+        case G_MWO_POINT_RGBA:
+            m_rsp->RSP_SetVertexColor( temp->vertexIndex, 
+                                       temp->r/255.0f, 
+                                       temp->g/255.0f, 
+                                       temp->b/255.0f, 
+                                       temp->a/255.0f );
+            break;
+        case G_MWO_POINT_ST:
+            m_rsp->RSP_SetVertexTexCoord(temp->vertexIndex, 
+                                         temp->t / 32.0f, 
+                                         temp->s / 32.0f );
+            break;
+        case G_MWO_POINT_XYSCREEN:
+            break;
+        case G_MWO_POINT_ZSCREEN:
+            break;
+    };
+}
+
+//-----------------------------------------------------------------------------
+//! Add 1 Triangle
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Tri1(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_Tri1", M64MSG_VERBOSE);
+    RSPUCodeAddOneTriangleF3DEX* temp = (RSPUCodeAddOneTriangleF3DEX*)ucode;
+
+    //Add one triangle 
+    m_rsp->RSP_1Triangle(temp->index0, temp->index1, temp->index2);
+}
+
+//-----------------------------------------------------------------------------
+//! Add 2 Triangles
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Tri2(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_Tri2", M64MSG_VERBOSE);
+    RSPUCodeAddTwoTrianglesF3DEX* temp = (RSPUCodeAddTwoTrianglesF3DEX*)ucode;
+
+    //Add two triangles
+    m_rsp->RSP_2Triangles( temp->v0, temp->v1, temp->v2, 0,
+                           temp->v3, temp->v4, temp->v5, 0);
+}
+
+//-----------------------------------------------------------------------------
+//! Add 1 Quadrangle
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Quad( MicrocodeArgument* ucode )
+{
+    Logger::getSingleton().printMsg("F3DEX_Quad", M64MSG_VERBOSE);
+    RSPUCodeAddOneQuadF3DEX* temp = (RSPUCodeAddOneQuadF3DEX*)ucode;
+
+    //Add one Quad
+    m_rsp->RSP_1Quadrangle(temp->index0, temp->index1, temp->index2, temp->index3);
+}
+
+//-----------------------------------------------------------------------------
+//! Cull Display List
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_CullDL(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned )
+    {
+        Logger::getSingleton().printMsg("F3DEX_CullDL - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+    RSPUCodeCullDisplayList* temp = (RSPUCodeCullDisplayList*)ucode;
+
+    //Cull display list?
+    m_rsp->RSP_CullDisplayList( temp->vertexIndex, temp->numVerticies  );
+}
+
+//-----------------------------------------------------------------------------
+//! Branch Z
+//-----------------------------------------------------------------------------
+void UCode1::F3DEX_Branch_Z(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("F3DEX_Branch_Z", M64MSG_VERBOSE);
+    RSPUCodeBranchZF3DEX* temp = (RSPUCodeBranchZF3DEX*)ucode;
+
+    //Branch Display List?
+    m_rsp->RSP_BranchLessZ(m_rdp->getHalf1(), temp->vertex, (float)(int)temp->zvalue );
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h
new file mode 100755 (executable)
index 0000000..2b4087f
--- /dev/null
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_1_H_
+#define UCODE_1_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+#define F3DEX_MTX_STACKSIZE        18
+
+#define F3DEX_MTX_MODELVIEW        0x00
+#define F3DEX_MTX_PROJECTION    0x01
+#define F3DEX_MTX_MUL            0x00
+#define F3DEX_MTX_LOAD            0x02
+#define F3DEX_MTX_NOPUSH        0x00
+#define F3DEX_MTX_PUSH            0x04
+
+#define F3DEX_TEXTURE_ENABLE    0x00000002
+#define F3DEX_SHADING_SMOOTH    0x00000200
+#define F3DEX_CULL_FRONT        0x00001000
+#define F3DEX_CULL_BACK            0x00002000
+#define F3DEX_CULL_BOTH            0x00003000
+#define F3DEX_CLIPPING            0x00800000
+
+#define F3DEX_MV_VIEWPORT        0x80
+
+#define F3DEX_MWO_aLIGHT_1        0x00
+#define F3DEX_MWO_bLIGHT_1        0x04
+#define F3DEX_MWO_aLIGHT_2        0x20
+#define F3DEX_MWO_bLIGHT_2        0x24
+#define F3DEX_MWO_aLIGHT_3        0x40
+#define F3DEX_MWO_bLIGHT_3        0x44
+#define F3DEX_MWO_aLIGHT_4        0x60
+#define F3DEX_MWO_bLIGHT_4        0x64
+#define F3DEX_MWO_aLIGHT_5        0x80
+#define F3DEX_MWO_bLIGHT_5        0x84
+#define F3DEX_MWO_aLIGHT_6        0xa0
+#define F3DEX_MWO_bLIGHT_6        0xa4
+#define F3DEX_MWO_aLIGHT_7        0xc0
+#define F3DEX_MWO_bLIGHT_7        0xc4
+#define F3DEX_MWO_aLIGHT_8        0xe0
+#define F3DEX_MWO_bLIGHT_8        0xe4
+
+// F3DEX commands
+#define F3DEX_MODIFYVTX                0xB2
+#define F3DEX_TRI2                    0xB1
+#define F3DEX_BRANCH_Z                0xB0
+#define F3DEX_LOAD_UCODE            0xAF // 0xCF
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+
+//*****************************************************************************
+//! UCode1 (aka F3DEX - Fast 3D EX)
+//! Microcode used for most games
+//*****************************************************************************
+class UCode1
+{
+public:
+
+    UCode1();
+    ~UCode1();
+
+    static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory);
+    static void initializeGBI();
+
+    static void F3DEX_Load_uCode(MicrocodeArgument* ucode);
+    static void F3DEX_Vtx(MicrocodeArgument* ucode);
+    static void F3DEX_ModifyVtx(MicrocodeArgument* ucode);
+    static void F3DEX_Tri1(MicrocodeArgument* ucode);    
+    static void F3DEX_Tri2(MicrocodeArgument* ucode);
+    static void F3DEX_Quad(MicrocodeArgument* ucode);
+    static void F3DEX_CullDL(MicrocodeArgument* ucode);
+    static void F3DEX_Branch_Z(MicrocodeArgument* ucode);    
+
+private:
+
+    static GBI* m_gbi;        //!< Graphics Binary Interface
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;        //!< Pointer to Reality Drawing Processor  
+    static Memory* m_memory;  //!< Pointer accessing memory like RDRAM and Texture Memory
+
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp
new file mode 100755 (executable)
index 0000000..50776d6
--- /dev/null
@@ -0,0 +1,219 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode10.h"
+#include "UCode5.h"
+
+//Forward declaration
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+#include "DisplayListParser.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+
+
+#define CONKER_BFD_ADD_VERTICES 1   /*F3DEX2_VTX ?*/ 
+
+#define RSP_MOVE_WORD_MATRIX        0x00    // NOTE: also used by movemem 
+#define RSP_MOVE_WORD_NUMLIGHT      0x02
+#define RSP_MOVE_WORD_CLIP          0x04
+#define RSP_MOVE_WORD_SEGMENT       0x06
+#define RSP_MOVE_WORD_FOG           0x08
+#define RSP_MOVE_WORD_LIGHTCOL      0x0a
+#define RSP_MOVE_WORD_POINTS        0x0c
+#define RSP_MOVE_WORD_PERSPNORM     0x0e
+
+#define RSP_GBI2_MV_MEM__VIEWPORT   8
+#define RSP_GBI2_MV_MEM__LIGHT      10
+#define RSP_GBI2_MV_MEM__POINT      12
+#define RSP_GBI2_MV_MEM__MATRIX     14    /* NOTE: this is in moveword table */
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP*    UCode10::m_rsp    = 0;   //!< Pointer to Reality Signal Processor 
+RDP*    UCode10::m_rdp    = 0;   //!< Pointer to Reality Drawing Processor 
+Memory* UCode10::m_memory = 0;
+GBI*    UCode10::m_gbi    = 0;
+DisplayListParser* UCode10::m_displayListParser = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode10::UCode10()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode10::~UCode10()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode10::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp)
+{
+    m_gbi = gbi;
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = mem;
+    m_displayListParser = dlp;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode10::initializeGBI()
+{
+    //Load F3DEX
+    UCode5::initializeGBI();
+
+    GBI_SetGBI( GBI::G_VTX,      CONKER_BFD_ADD_VERTICES,      m_gbi->m_cmds,       ConkerBFD_Vertex );
+    GBI_SetGBI( GBI::G_TRI4,     0x10,                         m_gbi->m_cmds,       ConkerBFD_Vertex );
+    GBI_SetGBI( GBI::G_TRI4,     0x11,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x12,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x13,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x14,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x15,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x16,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x17,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x18,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x19,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1a,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1b,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1c,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1d,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1e,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_TRI4,     0x1f,                         m_gbi->m_cmds,       ConkerBFD_Add4Triangles );
+    GBI_SetGBI( GBI::G_MOVEWORD, F3DEX2_MOVEWORD,              m_gbi->m_cmds,       ConkerBFD_MoveWord );
+    GBI_SetGBI( GBI::G_MOVEMEM,  F3DEX2_MOVEMEM,               m_gbi->m_cmds,       ConkerBFD_MoveMem );
+}
+
+//-----------------------------------------------------------------------------
+//! Conker Bad Fur Day Vertex
+//-----------------------------------------------------------------------------
+void UCode10::ConkerBFD_Vertex(MicrocodeArgument* ucode)
+{
+    unsigned int vertexEnd   = (((ucode->w0)   )&0xFFF)/2;
+    unsigned int numVertices = (((ucode->w0)>>12)&0xFFF);
+
+    //Add Vertices
+    m_rsp->getVertexMgr()->addConkerVertices( ucode->w1, numVertices, vertexEnd - numVertices );
+   // m_rsp->RSP_Vertex( ucode->w1, numVertices, vertexEnd - numVertices); 
+}
+
+//-----------------------------------------------------------------------------
+//! Conker Bad Fur Day Add Four Triangles
+//-----------------------------------------------------------------------------
+void UCode10::ConkerBFD_Add4Triangles(MicrocodeArgument* ucode)
+{
+    unsigned int w0 = ucode->w0;
+    unsigned int w1 = ucode->w1;
+
+    unsigned int idx[12];
+    idx[0]  = (w1   )&0x1F;    //Tri1
+    idx[1]  = (w1>> 5)&0x1F;
+    idx[2]  = (w1>>10)&0x1F;
+    idx[3]  = (w1>>15)&0x1F;   //Tri2
+    idx[4]  = (w1>>20)&0x1F;
+    idx[5]  = (w1>>25)&0x1F;
+    idx[6]  = (w0    )&0x1F;   //Tri3
+    idx[7]  = (w0>> 5)&0x1F;
+    idx[8]  = (w0>>10)&0x1F;
+    idx[9]  = (((w0>>15)&0x7)<<2)|(w1>>30);  //Tri4
+    idx[10] = (w0>>18)&0x1F;
+    idx[11] = (w0>>23)&0x1F;
+
+    //Add Triagles
+    m_rsp->RSP_1Triangle(idx[0], idx[1], idx[2]);
+    m_rsp->RSP_1Triangle(idx[3], idx[4], idx[5]);
+    m_rsp->RSP_1Triangle(idx[6], idx[7], idx[8]);
+    m_rsp->RSP_1Triangle(idx[9], idx[10], idx[11]);
+
+    unsigned int* RDRAMu32 = m_memory->getRDRAMint32();
+
+    //Get next command        
+    MicrocodeArgument* ucodeNext =  (MicrocodeArgument*)&RDRAMu32[(m_displayListParser->getPC()>>2)];
+
+    //Conker Bad Fur Day Render Fix (because conker has multiple Tri4)
+    ucode->cmd = GBI::G_TRI4;
+    if ( ucodeNext->cmd >= 0x10 && ucodeNext->cmd <= 0x1f )
+    {
+        ucodeNext->cmd = GBI::G_TRI4; 
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Conker Bad Fur Day Move Word
+//-----------------------------------------------------------------------------
+void UCode10::ConkerBFD_MoveWord(MicrocodeArgument* ucode)
+{
+    unsigned int dwType   = ((ucode->w0) >> 16) & 0xFF;
+
+    if( dwType == RSP_MOVE_WORD_NUMLIGHT )
+    {
+        m_rsp->RSP_NumLights( ((ucode->w1)/48) );
+    }
+    else
+    {
+        UCode5::F3DEX2_MoveWord(ucode);
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Conker Bad Fur Day Move Memory
+//-----------------------------------------------------------------------------
+void UCode10::ConkerBFD_MoveMem(MicrocodeArgument* ucode)
+{
+    unsigned int dwType = ((ucode->w0)     ) & 0xFE;
+    unsigned int dwAddr =  ucode->w1;     //RSPSegmentAddr((gfx->words.w1));
+
+    switch ( dwType )
+    {
+        case RSP_GBI2_MV_MEM__MATRIX:
+            m_rsp->getVertexMgr()->setConkerAddress(dwAddr);
+            break;
+
+        case RSP_GBI2_MV_MEM__LIGHT:
+            {
+                unsigned int dwOffset2 = ((ucode->w0) >> 5) & 0x3FFF;
+                if( dwOffset2 >= 0x30 )
+                {
+                    m_rsp->RSP_Light(((dwOffset2 - 0x30)/0x30), dwAddr);
+                }
+                else
+                {
+                    //FIX ME
+                }
+            }
+            break;
+
+        default:
+            UCode5::F3DEX2_MoveMem(ucode);
+            break;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h
new file mode 100755 (executable)
index 0000000..dddd61d
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_10_H_
+#define UCODE_10_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+class DisplayListParser;
+
+//*****************************************************************************
+//! UCode10
+//! Microcode used for Conker's Bad Fur Day
+//*****************************************************************************
+class UCode10
+{
+public:
+
+    UCode10();
+    ~UCode10();
+
+    static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp);
+    static void initializeGBI();
+
+    static void ConkerBFD_Vertex(MicrocodeArgument* ucode);
+    static void ConkerBFD_Add4Triangles(MicrocodeArgument* ucode);
+    static void ConkerBFD_MoveWord(MicrocodeArgument* ucode);
+    static void ConkerBFD_MoveMem(MicrocodeArgument* ucode);
+
+private:
+
+    static GBI* m_gbi;        //!< Graphics Binary Interface
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;        //!< Pointer to Reality Drawing Processor  
+    static Memory* m_memory;  //!< Pointer accessing memory like RDRAM and Texture Memory
+    static DisplayListParser* m_displayListParser;
+
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp
new file mode 100755 (executable)
index 0000000..21fe1e9
--- /dev/null
@@ -0,0 +1,110 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode2.h"
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+#include "Memory.h"
+#include "DisplayListParser.h"
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+GBI*               UCode2::m_gbi = 0;   //!< Pointer to Graphics Binary Interface
+RSP*               UCode2::m_rsp = 0;   //!< Pointer to Reality Signal Processor 
+RDP*               UCode2::m_rdp = 0;   //!< Pointer to Reality Drawing Processor 
+Memory*            UCode2::m_memory            = 0;
+DisplayListParser* UCode2::m_displayListParser = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode2::UCode2()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode2::~UCode2()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Initialize 
+//-----------------------------------------------------------------------------
+void UCode2::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp)
+{
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_gbi = gbi;
+    m_memory = mem;
+    m_displayListParser = dlp;
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize GBI
+//! Assigns functions to the GBI
+//-----------------------------------------------------------------------------
+void UCode2::initializeGBI()
+{
+    UCode0::initializeGBI(m_gbi);
+    GBI_SetGBI(GBI::G_RDPHALF_1, F3D_RDPHALF_1, m_gbi->m_cmds, renderSky);
+}
+
+//-----------------------------------------------------------------------------
+//* RDP Half 1 With Sky Rendering
+//! Render Sky
+//! @todo Set Half 1 also?
+//! @todo Use extracted color
+//! @todo set x0 and x1
+//-----------------------------------------------------------------------------
+void UCode2::renderSky(MicrocodeArgument* ucode)
+{    
+    //Check for error
+    if ( (ucode->w1)>>24 != 0xCE )
+    {
+        return;
+    }
+
+    unsigned int w2  = m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    m_displayListParser->getNextWord();
+    
+    //Extract Vertex Coordinats
+    unsigned int x0 = 0;     //TODO Use VI pos or Viewport pos or Scissor pos ?
+    unsigned int y0 = (unsigned int)int(w2&0xFFFF)/4;
+    unsigned int x1 = 320;   //TODO Use VI Height or Viewport Height or Scissor Height ?
+    unsigned int y1 = (unsigned int)int(w2>>16)/4;
+
+    m_rdp->RDP_TexRect(x0, y0, x1, y1, 0, 0, 0, 1024, 1024);  
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h
new file mode 100755 (executable)
index 0000000..9b87d5e
--- /dev/null
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_2_H_
+#define UCODE_2_H_
+
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+class DisplayListParser;
+
+//*****************************************************************************
+//! UCode2
+//! Microcode used for Golden Eye
+//! Note: This ucode is very similar to F3D, The diffrence is that this 
+//!       UCode has a special way to render sky. That sky rendering is
+//!       also used in perfect dark.
+//*****************************************************************************
+class UCode2
+{
+public:
+
+    //Constructor / Destructor
+    UCode2();
+    ~UCode2();
+
+    static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp);
+    static void initializeGBI();
+
+    static void renderSky(MicrocodeArgument* ucode);
+
+private:
+
+    static GBI* m_gbi;                               //!< Pointer to Graphics Binary Interface
+    static RSP* m_rsp;                               //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;                               //!< Pointer to Reality Drawing Processor 
+    static Memory* m_memory;                         //!< Pointer to Memory Manager
+    static DisplayListParser* m_displayListParser;   //!< Pointer to Display-List Parser
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.h
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp
new file mode 100755 (executable)
index 0000000..fe81a9f
--- /dev/null
@@ -0,0 +1,126 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode4.h"
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+
+#define F3DWRUS_TRI2        0xB1
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+GBI* UCode4::m_gbi = 0;
+RSP* UCode4::m_rsp = 0;   //!< Pointer to Reality Signal Processor 
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode4::UCode4()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode4::~UCode4()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode4::initialize(GBI* gbi, RSP* rsp)
+{
+    m_gbi = gbi;
+    m_rsp = rsp;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode4::initializeGBI()
+{
+    UCode0::initializeGBI(m_gbi);
+
+    //Init special Wave Race functions
+    GBI_SetGBI( GBI::G_VTX,                 F3D_VTX,                 m_gbi->m_cmds,    WaveRace64_Vertex );
+    GBI_SetGBI( GBI::G_TRI1,                F3D_TRI1,                m_gbi->m_cmds,    WaveRace64_Tri1 );
+    GBI_SetGBI( GBI::G_QUAD,                F3D_QUAD,                m_gbi->m_cmds,    WaveRace64_Quad );
+    GBI_SetGBI( GBI::G_TRI2,                F3DWRUS_TRI2,            m_gbi->m_cmds,    WaveRace64_Tri2 );
+}
+
+//-----------------------------------------------------------------------------
+//! Add Vertices
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode4::WaveRace64_Vertex(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("WaveRace64_Vertex", M64MSG_VERBOSE);
+    RSPUCodeAddVerticesWaveRace64* temp = (RSPUCodeAddVerticesWaveRace64*)ucode;
+
+    //Add Vertices
+    m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->firstVertexIndex/5);
+}
+
+//-----------------------------------------------------------------------------
+//! Add one Triangle
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode4::WaveRace64_Tri1(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("WaveRace64_Tri1", M64MSG_VERBOSE);
+    RSPUCodeAddOneTriangleF3D* temp = (RSPUCodeAddOneTriangleF3D*)ucode;
+
+    //Add triangle
+    m_rsp->RSP_1Triangle(temp->index0 / 5, temp->index1 / 5, temp->index2 / 5 /*,temp->flag,*/ );
+}
+
+//-----------------------------------------------------------------------------
+//! Add 2 Triangles
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode4::WaveRace64_Tri2(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("WaveRace64_Tri2", M64MSG_VERBOSE);
+    RSPUCodeAddTwoTrianglesWaveRace64* temp = (RSPUCodeAddTwoTrianglesWaveRace64*)ucode;
+
+    //Add Two triangles
+    m_rsp->RSP_2Triangles( temp->v0 / 5, temp->v1 / 5, temp->v2 / 5, 0,
+                           temp->v3 / 5, temp->v4 / 5, temp->v5 / 5, 0);
+}
+
+//-----------------------------------------------------------------------------
+//! Add Quad
+//! @param ucode instruction from displaylist with input data
+//-----------------------------------------------------------------------------
+void UCode4::WaveRace64_Quad(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("WaveRace64_Quad", M64MSG_VERBOSE);
+    RSPUCodeAddOneQuadF3D* temp = (RSPUCodeAddOneQuadF3D*)ucode;
+
+    //Add Quad
+    m_rsp->RSP_1Quadrangle(temp->index0/5, temp->index1/5, temp->index2/5, temp->index3/5);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h
new file mode 100755 (executable)
index 0000000..4c9eb6e
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_4_H_
+#define UCODE_4_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+
+//*****************************************************************************
+//! UCode4 
+//! Microcode used for Wave Race 64
+//*****************************************************************************
+class UCode4
+{
+public:
+
+    UCode4();
+    ~UCode4();
+
+    static void initialize(GBI* gbi, RSP* rsp);
+    static void initializeGBI();
+
+    static void WaveRace64_Vertex(MicrocodeArgument* ucode);
+    static void WaveRace64_Tri1(MicrocodeArgument* ucode);
+    static void WaveRace64_Tri2(MicrocodeArgument* ucode);
+    static void WaveRace64_Quad(MicrocodeArgument* ucode);
+
+private:
+
+    static GBI* m_gbi;
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+
+};
+
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp
new file mode 100755 (executable)
index 0000000..01c0b5d
--- /dev/null
@@ -0,0 +1,515 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode5.h"
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+#include "DisplayListParser.h"
+
+
+#define F3DEX2_MTX_STACKSIZE       18
+
+#define F3DEX2_MTX_MODELVIEW       0x00
+#define F3DEX2_MTX_PROJECTION      0x04
+#define F3DEX2_MTX_MUL             0x00
+#define F3DEX2_MTX_LOAD            0x02
+#define F3DEX2_MTX_NOPUSH          0x00
+#define F3DEX2_MTX_PUSH            0x01
+
+#define F3DEX2_TEXTURE_ENABLE      0x00000000
+#define F3DEX2_SHADING_SMOOTH      0x00200000
+#define F3DEX2_CULL_FRONT          0x00000200
+#define F3DEX2_CULL_BACK           0x00000400
+#define F3DEX2_CULL_BOTH           0x00000600
+#define F3DEX2_CLIPPING            0x00800000
+
+#define F3DEX2_MV_VIEWPORT         8
+
+#define F3DEX2_MWO_aLIGHT_1        0x00
+#define F3DEX2_MWO_bLIGHT_1        0x04
+#define F3DEX2_MWO_aLIGHT_2        0x18
+#define F3DEX2_MWO_bLIGHT_2        0x1c
+#define F3DEX2_MWO_aLIGHT_3        0x30
+#define F3DEX2_MWO_bLIGHT_3        0x34
+#define F3DEX2_MWO_aLIGHT_4        0x48
+#define F3DEX2_MWO_bLIGHT_4        0x4c
+#define F3DEX2_MWO_aLIGHT_5        0x60
+#define F3DEX2_MWO_bLIGHT_5        0x64
+#define F3DEX2_MWO_aLIGHT_6        0x78
+#define F3DEX2_MWO_bLIGHT_6        0x7c
+#define F3DEX2_MWO_aLIGHT_7        0x90
+#define F3DEX2_MWO_bLIGHT_7        0x94
+#define F3DEX2_MWO_aLIGHT_8        0xa8
+#define F3DEX2_MWO_bLIGHT_8        0xac
+
+
+#define    F3DEX2_RDPHALF_2        0xF1
+#define    F3DEX2_SETOTHERMODE_H   0xE3
+#define    F3DEX2_SETOTHERMODE_L   0xE2
+#define    F3DEX2_RDPHALF_1        0xE1
+#define    F3DEX2_SPNOOP           0xE0
+#define    F3DEX2_ENDDL            0xDF
+#define    F3DEX2_DL               0xDE
+#define    F3DEX2_LOAD_UCODE       0xDD
+#define    F3DEX2_MTX              0xDA
+#define F3DEX2_GEOMETRYMODE        0xD9
+#define    F3DEX2_POPMTX           0xD8
+#define    F3DEX2_TEXTURE          0xD7
+#define    F3DEX2_DMA_IO           0xD6
+#define    F3DEX2_SPECIAL_1        0xD5
+#define    F3DEX2_SPECIAL_2        0xD4
+#define    F3DEX2_SPECIAL_3        0xD3
+
+#define    F3DEX2_VTX              0x01
+#define    F3DEX2_MODIFYVTX        0x02
+#define    F3DEX2_CULLDL           0x03
+#define    F3DEX2_BRANCH_Z         0x04
+#define    F3DEX2_TRI1             0x05
+#define F3DEX2_TRI2                0x06
+#define F3DEX2_QUAD                0x07
+#define F3DEX2_LINE3D              0x08
+
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP*    UCode5::m_rsp    = 0;   //!< Pointer to Reality Signal Processor 
+RDP*    UCode5::m_rdp    = 0;   //!< Pointer to Reality Drawing Processor 
+Memory* UCode5::m_memory = 0;
+GBI*    UCode5::m_gbi    = 0;
+DisplayListParser* UCode5::m_displayListParser = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode5::UCode5()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode5::~UCode5()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode5::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
+{
+    m_gbi = gbi;
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+    m_displayListParser = dlp;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode5::initializeGBI()
+{
+    //Set flags
+    GBI_InitFlags( F3DEX2 );
+
+
+    // GBI Command                        Command Value                Command Function
+    GBI_SetGBI( GBI::G_RDPHALF_2,         F3DEX2_RDPHALF_2,            m_gbi->m_cmds,    UCode0::F3D_RDPHalf_2 );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,    F3DEX2_SETOTHERMODE_H,       m_gbi->m_cmds,    F3DEX2_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,    F3DEX2_SETOTHERMODE_L,       m_gbi->m_cmds,    F3DEX2_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_RDPHALF_1,         F3DEX2_RDPHALF_1,            m_gbi->m_cmds,    UCode0::F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_SPNOOP,            F3DEX2_SPNOOP,               m_gbi->m_cmds,    UCode0::F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_ENDDL,             F3DEX2_ENDDL,                m_gbi->m_cmds,    UCode0::F3D_EndDL );
+    GBI_SetGBI( GBI::G_DL,                F3DEX2_DL,                   m_gbi->m_cmds,    UCode0::F3D_DList );
+    GBI_SetGBI( GBI::G_LOAD_UCODE,        F3DEX2_LOAD_UCODE,           m_gbi->m_cmds,    UCode1::F3DEX_Load_uCode );
+    GBI_SetGBI( GBI::G_MOVEMEM,           F3DEX2_MOVEMEM,              m_gbi->m_cmds,    F3DEX2_MoveMem );
+    GBI_SetGBI( GBI::G_MOVEWORD,          F3DEX2_MOVEWORD,             m_gbi->m_cmds,    F3DEX2_MoveWord );
+    GBI_SetGBI( GBI::G_MTX,               F3DEX2_MTX,                  m_gbi->m_cmds,    F3DEX2_Mtx );
+    GBI_SetGBI( GBI::G_GEOMETRYMODE,      F3DEX2_GEOMETRYMODE,         m_gbi->m_cmds,    F3DEX2_GeometryMode );
+    GBI_SetGBI( GBI::G_POPMTX,            F3DEX2_POPMTX,               m_gbi->m_cmds,    F3DEX2_PopMtx );
+    GBI_SetGBI( GBI::G_TEXTURE,           F3DEX2_TEXTURE,              m_gbi->m_cmds,    F3DEX2_Texture );
+    GBI_SetGBI( GBI::G_DMA_IO,            F3DEX2_DMA_IO,               m_gbi->m_cmds,    F3DEX2_DMAIO );
+    GBI_SetGBI( GBI::G_SPECIAL_1,         F3DEX2_SPECIAL_1,            m_gbi->m_cmds,    F3DEX2_Special_1 );
+    GBI_SetGBI( GBI::G_SPECIAL_2,         F3DEX2_SPECIAL_2,            m_gbi->m_cmds,    F3DEX2_Special_2 );
+    GBI_SetGBI( GBI::G_SPECIAL_3,         F3DEX2_SPECIAL_3,            m_gbi->m_cmds,    F3DEX2_Special_3 );
+    GBI_SetGBI( GBI::G_VTX,               F3DEX2_VTX,                  m_gbi->m_cmds,    F3DEX2_Vtx );
+    GBI_SetGBI( GBI::G_MODIFYVTX,         F3DEX2_MODIFYVTX,            m_gbi->m_cmds,    UCode1::F3DEX_ModifyVtx );
+    GBI_SetGBI(    GBI::G_CULLDL,         F3DEX2_CULLDL,               m_gbi->m_cmds,    UCode1::F3DEX_CullDL );
+    GBI_SetGBI( GBI::G_BRANCH_Z,          F3DEX2_BRANCH_Z,             m_gbi->m_cmds,    UCode1::F3DEX_Branch_Z );
+    GBI_SetGBI( GBI::G_TRI1,              F3DEX2_TRI1,                 m_gbi->m_cmds,    F3DEX2_Tri1 );
+    GBI_SetGBI( GBI::G_TRI2,              F3DEX2_TRI2,                 m_gbi->m_cmds,    UCode1::F3DEX_Tri2 );
+    GBI_SetGBI( GBI::G_QUAD,              F3DEX2_QUAD,                 m_gbi->m_cmds,    F3DEX2_Quad );
+    GBI_SetGBI( GBI::G_LINE3D,            F3DEX2_LINE3D,               m_gbi->m_cmds,    F3DEX2_Line3D );
+}
+
+//*****************************************************************************
+// Matrices
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//! Add Matrix
+//! @todo Bomberman2 hack
+//! @todo South park rally hack
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Mtx( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Mtx", M64MSG_VERBOSE);
+    RSPUCodeAddMatrixF3DEX2* temp = (RSPUCodeAddMatrixF3DEX2*)ucode;
+
+    //TODO Bomberman2 hack
+    if( temp->param == 0 && temp->lenght == 0 )
+    {
+        //Bomberman2TextRect(ucode);
+        Logger::getSingleton().printMsg("F3DEX2_Mtx - Bomberman2TextRect - Unimplemented", M64MSG_WARNING);
+        return;
+    }
+
+    //Add Matrix
+    m_rsp->RSP_Matrix( temp->segmentAddress, temp->projection, !temp->nopush, temp->load );
+
+    //For Conker Bad Fur Day
+    m_rsp->getVertexMgr()->setConkerAddress(0);
+
+    //TODO South park rally hack
+}
+
+//-----------------------------------------------------------------------------
+//! Pop Matrix
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_PopMtx( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_PopMtx", M64MSG_VERBOSE);
+
+    m_rsp->RSP_PopMatrixN( ucode->w1 >> 6 );
+}
+
+//*****************************************************************************
+//Textures
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+//! Set Texture
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Texture( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Texture", M64MSG_VERBOSE);
+
+    float scaleS  = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 ); 
+    float scaleT  = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 ); 
+    int level    = _SHIFTR( ucode->w0, 11, 3 );
+    int tile     = _SHIFTR( ucode->w0, 8, 3 );
+    int on       = _SHIFTR( ucode->w0, 1, 7 );
+
+    m_rsp->RSP_Texture(scaleS, scaleT, level, tile, on);
+}
+
+//*****************************************************************************
+// Vertices and indices
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// Vertices
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Vtx( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Vtx", M64MSG_VERBOSE);
+    RSPUCodeAddVerticesF3DEX2* temp = (RSPUCodeAddVerticesF3DEX2*)ucode;
+
+    //Add Vertices
+    m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->vertexEnd - temp->numVertices);
+}
+
+//-----------------------------------------------------------------------------
+// Add 1 Triangle
+//! @todo Add triangle flag
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Tri1( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Tri1", M64MSG_VERBOSE);
+    RSPUCodeAddOneTriangleF3DEX2* temp = (RSPUCodeAddOneTriangleF3DEX2*)ucode;
+
+    //Add one triangle
+    m_rsp->RSP_1Triangle( temp->index0 / 2, temp->index1 / 2, temp->index2 / 2); //TODO flag
+}
+
+//-----------------------------------------------------------------------------
+// Add 1 Quad
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Quad( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Quad", M64MSG_VERBOSE);
+    RSPUCodeAddOneQuadF3DEX2* temp = (RSPUCodeAddOneQuadF3DEX2*)ucode;
+
+    //Add two triangles
+    m_rsp->RSP_2Triangles( temp->v0 / 2, temp->v1 / 2, temp->v2 / 2, 0,
+                           temp->v3 / 2, temp->v4 / 2, temp->v5 / 2, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Render Line 3D
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_Line3D( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_Line3D - Unimplemented", M64MSG_WARNING);
+}
+
+
+//*****************************************************************************
+// Misc
+//*****************************************************************************
+
+//-----------------------------------------------------------------------------
+// MoveMem
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_MoveMem( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_MoveMem", M64MSG_VERBOSE);
+
+    switch (_SHIFTR( ucode->w0, 0, 8 ))
+    {
+        case F3DEX2_MV_VIEWPORT:
+            m_rsp->moveMemViewport( ucode->w1 );
+            break;
+        case G_MV_MATRIX:
+            m_rsp->RSP_ForceMatrix( ucode->w1 );
+            m_displayListParser->increasePC(8);        // force matrix takes two commands
+            break;
+        case G_MV_LIGHT:
+            /*
+            unsigned int dwOffset2 = ((ucode->w0) >> 5) & 0x3FFF;
+
+            switch (dwOffset2)
+            {
+            case 0x00:
+            {
+                s8 * pcBase = g_pRDRAMs8 + addr;
+                LOG_UCODE("    RSP_GBI1_MV_MEM_LOOKATX %f %f %f",
+                    (float)pcBase[8 ^ 0x3],
+                    (float)pcBase[9 ^ 0x3],
+                    (float)pcBase[10 ^ 0x3]);
+
+            }
+            break;
+            case 0x18:
+                {
+                    s8 * pcBase = g_pRDRAMs8 + addr;
+                    LOG_UCODE("    RSP_GBI1_MV_MEM_LOOKATY %f %f %f",
+                        (float)pcBase[8 ^ 0x3],
+                        (float)pcBase[9 ^ 0x3],
+                        (float)pcBase[10 ^ 0x3]);
+                }
+                break;
+            default:        //0x30/48/60
+                {
+                    uint32 dwLight = (dwOffset2 - 0x30)/0x18;
+                    LOG_UCODE("    Light %d:", dwLight);
+                        RSP_MoveMemLight(dwLight, addr);
+                }
+                break;
+            }
+            break;
+            */
+            unsigned int offset = _SHIFTR( ucode->w0, 8, 8 ) << 3;
+
+            if (offset >= 48)
+            {
+                m_rsp->RSP_Light( ((offset - 24) / 24) - 1, ucode->w1);
+            }
+            else
+            {
+                static bool warned = false;
+                if ( !warned ) {
+                    Logger::getSingleton().printMsg("F3DEX2_MoveMem - Light - Unimplemented", M64MSG_WARNING);
+                    warned = true;
+                }
+            }
+            
+            break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Move Word
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_MoveWord(MicrocodeArgument* ucode) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_MoveWord", M64MSG_VERBOSE);
+    RSPUCodeMoveWordF3DEX2* temp = (RSPUCodeMoveWordF3DEX2*)ucode;
+
+    switch ( temp->type )
+    {
+        case G_MW_FORCEMTX:
+            Logger::getSingleton().printMsg("ForceMatrix - Unimplemented", M64MSG_WARNING);  // Handled in movemem???            
+            break;
+
+        case G_MW_MATRIX:
+            m_rsp->RSP_InsertMatrix( _SHIFTR( ucode->w0, 0, 16 ), ucode->w1 );            
+            break;
+
+        case G_MW_NUMLIGHT: 
+            m_rsp->RSP_NumLights(temp->value / 24); 
+            break;
+    
+        case G_MW_SEGMENT:
+            m_rsp->moveSegment(temp->offset>>2, temp->value & 0x00FFFFFF);
+            break;
+
+        case G_MW_CLIP:
+            //gSPClipRatio( ucode->w1 );
+            break;
+
+        case G_MW_FOG:
+            m_rsp->RSP_FogFactor(  (short)temp->fm, (short)temp->fo);
+            break;
+
+        case G_MW_PERSPNORM:
+            //gSPPerspNormalize( w1 );
+            break;
+
+        case G_MW_LIGHTCOL:
+            if ( (temp->offset & 0x7) == 0 )
+            {
+                m_rsp->RSP_LightColor(temp->offset / 0x18, temp->value);
+            }
+            break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Geometry Mode
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_GeometryMode( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_GeometryMode", M64MSG_VERBOSE);
+                             //clear                              set
+    m_rsp->RSP_GeometryMode( ~_SHIFTR( ucode->w0, 0, 24 ), ucode->w1 );
+}
+
+//-----------------------------------------------------------------------------
+//* Set Other Mode H
+//! @todo more case in switch
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_SetOtherMode_H( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_H", M64MSG_VERBOSE);
+
+    switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1))
+    {
+        case G_MDSFT_CYCLETYPE:  m_rdp->setCycleType( ucode->w1 >> G_MDSFT_CYCLETYPE );    break;
+        case G_MDSFT_TEXTLUT:    m_rdp->setTextureLUT( ucode->w1 >> G_MDSFT_TEXTLUT );     break;
+
+        //TODO
+        case G_MDSFT_PIPELINE:     //m_rdp->setPiplineMode( w1 >> G_MDSFT_PIPELINE ); 
+            break;
+        case G_MDSFT_TEXTPERSP:    //m_rdp->setTexturePerspective( w1 >> G_MDSFT_TEXTPERSP );
+            break;
+        case G_MDSFT_TEXTDETAIL:   //m_rdp->setTextureDetail( w1 >> G_MDSFT_TEXTDETAIL );
+            break;
+        case G_MDSFT_TEXTLOD:      //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD );
+            break;        
+        case G_MDSFT_TEXTFILT:     //gDPSetTextureFilter( w1 >> G_MDSFT_TEXTFILT );
+            break;
+        case G_MDSFT_TEXTCONV:     //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV );
+            break;
+        case G_MDSFT_COMBKEY:      //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY );
+            break;
+        case G_MDSFT_RGBDITHER:    //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER );
+            break;
+        case G_MDSFT_ALPHADITHER:  //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER );
+            break;
+        default:
+            Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L - Unknown type", M64MSG_WARNING);
+
+            unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1;
+            unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length;
+            unsigned int mask = ((1 << length) - 1) << shift;
+
+            m_rdp->m_otherMode.h &= ~mask;
+            m_rdp->m_otherMode.h |= ucode->w1 & mask;
+
+            m_rdp->setUpdateCombiner(true);
+            break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Set Other Mode L
+//-----------------------------------------------------------------------------
+void UCode5::F3DEX2_SetOtherMode_L( MicrocodeArgument* ucode ) 
+{
+    Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L", M64MSG_VERBOSE);
+
+    switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1))
+    {
+        case G_MDSFT_ALPHACOMPARE:
+            m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE);
+            break;
+        case G_MDSFT_ZSRCSEL:
+            m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL );
+            break;
+        case G_MDSFT_RENDERMODE:
+            m_rdp->setRenderMode(  ucode->w1 );
+            break;
+        default:
+            unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1;
+            unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length;
+            unsigned int mask = ((1 << length) - 1) << shift;
+            m_rdp->m_otherMode.l &= ~mask;
+            m_rdp->m_otherMode.l |= ucode->w1 & mask;
+            break;
+    }
+}
+
+//*****************************************************************************
+// Other
+//*****************************************************************************
+
+void UCode5::F3DEX2_DMAIO( MicrocodeArgument* ucode ) {
+    Logger::getSingleton().printMsg("F3DEX2_DMAIO", M64MSG_VERBOSE);
+    //Ignore?
+}
+void UCode5::F3DEX2_Special_1( MicrocodeArgument* ucode ) {
+    Logger::getSingleton().printMsg("F3DEX2_Special_1", M64MSG_VERBOSE);
+    //Ignore?
+}
+void UCode5::F3DEX2_Special_2( MicrocodeArgument* ucode ) {
+    Logger::getSingleton().printMsg("F3DEX2_Special_2", M64MSG_VERBOSE);
+    //Ignore?
+}
+void UCode5::F3DEX2_Special_3( MicrocodeArgument* ucode ) {
+    Logger::getSingleton().printMsg("F3DEX2_Special_3", M64MSG_VERBOSE);
+    //Ignore?
+}
+
+//*****************************************************************************
+// Unimportant Functions
+//*****************************************************************************
+void UCode5::F3DEX2_Reserved1(MicrocodeArgument* ucode) {
+    Logger::getSingleton().printMsg("F3DEX2_Reserved1", M64MSG_VERBOSE);
+    //Ignore
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h
new file mode 100755 (executable)
index 0000000..4b59e73
--- /dev/null
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_5_H_
+#define UCODE_5_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+class DisplayListParser;
+
+#define    F3DEX2_MOVEMEM            0xDC
+#define    F3DEX2_MOVEWORD           0xDB
+
+//*****************************************************************************
+//! UCode5 (aka F3DEX2)
+//! Microcode used for Zelda and newer games
+//*****************************************************************************
+class UCode5
+{
+public: 
+
+    // Constructor / Destructor
+    UCode5();
+    ~UCode5();
+
+    static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp);
+    static void initializeGBI();
+
+    //Matrices
+    static void F3DEX2_Mtx( MicrocodeArgument* ucode );
+    static void F3DEX2_PopMtx( MicrocodeArgument* ucode );
+
+    //Textures
+    static void F3DEX2_Texture( MicrocodeArgument* ucode );
+
+    //Vertices
+    static void F3DEX2_Vtx( MicrocodeArgument* ucode );
+    static void F3DEX2_Tri1( MicrocodeArgument* ucode );
+    static void F3DEX2_Quad( MicrocodeArgument* ucode );
+    static void F3DEX2_Line3D( MicrocodeArgument* ucode );
+
+    //Misc
+    static void F3DEX2_MoveMem( MicrocodeArgument* ucode );
+    static void F3DEX2_MoveWord( MicrocodeArgument* ucode );
+    static void F3DEX2_GeometryMode( MicrocodeArgument* ucode );
+    static void F3DEX2_SetOtherMode_H( MicrocodeArgument* ucode );
+    static void F3DEX2_SetOtherMode_L( MicrocodeArgument* ucode );
+
+    //Other
+    static void F3DEX2_DMAIO( MicrocodeArgument* ucode );
+    static void F3DEX2_Special_1( MicrocodeArgument* ucode );
+    static void F3DEX2_Special_2( MicrocodeArgument* ucode );
+    static void F3DEX2_Special_3( MicrocodeArgument* ucode );
+    static void F3DEX2_Reserved1( MicrocodeArgument* ucode );
+
+private:
+
+    static GBI* m_gbi;        //!< Graphics Binary Interface
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;        //!< Pointer to Reality Drawing Processor  
+    static Memory* m_memory;  //!< Pointer accessing memory like RDRAM and Texture Memory
+    static DisplayListParser* m_displayListParser;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp
new file mode 100755 (executable)
index 0000000..d64e3a0
--- /dev/null
@@ -0,0 +1,197 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode6.h"
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+#include "DisplayListParser.h"
+#include "RSPMatrixManager.h"
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+GBI*               UCode6::m_gbi = 0;                 // Pointer to Graphics Binary Interface
+RSP*               UCode6::m_rsp = 0;                 // Pointer to Reality Signal Processor 
+RDP*               UCode6::m_rdp = 0;                 // Pointer to Reality Drawing Processor 
+DisplayListParser* UCode6::m_displayListParser = 0;
+Memory*            UCode6::m_memory = 0;
+unsigned int       UCode6::m_vertexIndex = 0;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode6::UCode6()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode6::~UCode6()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Initialize 
+//-----------------------------------------------------------------------------
+void UCode6::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
+{
+    m_gbi = gbi;
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+    m_displayListParser = dlp;
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize GBI
+//! Assigns functions to the GBI
+//-----------------------------------------------------------------------------
+void UCode6::initializeGBI()
+{
+    GBI_InitFlags( F3D );
+
+    //          GBI Command              Command Value            Command Function
+    GBI_SetGBI( GBI::G_SPNOOP,           F3D_SPNOOP,              m_gbi->m_cmds,    UCode0::F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_DMA_MTX,          F3DDKR_DMA_MTX,          m_gbi->m_cmds,    F3DDKR_DMA_Mtx );
+    GBI_SetGBI( GBI::G_MOVEMEM,          F3D_MOVEMEM,             m_gbi->m_cmds,    UCode0::F3D_MoveMem );
+    GBI_SetGBI( GBI::G_DMA_VTX,          F3DDKR_DMA_VTX,          m_gbi->m_cmds,    F3DDKR_DMA_Vtx );
+    GBI_SetGBI( GBI::G_DL,               F3D_DL,                  m_gbi->m_cmds,    UCode0::F3D_DList );
+    GBI_SetGBI( GBI::G_DMA_DL,           F3DDKR_DMA_DL,           m_gbi->m_cmds,    F3DDKR_DMA_DList );
+    GBI_SetGBI( GBI::G_DMA_TRI,          F3DDKR_DMA_TRI,          m_gbi->m_cmds,    F3DDKR_DMA_Tri );
+    GBI_SetGBI( GBI::G_DMA_OFFSETS,      F3DDKR_DMA_OFFSETS,      m_gbi->m_cmds,    F3DDKR_DMA_Offsets );
+    GBI_SetGBI( GBI::G_CULLDL,           F3D_CULLDL,              m_gbi->m_cmds,    UCode0::F3D_CullDL );
+    GBI_SetGBI( GBI::G_MOVEWORD,         F3D_MOVEWORD,            m_gbi->m_cmds,    F3DDKR_MoveWord );
+    GBI_SetGBI( GBI::G_TEXTURE,          F3D_TEXTURE,             m_gbi->m_cmds,    UCode0::F3D_Texture );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,   F3D_SETOTHERMODE_H,      m_gbi->m_cmds,    UCode0::F3D_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,   F3D_SETOTHERMODE_L,      m_gbi->m_cmds,    UCode0::F3D_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_ENDDL,            F3D_ENDDL,               m_gbi->m_cmds,    UCode0::F3D_EndDL );
+    GBI_SetGBI( GBI::G_SETGEOMETRYMODE,  F3D_SETGEOMETRYMODE,     m_gbi->m_cmds,    UCode0::F3D_SetGeometryMode );
+    GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE,   m_gbi->m_cmds,    UCode0::F3D_ClearGeometryMode );
+    GBI_SetGBI( GBI::G_QUAD,             F3D_QUAD,                m_gbi->m_cmds,    UCode0::F3D_Quad );
+    GBI_SetGBI( GBI::G_RDPHALF_1,        F3D_RDPHALF_1,           m_gbi->m_cmds,    UCode0::F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_RDPHALF_2,        F3D_RDPHALF_2,           m_gbi->m_cmds,    UCode0::F3D_RDPHalf_2 );
+    GBI_SetGBI( GBI::G_RDPHALF_CONT,     F3D_RDPHALF_CONT,        m_gbi->m_cmds,    UCode0::F3D_RDPHalf_Cont );
+    GBI_SetGBI( GBI::G_TRI4,             F3D_TRI4,                m_gbi->m_cmds,    UCode0::F3D_Tri4 );
+}
+
+//-----------------------------------------------------------------------------
+// DMA Matrix
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_DMA_Mtx(MicrocodeArgument* ucode)
+{
+    if (_SHIFTR( ucode->w0, 0, 16 ) != 64)
+    {
+        //GBI_DetectUCode(); // Something's wrong
+        return;
+    }
+
+    unsigned int index = _SHIFTR( ucode->w0, 16, 4 );
+    unsigned int multiply;
+
+    if (index == 0) // DKR
+    {
+        index = _SHIFTR( ucode->w0, 22, 2 );
+        multiply = 0;
+    }
+    else // Gemini
+    {
+        multiply = _SHIFTR( ucode->w0, 23, 1 );
+    }
+
+    m_rsp->RSP_DMAMatrix( ucode->w1, index, multiply );
+}
+
+//-----------------------------------------------------------------------------
+// DMA Vertex 
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_DMA_Vtx(MicrocodeArgument* ucode)
+{
+    if ((ucode->w0 & F3DDKR_VTX_APPEND))
+    {
+        if ( m_rsp->getVertexMgr()->getBillboard() ) {
+            m_vertexIndex = 1;
+        }
+    }
+    else {
+        m_vertexIndex = 0;
+    }
+
+    unsigned int n = _SHIFTR( ucode->w0, 19, 5 ) + 1;
+
+    m_rsp->RSP_DMAVertex( ucode->w1, n, m_vertexIndex + _SHIFTR( ucode->w0, 9, 5 ) );
+
+    m_vertexIndex += n;
+}
+
+//-----------------------------------------------------------------------------
+// DMA Triangle
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_DMA_Tri(MicrocodeArgument* ucode)
+{
+    m_rsp->RSP_DMATriangles( ucode->w1, _SHIFTR( ucode->w0, 4, 12 ) );
+    m_vertexIndex = 0;
+}
+
+//-----------------------------------------------------------------------------
+// DMA Display List
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_DMA_DList(MicrocodeArgument* ucode)
+{
+    m_rsp->RSP_DMADisplayList( ucode->w0, ucode->w1   /*_SHIFTR( ucode->w0, 16, 8 )*/ );
+}
+
+//-----------------------------------------------------------------------------
+// DMA Offsets
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_DMA_Offsets(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("PerfectDark_Vertex", M64MSG_VERBOSE);
+    RSPUCodeSetDMAOffsets* temp = (RSPUCodeSetDMAOffsets*)ucode;
+
+    //Set DMA Offsets
+    m_rsp->RSP_SetDMAOffsets(temp->addressOffsetMatrix, temp->addressOffsetVertex);
+}
+
+//-----------------------------------------------------------------------------
+// MoveWord
+//-----------------------------------------------------------------------------
+void UCode6::F3DDKR_MoveWord(MicrocodeArgument* ucode)
+{
+    switch (_SHIFTR( ucode->w0, 0, 8 ))
+    {
+        case 0x02:
+            m_rsp->getVertexMgr()->setBillboard( ucode->w1 & 1 );
+            break;
+        case 0x0A:
+            m_rsp->getMatrixMgr()->selectViewMatrix(_SHIFTR( ucode->w1, 6, 2 ));
+            break;
+        default:
+            UCode0::F3D_MoveWord( ucode );
+            break;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h
new file mode 100755 (executable)
index 0000000..30e8bab
--- /dev/null
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_6_H_
+#define UCODE_6_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+#define F3DDKR_VTX_APPEND       0x00010000
+#define F3DDKR_DMA_MTX          0x01
+#define F3DDKR_DMA_VTX          0x04
+#define F3DDKR_DMA_TRI          0x05
+#define F3DDKR_DMA_DL           0x07
+#define F3DDKR_DMA_OFFSETS      0xBF
+
+//Forward declaration
+class GBI;
+class RSP;
+class RDP;
+class Memory;
+class DisplayListParser;
+
+//*****************************************************************************
+//! UCode6 
+//! Microcode used for Diddy Kong Racing
+//*****************************************************************************
+class UCode6
+{
+public:
+
+    UCode6();
+    ~UCode6();
+
+    static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp);
+    static void initializeGBI();
+
+    static void F3DDKR_MoveWord(MicrocodeArgument* ucode);
+    static void F3DDKR_DMA_Offsets(MicrocodeArgument* ucode);
+    static void F3DDKR_DMA_DList(MicrocodeArgument* ucode);
+    static void F3DDKR_DMA_Tri(MicrocodeArgument* ucode);
+    static void F3DDKR_DMA_Vtx(MicrocodeArgument* ucode);
+    static void F3DDKR_DMA_Mtx(MicrocodeArgument* ucode);
+
+private:
+
+    static GBI* m_gbi;                               //!< Pointer to Graphics Binary Interface
+    static RSP* m_rsp;                               //!< Pointer to Reality Signal Processor 
+    static RDP* m_rdp;                               //!< Pointer to Reality Drawing Processor  
+    static Memory* m_memory;                         //!< Pointer to Memory Manager
+    static DisplayListParser* m_displayListParser;   //!< Pointer to Display list parser
+
+    static unsigned int m_vertexIndex;
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp
new file mode 100755 (executable)
index 0000000..d7e7de9
--- /dev/null
@@ -0,0 +1,249 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode7.h"
+#include "UCode0.h"
+#include "UCode1.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "Memory.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+
+#define    S2DEX_BG_1CYC            0x01
+#define    S2DEX_BG_COPY            0x02
+#define    S2DEX_OBJ_RECTANGLE      0x03
+#define    S2DEX_OBJ_SPRITE         0x04
+#define    S2DEX_OBJ_MOVEMEM        0x05
+#define    S2DEX_LOAD_UCODE         0xAF
+#define    S2DEX_SELECT_DL          0xB0
+#define    S2DEX_OBJ_RENDERMODE     0xB1
+#define    S2DEX_OBJ_RECTANGLE_R    0xB2
+#define    S2DEX_OBJ_LOADTXTR       0xC1
+#define    S2DEX_OBJ_LDTX_SPRITE    0xC2
+#define    S2DEX_OBJ_LDTX_RECT      0xC3
+#define    S2DEX_OBJ_LDTX_RECT_R    0xC4
+#define    S2DEX_RDPHALF_0          0xE4
+
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP*    UCode7::m_rsp    = 0;   //!< Pointer to Reality Signal Processor 
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode7::UCode7()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode7::~UCode7()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode7::initialize(RSP* rsp)
+{
+    m_rsp = rsp;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode7::initializeGBI(GBI* gbi)
+{
+    // Set GeometryMode flags
+    GBI_InitFlags( F3DEX );
+
+    //          GBI Command             Command Value            Command Function
+    GBI_SetGBI( GBI::G_SPNOOP,          F3D_SPNOOP,              gbi->m_cmds,    UCode0::F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_BG_1CYC,         S2DEX_BG_1CYC,           gbi->m_cmds,    S2DEX_BG_1Cyc );
+    GBI_SetGBI( GBI::G_BG_COPY,         S2DEX_BG_COPY,           gbi->m_cmds,    S2DEX_BG_Copy );
+    GBI_SetGBI( GBI::G_OBJ_RECTANGLE,   S2DEX_OBJ_RECTANGLE,     gbi->m_cmds,    S2DEX_Obj_Rectangle );
+    GBI_SetGBI( GBI::G_OBJ_SPRITE,      S2DEX_OBJ_SPRITE,        gbi->m_cmds,    S2DEX_Obj_Sprite );
+    GBI_SetGBI( GBI::G_OBJ_MOVEMEM,     S2DEX_OBJ_MOVEMEM,       gbi->m_cmds,    S2DEX_Obj_MoveMem );
+    GBI_SetGBI( GBI::G_DL,              F3D_DL,                  gbi->m_cmds,    UCode0::F3D_DList );
+    GBI_SetGBI( GBI::G_SELECT_DL,       S2DEX_SELECT_DL,         gbi->m_cmds,    S2DEX_Select_DL );
+    GBI_SetGBI( GBI::G_OBJ_RENDERMODE,  S2DEX_OBJ_RENDERMODE,    gbi->m_cmds,    S2DEX_Obj_RenderMode );
+    GBI_SetGBI( GBI::G_OBJ_RECTANGLE_R, S2DEX_OBJ_RECTANGLE_R,   gbi->m_cmds,    S2DEX_Obj_Rectangle_R );
+    GBI_SetGBI( GBI::G_OBJ_LOADTXTR,    S2DEX_OBJ_LOADTXTR,      gbi->m_cmds,    S2DEX_Obj_LoadTxtr );
+    GBI_SetGBI( GBI::G_OBJ_LDTX_SPRITE, S2DEX_OBJ_LDTX_SPRITE,   gbi->m_cmds,    S2DEX_Obj_LdTx_Sprite );
+    GBI_SetGBI( GBI::G_OBJ_LDTX_RECT,   S2DEX_OBJ_LDTX_RECT,     gbi->m_cmds,    S2DEX_Obj_LdTx_Rect );
+    GBI_SetGBI( GBI::G_OBJ_LDTX_RECT_R, S2DEX_OBJ_LDTX_RECT_R,   gbi->m_cmds,    S2DEX_Obj_LdTx_Rect_R );
+    GBI_SetGBI( GBI::G_MOVEWORD,        F3D_MOVEWORD,            gbi->m_cmds,    UCode0::F3D_MoveWord );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,  F3D_SETOTHERMODE_H,      gbi->m_cmds,    UCode0::F3D_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,  F3D_SETOTHERMODE_L,      gbi->m_cmds,    UCode0::F3D_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_ENDDL,           F3D_ENDDL,               gbi->m_cmds,    UCode0::F3D_EndDL );
+    GBI_SetGBI( GBI::G_RDPHALF_1,       F3D_RDPHALF_1,           gbi->m_cmds,    UCode0::F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_RDPHALF_2,       F3D_RDPHALF_2,           gbi->m_cmds,    UCode0::F3D_RDPHalf_2 );
+    GBI_SetGBI(    GBI::G_LOAD_UCODE,   S2DEX_LOAD_UCODE,        gbi->m_cmds,    UCode1::F3DEX_Load_uCode );
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_BG_1Cyc(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_BG_1Cyc - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_BG_Copy(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_BG_Copy - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Obj Ractangle
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_Rectangle(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_Rectangle - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_Sprite(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_Sprite - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_MoveMem(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_MoveMem - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_LoadTxtr(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_LoadTxtr - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_LdTx_Sprite(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Sprite - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_LdTx_Rect_R(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Rect_R - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! Select Display List
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Select_DL(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Select_DL - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_RenderMode(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_RenderMode - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_Rectangle_R(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_Rectangle_R - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
+
+//-----------------------------------------------------------------------------
+//! 
+//-----------------------------------------------------------------------------
+void UCode7::S2DEX_Obj_LdTx_Rect(MicrocodeArgument* ucode)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Rect - Unimplemented", M64MSG_WARNING);
+        warned = true;
+    }
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h
new file mode 100755 (executable)
index 0000000..5565591
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_7_H_
+#define UCODE_7_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+//Forward declaration
+class GBI;
+class RSP;
+
+//*****************************************************************************
+//! UCode4 (aka S2DEX)
+//! Microcode used for Yoshi's Story
+//*****************************************************************************
+class UCode7
+{
+public:
+
+    UCode7();
+    ~UCode7();
+
+    static void initialize(RSP* rsp);
+    static void initializeGBI(GBI* gbi);
+
+    static void S2DEX_Select_DL(MicrocodeArgument* ucode);
+    static void S2DEX_BG_1Cyc(MicrocodeArgument* ucode);
+    static void S2DEX_BG_Copy(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_Rectangle(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_Sprite(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_MoveMem(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_RenderMode(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_Rectangle_R(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_LoadTxtr(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_LdTx_Sprite(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_LdTx_Rect(MicrocodeArgument* ucode);
+    static void S2DEX_Obj_LdTx_Rect_R(MicrocodeArgument* ucode);
+
+private:
+
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.h
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp
new file mode 100755 (executable)
index 0000000..62b62bb
--- /dev/null
@@ -0,0 +1,120 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCode9.h"
+#include "UCode0.h"
+#include "GBI.h"
+#include "RSP.h"
+#include "UCodeDefs.h"
+#include "GBIDefs.h"
+#include "Logger.h"
+
+#define F3DPD_VTXCOLORBASE        0x07
+                             
+//-----------------------------------------------------------------------------
+// Static Variables
+//-----------------------------------------------------------------------------
+RSP*    UCode9::m_rsp    = 0;   //!< Pointer to Reality Signal Processor 
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCode9::UCode9()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCode9::~UCode9()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize
+//-----------------------------------------------------------------------------
+void UCode9::initialize(RSP* rsp)
+{
+    m_rsp = rsp;
+}
+
+//-----------------------------------------------------------------------------
+//! Initialize GBI
+//-----------------------------------------------------------------------------
+void UCode9::initializeGBI(GBI* gbi)
+{
+    // Set GeometryMode flags
+    GBI_InitFlags( F3D );
+
+    //          GBI Command              Command Value                           Command Function
+    GBI_SetGBI( GBI::G_SPNOOP,           F3D_SPNOOP,             gbi->m_cmds,    UCode0::F3D_SPNoOp );
+    GBI_SetGBI( GBI::G_MTX,              F3D_MTX,                gbi->m_cmds,    UCode0::F3D_Mtx );
+    GBI_SetGBI( GBI::G_RESERVED0,        F3D_RESERVED0,          gbi->m_cmds,    UCode0::F3D_Reserved0 );
+    GBI_SetGBI( GBI::G_MOVEMEM,          F3D_MOVEMEM,            gbi->m_cmds,    UCode0::F3D_MoveMem );
+    GBI_SetGBI( GBI::G_VTX,              F3D_VTX,                gbi->m_cmds,    PerfectDark_Vertex );
+    GBI_SetGBI( GBI::G_RESERVED1,        F3D_RESERVED1,          gbi->m_cmds,    UCode0::F3D_Reserved1 );
+    GBI_SetGBI( GBI::G_DL,               F3D_DL,                 gbi->m_cmds,    UCode0::F3D_DList );
+    GBI_SetGBI( GBI::G_VTXCOLORBASE,     F3DPD_VTXCOLORBASE,     gbi->m_cmds,    PerfectDark_VertexColorBase );
+    GBI_SetGBI( GBI::G_RESERVED3,        F3D_RESERVED3,          gbi->m_cmds,    UCode0::F3D_Reserved3 );
+    GBI_SetGBI( GBI::G_SPRITE2D_BASE,    F3D_SPRITE2D_BASE,      gbi->m_cmds,    UCode0::F3D_Sprite2D_Base );
+    GBI_SetGBI( GBI::G_TRI1,             F3D_TRI1,               gbi->m_cmds,    UCode0::F3D_Tri1 );
+    GBI_SetGBI( GBI::G_CULLDL,           F3D_CULLDL,             gbi->m_cmds,    UCode0::F3D_CullDL );
+    GBI_SetGBI( GBI::G_POPMTX,           F3D_POPMTX,             gbi->m_cmds,    UCode0::F3D_PopMtx );
+    GBI_SetGBI( GBI::G_MOVEWORD,         F3D_MOVEWORD,           gbi->m_cmds,    UCode0::F3D_MoveWord );
+    GBI_SetGBI( GBI::G_TEXTURE,          F3D_TEXTURE,            gbi->m_cmds,    UCode0::F3D_Texture );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_H,   F3D_SETOTHERMODE_H,     gbi->m_cmds,    UCode0::F3D_SetOtherMode_H );
+    GBI_SetGBI( GBI::G_SETOTHERMODE_L,   F3D_SETOTHERMODE_L,     gbi->m_cmds,    UCode0::F3D_SetOtherMode_L );
+    GBI_SetGBI( GBI::G_ENDDL,            F3D_ENDDL,              gbi->m_cmds,    UCode0::F3D_EndDL );
+    GBI_SetGBI( GBI::G_SETGEOMETRYMODE,  F3D_SETGEOMETRYMODE,    gbi->m_cmds,    UCode0::F3D_SetGeometryMode );
+    GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE,  gbi->m_cmds,    UCode0::F3D_ClearGeometryMode );
+    GBI_SetGBI( GBI::G_QUAD,             F3D_QUAD,               gbi->m_cmds,    UCode0::F3D_Quad );
+    GBI_SetGBI( GBI::G_RDPHALF_1,        F3D_RDPHALF_1,          gbi->m_cmds,    UCode0::F3D_RDPHalf_1 );
+    GBI_SetGBI( GBI::G_RDPHALF_2,        F3D_RDPHALF_2,          gbi->m_cmds,    UCode0::F3D_RDPHalf_2 );
+    GBI_SetGBI( GBI::G_RDPHALF_CONT,     F3D_RDPHALF_CONT,       gbi->m_cmds,    UCode0::F3D_RDPHalf_Cont );
+    GBI_SetGBI( GBI::G_TRI4,             F3D_TRI4,               gbi->m_cmds,    UCode0::F3D_Tri4 );
+
+    //Set DMA Offset
+    m_rsp->RSP_SetDMAOffsets(0,0);
+}
+
+//-----------------------------------------------------------------------------
+//! Perfect Dark Vertex
+//-----------------------------------------------------------------------------
+void UCode9::PerfectDark_Vertex(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("PerfectDark_Vertex", M64MSG_VERBOSE);
+    RSPUCode9AddColorIndexVertices* temp = (RSPUCode9AddColorIndexVertices*)ucode;
+
+    //Set Color Index Vertices
+    m_rsp->RSP_CIVertex(temp->segmentAddress, temp->numVertices + 1, temp->firstVertexIndex);
+}
+
+//-----------------------------------------------------------------------------
+//! Perfect Dark Color Base
+//-----------------------------------------------------------------------------
+void UCode9::PerfectDark_VertexColorBase(MicrocodeArgument* ucode)
+{
+    Logger::getSingleton().printMsg("PerfectDark_VertexColorBase", M64MSG_VERBOSE);
+    RSPUCodeSetVertexColorBase* temp = (RSPUCodeSetVertexColorBase*)ucode;
+
+    //Set Vertex Color Base
+    m_rsp->RSP_SetVertexColorBase(temp->rdramAddress);
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h
new file mode 100755 (executable)
index 0000000..dfc15c3
--- /dev/null
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_9_H_
+#define UCODE_9_H_
+
+//Includes
+#include "UCodeDefs.h"
+
+class GBI;
+class RSP;
+
+//*****************************************************************************
+//! UCode9
+//! Microcode used to play Perfect Dark
+//*****************************************************************************
+class UCode9
+{
+public:
+
+    //Constructor / Destructor
+    UCode9();
+    ~UCode9();
+
+    static void initialize(RSP* rsp);
+    static void initializeGBI(GBI* gbi);
+
+    static void PerfectDark_Vertex(MicrocodeArgument* ucode);
+    static void PerfectDark_VertexColorBase(MicrocodeArgument* ucode);
+
+private:
+
+    static RSP* m_rsp;        //!< Pointer to Reality Signal Processor 
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h
new file mode 100755 (executable)
index 0000000..802a247
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_DATA_H_
+#define UCODE_DATA_H_
+
+//*****************************************************************************
+// UCode Definitions
+//*****************************************************************************
+#define F3D         0     // Super Mario 64
+#define F3DEX       1
+#define F3DEX2      2
+#define L3D         3
+#define L3DEX       4
+#define L3DEX2      5
+#define S2DEX       6
+#define S2DEX2      7
+#define F3DPD       8
+#define F3DDKR      9
+#define F3DWRUS    10
+#define NONE       11
+
+//*****************************************************************************
+//* UCode Data
+//! Used to Identify witch ucode diffrent games use
+//*****************************************************************************
+struct UcodeData
+{
+    unsigned int ucode;          //!< ID of ucode
+    unsigned int crc_size;       //!< Hash value used to identify ucode
+    unsigned int crc_800;        //!< Hash value used to identify ucode
+    const char*  ucode_name;     //!< Name used to identify ucode
+    bool         non_nearclip;   //!< Does ucode support near clipping?
+    bool         reject;         //!< 
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp
new file mode 100755 (executable)
index 0000000..82b28c4
--- /dev/null
@@ -0,0 +1,348 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "UCodeSelector.h"
+#include "Memory.h"
+#include "CRCCalculator.h"
+#include "UCodeIdentificationData.h"
+#include <cstdio>
+#include <cstring>
+#include <string>
+#include "Logger.h"
+
+#ifndef WIN32
+#define strnicmp strncasecmp
+#endif
+
+//*****************************************************************************
+//* UCode Data
+//! Used to Identify witch ucode diffrent games use
+//*****************************************************************************
+static UcodeData g_UcodeData[] = 
+{
+//  id, crc_size,    crc_800,     ucode string,
+    {0, 0x150c3ce8, 0x150c3ce8, "RSP SW Version: 2.0D, 04-01-96",}, // Super Mario 64
+    {4, 0x2b94276f, 0x2b94276f, "RSP SW Version: 2.0D, 04-01-96",}, // Wave Race 64 (v1.0)
+    {16,0xb1870454, 0xb1870454, "RSP SW Version: 2.0D, 04-01-96",}, // Star Wars - Shadows of the Empire (v1.0), 
+    {0, 0x51671ae4, 0x51671ae4, "RSP SW Version: 2.0D, 04-01-96",}, // Pilot Wings 64, 
+    {0, 0x67b5ac55, 0x67b5ac55, "RSP SW Version: 2.0D, 04-01-96",}, // Wibble, 
+    {0, 0x64dc8104, 0x64dc8104, "RSP SW Version: 2.0D, 04-01-96",}, // Dark Rift, 
+    {0, 0x309f363d, 0x309f363d, "RSP SW Version: 2.0D, 04-01-96",}, // Killer Instinct Gold, 
+    {0, 0xfcb57e57, 0xfcb57e57, "RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, 
+    {0, 0xb420f35a, 0xb420f35a, "RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, 
+    {0, 0x6e26c1df, 0x7c98e9c2, "RSP SW Version: 2.0D, 04-01-96",}, 
+    {2, 0xc02ac7bc, 0xc02ac7bc, "RSP SW Version: 2.0G, 09-30-96",}, // GoldenEye 007, 
+    {0, 0xe5fee3bc, 0xe5fee3bc, "RSP SW Version: 2.0G, 09-30-96",}, // Aero Fighters Assault, 
+    {8, 0xe4bb5ad8, 0x80129845, "RSP SW Version: 2.0G, 09-30-96",}, // Puzzle Master 64, 
+    {0, 0x72109ec6, 0x72109ec6, "RSP SW Version: 2.0H, 02-12-97",}, // Duke Nukem 64, 
+    {0, 0xf24a9a04, 0xf24a9a04, "RSP SW Version: 2.0H, 02-12-97",}, // Tetrisphere, 
+    {15,0x700de42e, 0x700de42e, "RSP SW Version: 2.0H, 02-12-97",}, // Wipeout 64 (uses GBI1 too!), 
+    {15,0x1b304a74, 0x1b304a74, "RSP SW Version: 2.0H, 02-12-97",}, // Flying Dragon, 
+    {15,0xe4bb5ad8, 0xa7b2f704, "RSP SW Version: 2.0H, 02-12-97",}, // Silicon Valley, 
+    {15,0xe4bb5ad8, 0x88202781, "RSP SW Version: 2.0H, 02-12-97",}, // Glover, 
+    {0, 0xe466b5bd, 0xe466b5bd, "Unknown 0xe466b5bd, 0xe466b5bd",}, // Dark Rift, 
+    {9, 0x7064a163, 0x7064a163, "Unknown 0x7064a163, 0x7064a163",}, // Perfect Dark (v1.0), 
+    {0, 0x6522df69, 0x71bd078d, "Unknown 0x6522df69, 0x71bd078d",}, // Tetris 
+    {0, 0x6522df69, 0x1b0c23a8, "Unknown 0x6522df69, 0x1b0c23a8",}, // Pachinko Nichi 
+
+    // GBI1
+    
+    {1, 0x45ca328e, 0x45ca328e, "RSP Gfx ucode F3DLX         0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64, 
+    {1, 0x98e3b909, 0x98e3b909, "RSP Gfx ucode F3DEX         0.95 Yoshitaka Yasumoto Nintendo.",},    // Mario Kart 64
+    {1, 0x5d446090, 0x5d446090, "RSP Gfx ucode F3DLP.Rej     0.96 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou J. League Perfect Striker, 
+    {1, 0x244f5ca3, 0x244f5ca3, "RSP Gfx ucode F3DEX         1.00 Yoshitaka Yasumoto Nintendo.",}, // F-1 Pole Position 64, 
+    {1, 0x6a022585, 0x6a022585, "RSP Gfx ucode F3DEX.NoN     1.00 Yoshitaka Yasumoto Nintendo.",1}, // Turok - The Dinosaur Hunter (v1.0), 
+    {1, 0x150706be, 0x150706be, "RSP Gfx ucode F3DLX.NoN     1.00 Yoshitaka Yasumoto Nintendo.",1}, // Extreme-G, 
+    {1, 0x503f2c53, 0x503f2c53, "RSP Gfx ucode F3DEX.NoN     1.21 Yoshitaka Yasumoto Nintendo.",1}, // Bomberman 64, 
+    {1, 0xc705c37c, 0xc705c37c, "RSP Gfx ucode F3DLX         1.21 Yoshitaka Yasumoto Nintendo.",}, // Fighting Force 64, Wipeout 64
+    {1, 0xa2146075, 0xa2146075, "RSP Gfx ucode F3DLX.NoN     1.21 Yoshitaka Yasumoto Nintendo.",1}, // San Francisco Rush - Extreme Racing, 
+    {1, 0xb65aa2da, 0xb65aa2da, "RSP Gfx ucode L3DEX         1.21 Yoshitaka Yasumoto Nintendo.",}, // Wipeout 64, 
+    {1, 0x0c8e5ec9, 0x0c8e5ec9, "RSP Gfx ucode F3DEX         1.21 Yoshitaka Yasumoto Nintendo.",}, // 
+    {1, 0xe30795f2, 0xa53df3c4, "RSP Gfx ucode F3DLP.Rej     1.21 Yoshitaka Yasumoto Nintendo.",0,1},
+
+    {1, 0xaebeda7d, 0xaebeda7d, "RSP Gfx ucode F3DLX.Rej     1.21 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou World Soccer 3, 
+    {1, 0x0c8e5ec9, 0x0c8e5ec9, "RSP Gfx ucode F3DEX         1.23 Yoshitaka Yasumoto Nintendo" ,},  // Wave Race 64 (Rev. 2) - Shindou Rumble Edition (JAP) 
+    {1, 0xc705c37c, 0xc705c37c, "RSP Gfx ucode F3DLX         1.23 Yoshitaka Yasumoto Nintendo.",}, // GT
+    {1, 0x2a61350d, 0x2a61350d, "RSP Gfx ucode F3DLX         1.23 Yoshitaka Yasumoto Nintendo.",}, // Toy Story2
+    {1, 0x0c8e5ec9, 0x0c8e5ec9, "RSP Gfx ucode F3DEX         1.23 Yoshitaka Yasumoto Nintendo.",}, // Wave Race 64 Shindou Edition
+    {12,0xfc6529aa, 0xfc6529aa, "RSP Gfx ucode F3DEX         1.23 Yoshitaka Yasumoto Nintendo.",}, // Superman - The Animated Series, 
+    {1, 0xa56cf996, 0xa56cf996, "RSP Gfx ucode L3DEX         1.23 Yoshitaka Yasumoto Nintendo.",}, // Flying Dragon, 
+    {1, 0xcc83b43f, 0xcc83b43f, "RSP Gfx ucode F3DEX.NoN     1.23 Yoshitaka Yasumoto Nintendo.",1}, // AeroGauge, 
+    {1, 0xca8927a0, 0xca8927a0, "RSP Gfx ucode F3DLX.Rej     1.23 Yoshitaka Yasumoto Nintendo.",0,1},    // Puzzle Bobble 64, 
+    {1, 0x25689c75, 0xbe481ae8, "RSP Gfx ucode F3DLP.Rej     1.23 Yoshitaka Yasumoto Nintendo.",0,1},
+    {1, 0xd2d747b7, 0xd2d747b7, "RSP Gfx ucode F3DLX.NoN     1.23 Yoshitaka Yasumoto Nintendo.",1}, // Penny Racers, 
+    {1, 0xa849c858, 0x5bd32b5a, "RSP Gfx ucode F3DTEX/A      1.23 Yoshitaka Yasumoto Nintendo.",}, // Tamagotchi 
+
+    {7, 0xecd8b772, 0xecd8b772, "RSP Gfx ucode S2DEX  1.06 Yoshitaka Yasumoto Nintendo.",}, // Yoshi's Story, 
+    {7, 0xf59132f5, 0xf59132f5, "RSP Gfx ucode S2DEX  1.07 Yoshitaka Yasumoto Nintendo.",}, // Bakuretsu Muteki Bangaioh, 
+    {7, 0x961dd811, 0x961dd811, "RSP Gfx ucode S2DEX  1.03 Yoshitaka Yasumoto Nintendo.",}, // GT
+
+    {5, 0x3e083afa, 0x722f97cc, "RSP Gfx ucode F3DEX.NoN   fifo 2.03  Yoshitaka Yasumoto 1998 Nintendo.",1}, // F-Zero X, 
+    {5, 0xa8050bd1, 0xa8050bd1, "RSP Gfx ucode F3DEX       fifo 2.03  Yoshitaka Yasumoto 1998 Nintendo.",}, // F-Zero X, 
+    {5, 0x4e8055f0, 0x4e8055f0, "RSP Gfx ucode F3DLX.Rej   fifo 2.03  Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, 
+    {5, 0xabf001f5, 0xabf001f5, "RSP Gfx ucode F3DFLX.Rej  fifo 2.03F Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, 
+    {5, 0xadb4b686, 0xadb4b686, "RSP Gfx ucode F3DEX       fifo 2.04  Yoshitaka Yasumoto 1998 Nintendo.",}, // Top Gear Rally 2, 
+    {5, 0x779e2a9b, 0x779e2a9b, "RSP Gfx ucode F3DEX.NoN   fifo 2.04  Yoshitaka Yasumoto 1998 Nintendo.",1}, // California Speed, 
+    {5, 0xa8cb3e09, 0xa8cb3e09, "RSP Gfx ucode L3DEX       fifo 2.04  Yoshitaka Yasumoto 1998 Nintendo.",}, // In-Fisherman Bass Hunter 64, 
+    {5, 0x2a1341d6, 0x2a1341d6, "RSP Gfx ucode F3DEX       fifo 2.04H Yoshitaka Yasumoto 1998 Nintendo.",}, // Kirby 64 - The Crystal Shards, 
+    {5, 0x3e083afa, 0x89a8e0ed, "RSP Gfx ucode F3DEX.NoN   fifo 2.05  Yoshitaka Yasumoto 1998 Nintendo.",1}, // Carmageddon 64 (uncensored), 
+    {5, 0x4964b75d, 0x4964b75d, "RSP Gfx ucode F3DEX.NoN   fifo 2.05  Yoshitaka Yasumoto 1998 Nintendo.",1}, 
+    {5, 0x39e3e95a, 0x39e3e95a, "RSP Gfx ucode F3DEX       fifo 2.05  Yoshitaka Yasumoto 1998 Nintendo."}, // Knife Edge - Nose Gunner, 
+    {5, 0xd2913522, 0xd2913522, "RSP Gfx ucode F3DAM       fifo 2.05  Yoshitaka Yasumoto 1998 Nintendo."}, // Hey You, Pikachu!, 
+    {5, 0x3e083afa, 0xc998443f, "RSP Gfx ucode F3DEX       xbus 2.05  Yoshitaka Yasumoto 1998 Nintendo."}, //Triple play
+    {5, 0xf4184a7d, 0xf4184a7d, "RSP Gfx ucode F3DEX       fifo 2.06  Yoshitaka Yasumoto 1998 Nintendo.",}, // Hey You, Pikachu!, 
+    {5, 0x595a88de, 0x595a88de, "RSP Gfx ucode F3DEX.Rej   fifo 2.06  Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Bio Hazard 2, 
+    {5, 0x0259f764, 0x0259f764, "RSP Gfx ucode F3DLX.Rej   fifo 2.06  Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Mario Party, 
+    {5, 0xe1a5477a, 0xe1a5477a, "RSP Gfx ucode F3DEX.NoN   xbus 2.06  Yoshitaka Yasumoto 1998 Nintendo.",1}, // Command & Conquer, 
+    {5, 0x4cfa0a19, 0x4cfa0a19, "RSP Gfx ucode F3DZEX.NoN  fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, // The Legend of Zelda - Ocarina of Time (v1.0), 
+    {5, 0x2cbd9514, 0x5f40b9f5, "RSP Gfx ucode F3DZEX.NoN  fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, 
+
+    {5, 0x3e083afa, 0x882680f4, "RSP Gfx ucode L3DEX       fifo 2.07  Yoshitaka Yasumoto 1998 Nintendo."},    // Polaris Sno
+
+    {5, 0xdeb1cac0, 0xdeb1cac0, "RSP Gfx ucode F3DEX.NoN   fifo 2.07  Yoshitaka Yasumoto 1998 Nintendo.",1}, // Knockout Kings 2000, 
+    {5, 0xf4184a7d, 0xf4184a7d, "RSP Gfx ucode F3DEX       fifo 2.07  Yoshitaka Yasumoto 1998 Nintendo.",}, // Xena Warrior Princess - Talisman of Fate, Army Men - Air Combat, Destruction Derby
+    {5, 0x4b013e60, 0x4b013e60, "RSP Gfx ucode F3DEX       xbus 2.07  Yoshitaka Yasumoto 1998 Nintendo.",}, // Lode Runner 3-D, 
+    {5, 0xd1a63836, 0xd1a63836, "RSP Gfx ucode L3DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // Hey You, Pikachu!, 
+    {5, 0x97193667, 0x97193667, "RSP Gfx ucode F3DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // Top Gear Hyper-Bike, 
+    {5, 0x92149ba8, 0x92149ba8, "RSP Gfx ucode F3DEX       fifo 2.08  Yoshitaka Yasumoto/Kawasedo 1999.",}, // Paper Mario, 
+    {5, 0xae0fb88f, 0xae0fb88f, "RSP Gfx ucode F3DEX       xbus 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF WrestleMania 2000, 
+    {5, 0xc572f368, 0xc572f368, "RSP Gfx ucode F3DLX.Rej   xbus 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF No Mercy, 
+    {5, 0x3e083afa, 0x74252492, "RSP Gfx ucode F3DEX.NoN   xbus 2.08  Yoshitaka Yasumoto 1999 Nintendo.",1}, 
+
+    {5, 0x9c2edb70, 0xea98e740, "RSP Gfx ucode F3DEX.NoN   fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",1}, // LEGO Racers, Fighter's Destiny 2
+    {5, 0x79e004a6, 0x79e004a6, "RSP Gfx ucode F3DLX.Rej   fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // Mario Party 2, 
+    {5, 0xaa6ab3ca, 0xaa6ab3ca, "RSP Gfx ucode F3DEX.Rej   fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // V-Rally Edition 99, 
+    {5, 0x2c597e0f, 0x2c597e0f, "RSP Gfx ucode F3DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // Cruis'n Exotica,
+    {10, 0x4e5f3e3b, 0x4e5f3e3b,"RSP Gfx ucode F3DEXBG.NoN fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",1}, // Conker The Bad Fur Day 
+    {5, 0x61f31862, 0x61f31862, "RSP Gfx ucode F3DEX.NoN   fifo 2.08H Yoshitaka Yasumoto 1999 Nintendo.",1}, // Pokemon Snap, 
+    {5, 0x005f5b71, 0x005f5b71, "RSP Gfx ucode F3DZEX.NoN  fifo 2.08I Yoshitaka Yasumoto/Kawasedo 1999.",1}, // The Legend of Zelda 2 - Majora's Mask, 
+
+    {3, 0x41839d1e, 0x41839d1e, "RSP Gfx ucode S2DEX       fifo 2.05  Yoshitaka Yasumoto 1998 Nintendo.",}, // Chou Snobow Kids, 
+    {3, 0x2cbd9514, 0xc639dbb9, "RSP Gfx ucode S2DEX       xbus 2.06  Yoshitaka Yasumoto 1998 Nintendo.",},
+    {3, 0xec89e273, 0xec89e273, "RSP Gfx ucode S2DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // V-Rally Edition 99, 
+    {3, 0x9429b7d6, 0x9429b7d6, "RSP Gfx ucode S2DEX       xbus 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // Star Craft, 
+    //{14,0x5a72397b, 0xec89e273, "RSP Gfx ucode S2DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // OgreBattle Background, 
+    {3, 0x2cbd9514, 0xec89e273, "RSP Gfx ucode S2DEX       fifo 2.08  Yoshitaka Yasumoto 1999 Nintendo.",}, // Zelda MM, 
+
+    {6, 0x6aef74f8, 0x6aef74f8, "Unknown 0x6aef74f8, 0x6aef74f8",}, // Diddy Kong Racing (v1.0), 
+    {6, 0x4c4eead8, 0x4c4eead8, "Unknown 0x4c4eead8, 0x4c4eead8",}, // Diddy Kong Racing (v1.1), 
+
+    {1, 0xed421e9a, 0xed421e9a, "Unknown 0xed421e9a, 0xed421e9a",}, // Kuiki Uhabi Suigo, 
+    {5, 0x37751932, 0x55c0fd25, "Unknown 0x37751932, 0x55c0fd25",}, // Bio Hazard 2, 
+    {11,0xbe0b83e7, 0xbe0b83e7,"Unknown 0xbe0b83e7, 0xbe0b83e7",},  // Jet Force Gemini, 
+
+    {17, 0x02e882cf, 0x2ad17281, "Unknown 0x02e882cf, 0x2ad17281",}, // Indiana Jones, 
+    {17, 0x1f7d9118, 0xdab2199b, "Unknown 0x1f7d9118, 0xdab2199b",}, // Battle Naboo, 
+    {17, 0x74583614, 0x74583614, "Unknown 0x74583614, 0x74583614",}, // Star Wars - Rogue Squadron, 
+    {17, 0xe37e2f49, 0x1eb63fd8, "Unknown 0xe37e2f49, 0x1eb63fd8",}, // Star Wars - Rogue Squadron, 
+    {17, 0x8ce1af3d, 0xb2760ea2, "Unknown 0x8ce1af3d, 0xb2760ea2",}, // Star Wars - Rogue Squadron, 
+
+    {18, 0x7b685972, 0x57b8095a, "Unknown 0x7b685972, 0x57b8095a",}, // World Driver Championship
+    {18, 0xe92dbb9b, 0x57b8095a, "Unknown 0xe92dbb9b, 0x57b8095a",}, // World Driver Championship
+    {18, 0xe6c9acc1, 0x65f80845, "Unknown 0xe6c9acc1, 0x65f80845",}, // World Driver Championship
+    {18, 0x6522df69, 0x720b88a0, "Unknown 0x6522df69, 0x720b88a0",}, // World Driver Championship
+    {18, 0x6522df69, 0xf1e8ba9e, "Unknown 0x6522df69, 0xf1e8ba9e",}, // World Driver Championship
+
+    {19, 0xa486bed3, 0xa486bed3, "Unknown 0xa486bed3, 0xa486bed3",}, // Last Legion UX, 
+    {19, 0x6b519381, 0xfebacfd8, "Unknown in Toukan Road",},    // I don't know which ucode
+
+    {20, 0x6d2a01b1, 0x6d2a01b1, "RSP Gfx ucode ZSortp 0.33 Yoshitaka Yasumoto Nintendo.",}, // Mia Hamm Soccer 64, 
+};
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+UCodeSelector::UCodeSelector()
+{
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+UCodeSelector::~UCodeSelector()
+{
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//! Saves pointer to memory
+//! @param[in] memory Pointer to memory manager used to access RDRAM
+//-----------------------------------------------------------------------------
+bool UCodeSelector::initialize(Memory* memory)
+{
+    m_memory = memory;
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+//* check UCode
+//! Will select a good ucode
+//! @return ID of The selected ucode
+//-----------------------------------------------------------------------------
+unsigned int UCodeSelector::checkUCode( unsigned int ucStart, 
+                                        unsigned int ucDataStart, 
+                                        unsigned int ucSize, 
+                                        unsigned int ucDataSize )
+{
+    unsigned char* RDRAM = m_memory->getRDRAM();
+    unsigned int base = ucStart & 0x1fffffff;
+
+    //Calculate Hash values
+    CRCCalculator crcCalculator;
+    unsigned int crc_ucDataSize = crcCalculator.calcCRC(0, &RDRAM[base], 8); //ucDataSize
+    unsigned int crc_800        = crcCalculator.calcCRC(0, &RDRAM[base], 0x800);
+
+    //Get UCode String
+    char ucodeString[500];
+    bool foundString = _extractUCodeString(ucDataStart, ucodeString);
+
+    //Try to identify ucode
+    int ucode = _detectUCode(crc_ucDataSize, crc_800, ucodeString );
+
+    //Is ucode valid?
+    if ( ucode == -1 && foundString )
+    {
+        //We were unable to identify ucode so try from string
+        ucode = _detectUCodeFromString(ucodeString);
+        
+        //Is ucode valid?
+        if ( ucode == -5 )
+        {
+            Logger::getSingleton().printMsg("Unable to find UCode!", M64MSG_WARNING);
+            ucode = 5; //We where unable to find ucode, so just select one and hope for the best.
+        }
+    }
+    char logMsg[530];
+    if ( foundString )
+    {
+        sprintf(logMsg, "Selected UCode %d String=%s", ucode, ucodeString);
+        Logger::getSingleton().printMsg(logMsg, M64MSG_INFO);
+    }
+    else
+    {
+        sprintf(logMsg, "Selected UCode %d Could not find UCode String ", ucode);
+        Logger::getSingleton().printMsg(logMsg, M64MSG_WARNING);
+    }
+
+    return ucode;
+}
+
+//-----------------------------------------------------------------------------
+//* Extract UCode String
+//! @param ucDataStart Address in RAM memory where to find UCode Data were
+//!                    the string is placed.
+//! @param out The string identifing what ucode to use
+//! @return True if we found the string OK.
+//-----------------------------------------------------------------------------
+bool UCodeSelector::_extractUCodeString(unsigned int ucDataStart, char out[500])
+{
+    unsigned int base = ucDataStart & 0x1fffffff;
+    signed char* RDRAM = (signed char*)m_memory->getRDRAM();
+    
+    //Check for error
+    if ( base >= m_memory->getRDRAMSize()+0x1000 )
+    {
+        return false;
+    }    
+
+    //Extract string
+    for (unsigned int i=0; i<0x1000; ++i)
+    {
+        //If found RSP string
+        if ( RDRAM[base+((i+0)^3)] == 'R' && 
+             RDRAM[base+((i+1)^3)] == 'S' && 
+             RDRAM[base+((i+2)^3)] == 'P' )
+        {                            
+            //while there are characters in string
+            char* p = out;
+            while ( RDRAM[base+(i^3)] >= ' ' )
+            {
+                //Copy string to output
+                *p++ = RDRAM[base+(i^3)];
+                i++;
+            }
+            *p++ = 0;                    
+            return true;   //Found ucode string
+        }
+    }
+    return false;
+}
+
+//-----------------------------------------------------------------------------
+//* Detect UCode
+//! Use hash values to detect ucodes
+//! @return Index of detected ucode, -1 if no ucode was found
+//-----------------------------------------------------------------------------
+int UCodeSelector::_detectUCode(unsigned int crcUCodeDataSize, unsigned int crc800, const char ucodeStr[500])
+{
+    //For each ucode
+    for (unsigned int i=0; i<sizeof(g_UcodeData)/sizeof(UcodeData); ++i)
+    {
+        if ( crc800 == g_UcodeData[i].crc_800 )
+        {
+            //Found ucode!!!
+            //gRSP.bNearClip = !g_UcodeData[i].non_nearclip;
+            //gRSP.bRejectVtx = g_UcodeData[i].reject;
+            return g_UcodeData[i].ucode;
+        }
+    }
+
+    //gRSP.bNearClip = false;
+    //gRSP.bRejectVtx = false;
+    return -1;  //Return invalid number
+}
+
+//-----------------------------------------------------------------------------
+//! Detect UCode from string
+//! @param ucodeStr String from ROM that tells use wich ucode it uses.
+//! @return Index of detected ucode, -1 if no ucode was found
+//-----------------------------------------------------------------------------
+int UCodeSelector::_detectUCodeFromString(const char ucodeStr[500])
+{
+    //UCode F3D?
+    const char tempUCode0[] = "RSP SW Version: 2.0";
+    if ( strnicmp( ucodeStr, tempUCode0, strlen(tempUCode0) ) == 0 )
+    {
+        return F3D;
+    }
+    if ( strncmp(&ucodeStr[4], "SW", 2) == 0 )
+    {
+        return F3D;
+    }
+
+    //If String = "RSP Gfx ucode "
+    const char temp[] = "RSP Gfx ucode ";
+    if ( strnicmp(ucodeStr, temp, strlen(temp)) == 0 )
+    {
+        //If v1.x
+        if( strstr(ucodeStr, "1.") != 0 )
+        {
+            return (!strstr(ucodeStr, "S2DEX")) ? 7  : 1;
+        }
+        //If v2.x
+        else if( strstr(ucodeStr,"2.") != 0 )
+        {
+            return (!strstr(ucodeStr,"S2DEX")) ? 3 : 5;
+        }
+    }
+
+    return -1;
+}
diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.h
new file mode 100755 (executable)
index 0000000..0cb5375
--- /dev/null
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef UCODE_SELECTOR_H_
+#define UCODE_SELECTOR_H_
+
+//Forward declarations
+class Memory;
+
+//*****************************************************************************
+//* UCode Selector
+//! Class for selecting a good ucode for the current game
+//*****************************************************************************
+class UCodeSelector
+{
+public:
+
+    //Constructor / Destructor
+    UCodeSelector();
+    ~UCodeSelector();
+
+    //Initialize
+    bool initialize(Memory* memory);
+
+    //Check ucode
+    unsigned int checkUCode( unsigned int ucStart, 
+                             unsigned int ucDStart, 
+                             unsigned int ucSize, 
+                             unsigned int ucDSize );
+
+private:
+
+    //Private functions
+    bool _extractUCodeString(unsigned int ucDataStart, char out[500]);
+    int _detectUCode(unsigned int crcUCodeDataSize, unsigned int crc800, const char ucodeStr[500]);
+    int _detectUCodeFromString(const char ucodeStr[500]);
+
+private:
+
+    Memory* m_memory;   //!< Pointer to memory manager
+
+};
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/utils/MemoryLeakDetector.h b/source/mupen64plus-video-arachnoid/src/utils/MemoryLeakDetector.h
new file mode 100755 (executable)
index 0000000..86fad4d
--- /dev/null
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MEMORY_LEAK_DETECTOR_H
+#define MEMORY_LEAK_DETECTOR_H
+
+#include "m64p.h"
+#include <cstdio>
+#if defined(WIN32) && !defined(__MINGW32__)
+#include <crtdbg.h>
+#endif
+
+//*****************************************************************************
+//* Memory Leak Detector Class
+//! Class for checking if there are any memory leaks.
+//*****************************************************************************
+class CMemoryLeakDetector
+{
+public:
+    
+    //Constructor
+    CMemoryLeakDetector() 
+    { 
+#if defined(WIN32) && !defined(__MINGW32__)
+        ::OutputDebugString(">>> Memory leak detection enabled <<<\n"); 
+#endif
+    }
+
+    //Destructor
+    ~CMemoryLeakDetector()
+    { 
+#if defined(WIN32) && !defined(__MINGW32__)
+        if ( !_CrtDumpMemoryLeaks() )
+        {
+            ::OutputDebugString(">>> No memory leak detected <<<\n"); 
+        }
+#endif
+    }
+};
+
+CMemoryLeakDetector md;
+
+#endif
diff --git a/source/mupen64plus-video-arachnoid/src/video_api_export.ver b/source/mupen64plus-video-arachnoid/src/video_api_export.ver
new file mode 100644 (file)
index 0000000..c4db656
--- /dev/null
@@ -0,0 +1,22 @@
+{ global:
+PluginStartup;
+PluginShutdown;
+PluginGetVersion;
+ChangeWindow;
+InitiateGFX;
+MoveScreen;
+ProcessDList;
+ProcessRDPList;
+RomClosed;
+RomOpen;
+ShowCFB;
+UpdateScreen;
+ViStatusChanged;
+ViWidthChanged;
+ReadScreen2;
+SetRenderingCallback;
+ResizeVideoOutput;
+FBRead;
+FBWrite;
+FBGetFrameBufferInfo;
+local: *; };