--- /dev/null
+repo: 976896f303442924a04de6fb0725b98269a9bbe3
+node: d88e66b6a15a517db588fdb5eabf1ad4b7de0056
+branch: default
+latesttag: 2.0.0
+latesttagdistance: 1
--- /dev/null
+syntax: regexp
+
+^projects/unix/_obj/
+^projects/unix/mupen64plus-video-arachnoid.so$
--- /dev/null
+7713c313dc69e551761636645e9ad94d2e3a93c6 1.99.4
+567e98c190507a3818bf851ecb2b5de600de7896 1.99.5
+2e14d1a541b7a6c2a09c4c6173370ca336f4c001 2.0.0
--- /dev/null
+ 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.
--- /dev/null
+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.
--- /dev/null
+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
--- /dev/null
+<?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 "$(TargetPath)" "$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)""
+ />
+ </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 "$(TargetPath)" "$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)"
"
+ />
+ <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 "$(TargetPath)" "$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)""
+ />
+ </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'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>
--- /dev/null
+#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+# * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+};
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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();
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+ }
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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 );
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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 );
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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)
+{
+
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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];
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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++;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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_
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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");
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 */
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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;
+}
+
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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?
+}
+
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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();
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/**
+ *
+ * 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;
+}
--- /dev/null
+/**
+ *
+ * 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 */
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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 );
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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);
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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;
+}
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+/******************************************************************************
+ * 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
--- /dev/null
+{ global:
+PluginStartup;
+PluginShutdown;
+PluginGetVersion;
+ChangeWindow;
+InitiateGFX;
+MoveScreen;
+ProcessDList;
+ProcessRDPList;
+RomClosed;
+RomOpen;
+ShowCFB;
+UpdateScreen;
+ViStatusChanged;
+ViWidthChanged;
+ReadScreen2;
+SetRenderingCallback;
+ResizeVideoOutput;
+FBRead;
+FBWrite;
+FBGetFrameBufferInfo;
+local: *; };