From: ptitSeb Date: Tue, 24 Sep 2013 19:59:33 +0000 (+0200) Subject: Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the... X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22726e4d55be26faa48b57b22689cbedde27ae44;p=mupen64plus-pandora.git Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the OpenPandora --- diff --git a/source/mupen64plus-video-arachnoid/.hg_archival.txt b/source/mupen64plus-video-arachnoid/.hg_archival.txt new file mode 100644 index 0000000..76878a8 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/.hg_archival.txt @@ -0,0 +1,5 @@ +repo: 976896f303442924a04de6fb0725b98269a9bbe3 +node: d88e66b6a15a517db588fdb5eabf1ad4b7de0056 +branch: default +latesttag: 2.0.0 +latesttagdistance: 1 diff --git a/source/mupen64plus-video-arachnoid/.hgignore b/source/mupen64plus-video-arachnoid/.hgignore new file mode 100644 index 0000000..8f52e27 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/.hgignore @@ -0,0 +1,4 @@ +syntax: regexp + +^projects/unix/_obj/ +^projects/unix/mupen64plus-video-arachnoid.so$ diff --git a/source/mupen64plus-video-arachnoid/.hgtags b/source/mupen64plus-video-arachnoid/.hgtags new file mode 100644 index 0000000..609eac5 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/.hgtags @@ -0,0 +1,3 @@ +7713c313dc69e551761636645e9ad94d2e3a93c6 1.99.4 +567e98c190507a3818bf851ecb2b5de600de7896 1.99.5 +2e14d1a541b7a6c2a09c4c6173370ca336f4c001 2.0.0 diff --git a/source/mupen64plus-video-arachnoid/COPYING b/source/mupen64plus-video-arachnoid/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/source/mupen64plus-video-arachnoid/README b/source/mupen64plus-video-arachnoid/README new file mode 100644 index 0000000..49333a7 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/README @@ -0,0 +1,8 @@ +Arachnoid Graphics Plugin for Mupen64Plus +http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + +Derived from the Project64/1964 version of Arachnoid, available from: +http://sourceforge.net/projects/arachnoid/ + +To build, enter the projects/unix directory and type "make". +To build a debugging version, use "make DEBUG=1" instead. diff --git a/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln new file mode 100755 index 0000000..3cfc3cc --- /dev/null +++ b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsPlugin", "GraphicsPlugin.vcproj", "{6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Debug|Win32.ActiveCfg = Debug|Win32 + {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Debug|Win32.Build.0 = Debug|Win32 + {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Release|Win32.ActiveCfg = Release|Win32 + {6F7FDCD3-C278-4A5C-BD36-85D58AC75AFE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj new file mode 100755 index 0000000..e63d7dc --- /dev/null +++ b/source/mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj @@ -0,0 +1,922 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/mupen64plus-video-arachnoid/projects/unix/Makefile b/source/mupen64plus-video-arachnoid/projects/unix/Makefile new file mode 100755 index 0000000..a12ef44 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/projects/unix/Makefile @@ -0,0 +1,406 @@ +#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +# * Arachnoid - Makefile * +# * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * +# * Copyright (C) 2009 Richard42, Jon Ring * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with this program; if not, write to the * +# * Free Software Foundation, Inc., * +# * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * +# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +# Makefile for mupen64plus-video-arachnoid + +# detect operation system +UNAME ?= $(shell uname -s) +ifeq ("$(UNAME)","Linux") + OS = LINUX + SO_EXTENSION = so + SHARED = -shared +endif +ifeq ("$(UNAME)","linux") + OS = LINUX + SO_EXTENSION = so + SHARED = -shared +endif +ifneq ("$(filter GNU hurd,$(UNAME))","") + OS = LINUX + SO_EXTENSION = so + SHARED = -shared +endif +ifeq ("$(UNAME)","Darwin") + OS = OSX + LDLIBS += -liconv -lpng + SO_EXTENSION = dylib + SHARED = -bundle +endif +ifeq ("$(UNAME)","FreeBSD") + OS = FREEBSD + SO_EXTENSION = so + SHARED = -shared +endif +ifeq ("$(UNAME)","OpenBSD") + OS = FREEBSD + SO_EXTENSION = so + SHARED = -shared + $(warning OS type "$(UNAME)" not officially supported.') +endif +ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","") + OS = LINUX + SO_EXTENSION = so + SHARED = -shared +endif +ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW") + OS = MINGW + SO_EXTENSION = dll + SHARED = -shared + PIC = 0 +endif +ifeq ("$(OS)","NONE") + $(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues') +endif + +# detect system architecture +HOST_CPU ?= $(shell uname -m) +NO_ASM ?= 1 +ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","") + CPU := X86 + ifeq ("$(BITS)", "32") + ARCH_DETECTED := 64BITS_32 + else + ARCH_DETECTED := 64BITS + PIC ?= 1 + endif +endif +ifneq ("$(filter pentium i%86,$(HOST_CPU))","") + CPU := X86 + ARCH_DETECTED := 32BITS +endif +ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","") + CPU := PPC + ARCH_DETECTED := 32BITS + BIG_ENDIAN := 1 + PIC ?= 1 + $(warning Architecture "$(HOST_CPU)" not officially supported.') +endif +ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","") + CPU := PPC + ARCH_DETECTED := 64BITS + BIG_ENDIAN := 1 + PIC ?= 1 + $(warning Architecture "$(HOST_CPU)" not officially supported.') +endif +ifneq ("$(filter arm%,$(HOST_CPU))","") + ifeq ("$(filter arm%b,$(HOST_CPU))","") + CPU := ARM + ARCH_DETECTED := 32BITS + PIC ?= 1 + CFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a8 -fsigned-char -ffast-math -fpermissive + CFLAGS += -DHAVE_GLES + $(warning Architecture "$(HOST_CPU)" not officially supported.') + endif +endif + +# base CFLAGS, LDLIBS, and LDFLAGS +OPTFLAGS ?= -O3 +WARNFLAGS ?= -Wall +CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src \ + -I../../src/hash -I../../src/ucodes -I../../src/GBI -I../../src/RDP -I../../src/utils \ + -I../../src/log -I../../src/RSP -I../../src/framebuffer -I../../src/math -I../../src/renderer \ + -I../../src/Assembler -I../../src/texture -I../../src/config -I../../src/Combiner +CXXFLAGS += -fvisibility-inlines-hidden +LDFLAGS += $(SHARED) + +# On OS X, add a few extra flags to elegantly support cross-compilation and backward +# compatibility (and also the flags to link against OpenGL) +ifeq ($(OS), OSX) + # Select the proper SDK + # Also, SDKs are stored in a different location since XCode 4.3 + OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .) + OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .) + OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .) + OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`") + ifeq ($(OSX_XCODEGE43), 11) + OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs + else + OSX_SYSROOT := /Developer/SDKs + endif + + ifeq ($(CPU), X86) + ifeq ($(ARCH_DETECTED), 64BITS) + CFLAGS += -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk + LDFLAGS += -bundle + else + CFLAGS += -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk + LDFLAGS += -bundle + endif + endif +else + # search for OpenGL libraries + ifeq ($(OS), OSX) + GL_LDLIBS = -framework OpenGL + endif + ifeq ($(OS), MINGW) + GL_LDLIBS = -lopengl32 + endif + + ifeq ($(origin GL_CFLAGS) $(origin GL_LDLIBS), undefined undefined) + ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = $(CROSS_COMPILE)pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif + endif + + ifeq ($(shell $(PKG_CONFIG) --modversion gl 2>/dev/null),) + $(error No OpenGL development libraries found!) + endif + #GL_CFLAGS += $(shell $(PKG_CONFIG) --cflags gl) + #GL_LDLIBS += $(shell $(PKG_CONFIG) --libs gl) + GL_CFLAGS += $(shell sdl-config --cflags) + GL_LDLIBS += $(shell sdl-config --libs) + GL_CFLAGS += -I/mnt/utmp/codeblocks/usr/include/GLES + GL_LDLIBS += -lGLES_CM -lEGL -lrt + endif + CFLAGS += $(GL_CFLAGS) + LDLIBS += $(GL_LDLIBS) + + CFLAGS += -pthread +endif +ifeq ($(OS), LINUX) + LDLIBS += -ldl +endif +ifeq ($(OS), FREEBSD) + LDLIBS += -lc +endif + + +# Since we are building a shared library, we must compile with -fPIC on some architectures +# On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch +ifeq ($(PIC), 1) + CFLAGS += -fPIC +else + CFLAGS += -fno-PIC +endif + +ifeq ($(BIG_ENDIAN), 1) + CFLAGS += -DM64P_BIG_ENDIAN +endif + +# set mupen64plus core API header path +ifneq ("$(APIDIR)","") + CFLAGS += "-I$(APIDIR)" +else + TRYDIR = ../../../mupen64plus-core/src/api + ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","") + CFLAGS += -I$(TRYDIR) + else + TRYDIR = /usr/local/include/mupen64plus + ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","") + CFLAGS += -I$(TRYDIR) + else + TRYDIR = /usr/include/mupen64plus + ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","") + CFLAGS += -I$(TRYDIR) + endif + endif + endif +endif + +# set special flags per-system +ifeq ($(OS), LINUX) + # only export api symbols + LDFLAGS += -Wl,-version-script,$(SRCDIR)/video_api_export.ver +endif +ifneq ($(OS), FREEBSD) + ifeq ($(CPU), X86) + # tweak flags for 32-bit build on 64-bit system + ifeq ($(ARCH_DETECTED), 64BITS_32) + CFLAGS += -m32 + LDFLAGS += -Wl,-m,elf_i386 + endif + endif +else + ifeq ($(ARCH_DETECTED), 64BITS_32) + $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386) + endif +endif + +# reduced compile output when running make without V=1 +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + Q_CC = @echo ' CC '$@; + Q_CXX = @echo ' CXX '$@; + Q_LD = @echo ' LD '$@; +endif +endif + +# set base program pointers and flags +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +RM ?= rm -f +INSTALL ?= install +MKDIR ?= mkdir -p +COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c +COMPILE.cc = $(Q_CXX)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c +LINK.o = $(Q_LD)$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TARGET_ARCH) + +# set special flags for given Makefile parameters +ifeq ($(DEBUG),1) + CFLAGS += -g + INSTALL_STRIP_FLAG ?= +else + INSTALL_STRIP_FLAG ?= -s +endif + +# set installation options +ifeq ($(PREFIX),) + PREFIX := /usr/local +endif +ifeq ($(SHAREDIR),) + SHAREDIR := $(PREFIX)/share/mupen64plus +endif +ifeq ($(LIBDIR),) + LIBDIR := $(PREFIX)/lib +endif +ifeq ($(PLUGINDIR),) + PLUGINDIR := $(LIBDIR)/mupen64plus +endif + + +SRCDIR = ../../src +OBJDIR = _obj$(POSTFIX) + +# list of source files to compile +SOURCE = \ + $(SRCDIR)/main.cpp \ + $(SRCDIR)/log/Logger.cpp \ + $(SRCDIR)/config/Config.cpp \ + $(SRCDIR)/config/StringFunctions.cpp \ + $(SRCDIR)/GraphicsPlugin.cpp \ + $(SRCDIR)/OpenGLManager.cpp \ + $(SRCDIR)/renderer/OpenGLRenderer.cpp \ + $(SRCDIR)/framebuffer/FrameBuffer.cpp \ + $(SRCDIR)/FogManager.cpp \ + $(SRCDIR)/MultiTexturingExt.cpp \ + $(SRCDIR)/ExtensionChecker.cpp \ + $(SRCDIR)/SecondaryColorExt.cpp \ + $(SRCDIR)/Memory.cpp \ + $(SRCDIR)/math/Matrix4.cpp \ + $(SRCDIR)/texture/CachedTexture.cpp \ + $(SRCDIR)/texture/TextureCache.cpp \ + $(SRCDIR)/texture/ImageFormatSelector.cpp \ + $(SRCDIR)/hash/CRCCalculator.cpp \ + $(SRCDIR)/hash/CRCCalculator2.cpp \ + $(SRCDIR)/texture/TextureLoader.cpp \ + $(SRCDIR)/DisplayListParser.cpp \ + $(SRCDIR)/VI.cpp \ + $(SRCDIR)/ucodes/UCodeSelector.cpp \ + $(SRCDIR)/ucodes/UCode0.cpp \ + $(SRCDIR)/ucodes/UCode1.cpp \ + $(SRCDIR)/ucodes/UCode2.cpp \ + $(SRCDIR)/ucodes/UCode3.cpp \ + $(SRCDIR)/ucodes/UCode4.cpp \ + $(SRCDIR)/ucodes/UCode5.cpp \ + $(SRCDIR)/ucodes/UCode6.cpp \ + $(SRCDIR)/ucodes/UCode7.cpp \ + $(SRCDIR)/ucodes/UCode8.cpp \ + $(SRCDIR)/ucodes/UCode9.cpp \ + $(SRCDIR)/ucodes/UCode10.cpp \ + $(SRCDIR)/GBI/GBI.cpp \ + $(SRCDIR)/RSP/RSP.cpp \ + $(SRCDIR)/RSP/RSPMatrixManager.cpp \ + $(SRCDIR)/RSP/RSPVertexManager.cpp \ + $(SRCDIR)/RSP/RSPLightManager.cpp \ + $(SRCDIR)/Combiner/AdvancedCombinerManager.cpp \ + $(SRCDIR)/Combiner/CombinerBase.cpp \ + $(SRCDIR)/Combiner/AdvancedTexEnvCombiner.cpp \ + $(SRCDIR)/Combiner/SimpleTexEnvCombiner.cpp \ + $(SRCDIR)/Combiner/DummyCombiner.cpp \ + $(SRCDIR)/Combiner/CombinerStageMerger.cpp \ + $(SRCDIR)/Combiner/CombinerStageCreator.cpp \ + $(SRCDIR)/Combiner/CombinerCache.cpp \ + $(SRCDIR)/RomDetector.cpp \ + $(SRCDIR)/RDP/RDP.cpp \ + $(SRCDIR)/RDP/RDPInstructions.cpp \ + $(SRCDIR)/renderer/eglport.cpp \ + $(SRCDIR)/renderer/OpenGL2DRenderer.cpp \ + +ifeq ($(OS),MINGW) +SOURCE += $(SRCDIR)/osal_dynamiclib_win32.cpp +else +SOURCE += $(SRCDIR)/osal_dynamiclib_unix.cpp +endif + + +# generate a list of object files build, make a temporary directory for them +OBJECTS := $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SOURCE))) +OBJDIRS = $(dir $(OBJECTS)) +$(shell $(MKDIR) $(OBJDIRS)) + +# build targets + +TARGET = mupen64plus-video-arachnoid$(POSTFIX).$(SO_EXTENSION) +targets: + @echo "Mupen64plus-video-arachnoid N64 Graphics plugin makefile. " + @echo " Targets:" + @echo " all == Build Mupen64plus-video-arachnoid plugin" + @echo " clean == remove object files" + @echo " rebuild == clean and re-build all" + @echo " install == Install Mupen64Plus-video-arachnoid plugin" + @echo " uninstall == Uninstall Mupen64Plus-video-arachnoid plugin" + @echo " Options:" + @echo " BITS=32 == build 32-bit binaries on 64-bit machine" + @echo " APIDIR=path == path to find Mupen64Plus Core headers" + @echo " OPTFLAGS=flag == compiler optimization (default: -O3 -flto)" + @echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)" + @echo " PIC=(1|0) == Force enable/disable of position independent code" + @echo " POSTFIX=name == String added to the name of the the build (default: '')" + @echo " Install Options:" + @echo " PREFIX=path == install/uninstall prefix (default: /usr/local)" + @echo " LIBDIR=path == library prefix (default: PREFIX/lib)" + @echo " PLUGINDIR=path == path to install plugin libraries (default: LIBDIR/mupen64plus)" + @echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)" + @echo " Debugging Options:" + @echo " DEBUG=1 == add debugging symbols" + @echo " V=1 == show verbose compiler output" + +all: $(TARGET) + +install: $(TARGET) + $(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)" + $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)" + +uninstall: + $(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)" + + +clean: + $(RM) -r $(OBJDIR) $(TARGET) + +# build dependency files +CFLAGS += -MD +-include $(OBJECTS:.o=.d) + +CXXFLAGS += $(CFLAGS) + +# standard build rules +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(COMPILE.c) -o $@ $< + +$(OBJDIR)/%.o: $(SRCDIR)/%.cpp + $(COMPILE.cc) -o $@ $< + +$(TARGET): $(OBJECTS) + $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ + +.PHONY: all clean install uninstall targets diff --git a/source/mupen64plus-video-arachnoid/src/Assembler/assembler.h b/source/mupen64plus-video-arachnoid/src/Assembler/assembler.h new file mode 100755 index 0000000..783eb2c --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Assembler/assembler.h @@ -0,0 +1,384 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef ASSEMBLER_H_ +#define ASSEMBLER_H_ + +#ifndef WIN32 +#include +#endif +// Swap bytes from 80 37 12 40 +// to 40 12 37 80 +// dwLen must be a multiple of 4 +inline void swapRomHeaderBytes(void *v, unsigned int dwLen) +{ + int *b = (int*)v; + dwLen /= 4; + for (unsigned int i = 0; i < dwLen; ++i) + { + int tmp = b[i]; + b[i] = ((tmp & 0xff000000) >> 24) | ((tmp & 0x00ff0000) >> 8) | \ + ((tmp & 0x0000ff00) << 8) | ((tmp & 0x000000ff) << 24); + } +} + + +inline unsigned short swapword( unsigned short value ) +{ + return (value >> 8) | (value << 8); +} + +inline void UnswapCopy( void *src, void *dest, unsigned int numBytes ) +{ +#ifdef WIN32_ASM + __asm + { + mov ecx, 0 + mov esi, dword ptr [src] + mov edi, dword ptr [dest] + + mov ebx, esi + and ebx, 3 // ebx = number of leading bytes + + cmp ebx, 0 + jz StartDWordLoop + neg ebx + add ebx, 4 + + cmp ebx, [numBytes] + jle NotGreater + mov ebx, [numBytes] +NotGreater: + mov ecx, ebx + xor esi, 3 +LeadingLoop: // Copies leading bytes, in reverse order (un-swaps) + mov al, byte ptr [esi] + mov byte ptr [edi], al + sub esi, 1 + add edi, 1 + loop LeadingLoop + add esi, 5 + +StartDWordLoop: + mov ecx, dword ptr [numBytes] + sub ecx, ebx // Don't copy what's already been copied + + mov ebx, ecx + and ebx, 3 +// add ecx, 3 // Round up to nearest dword + shr ecx, 2 + + cmp ecx, 0 // If there's nothing to do, don't do it + jle StartTrailingLoop + + // Copies from source to destination, bswap-ing first +DWordLoop: + mov eax, dword ptr [esi] + bswap eax + mov dword ptr [edi], eax + add esi, 4 + add edi, 4 + loop DWordLoop +StartTrailingLoop: + cmp ebx, 0 + jz Done + mov ecx, ebx + xor esi, 3 + +TrailingLoop: + mov al, byte ptr [esi] + mov byte ptr [edi], al + sub esi, 1 + add edi, 1 + loop TrailingLoop +Done: + } +#else + + long long beginOffset = (long long)src & 3; + char *readPtr = (char*)src - beginOffset; + char *writePtr = (char*)dest; + + int swapOffset = beginOffset; + for (unsigned int i = 0; i < numBytes; ++i) + { + *writePtr = readPtr[3 - swapOffset]; + ++writePtr; + ++swapOffset; + if (swapOffset > 3) + { + swapOffset = 0; + readPtr += 4; + } + } + +#endif +} + +inline void DWordInterleave( void *mem, unsigned int numDWords ) +{ +#ifdef WIN32_ASM + __asm { + mov esi, dword ptr [mem] + mov edi, dword ptr [mem] + add edi, 4 + mov ecx, dword ptr [numDWords] +DWordInterleaveLoop: + mov eax, dword ptr [esi] + mov ebx, dword ptr [edi] + mov dword ptr [esi], ebx + mov dword ptr [edi], eax + add esi, 8 + add edi, 8 + loop DWordInterleaveLoop + } +#else + int *m = (int*)mem; + for (unsigned int i = 0; i < numDWords; ++i) + { + int tmp = m[2 * i]; + m[2 * i] = m[2 * i + 1]; + m[2 * i + 1] = tmp; + } +#endif +} + +inline void QWordInterleave( void *mem, unsigned int numDWords ) +{ +#ifdef WIN32_ASM + __asm + { + // Interleave the line on the qword + mov esi, dword ptr [mem] + mov edi, dword ptr [mem] + add edi, 8 + mov ecx, dword ptr [numDWords] + shr ecx, 1 +QWordInterleaveLoop: + mov eax, dword ptr [esi] + mov ebx, dword ptr [edi] + mov dword ptr [esi], ebx + mov dword ptr [edi], eax + add esi, 4 + add edi, 4 + mov eax, dword ptr [esi] + mov ebx, dword ptr [edi] + mov dword ptr [esi], ebx + mov dword ptr [edi], eax + add esi, 12 + add edi, 12 + loop QWordInterleaveLoop + } +#else + long long *m = (long long*)mem; + for (unsigned int i = 0; i < numDWords / 2; ++i) + { + long long tmp = m[2 * i]; + m[2 * i] = m[2 * i + 1]; + m[2 * i + 1] = tmp; + } +#endif +} + +const unsigned char Five2Eight[32] = +{ + 0, // 00000 = 00000000 + 8, // 00001 = 00001000 + 16, // 00010 = 00010000 + 25, // 00011 = 00011001 + 33, // 00100 = 00100001 + 41, // 00101 = 00101001 + 49, // 00110 = 00110001 + 58, // 00111 = 00111010 + 66, // 01000 = 01000010 + 74, // 01001 = 01001010 + 82, // 01010 = 01010010 + 90, // 01011 = 01011010 + 99, // 01100 = 01100011 + 107, // 01101 = 01101011 + 115, // 01110 = 01110011 + 123, // 01111 = 01111011 + 132, // 10000 = 10000100 + 140, // 10001 = 10001100 + 148, // 10010 = 10010100 + 156, // 10011 = 10011100 + 165, // 10100 = 10100101 + 173, // 10101 = 10101101 + 181, // 10110 = 10110101 + 189, // 10111 = 10111101 + 197, // 11000 = 11000101 + 206, // 11001 = 11001110 + 214, // 11010 = 11010110 + 222, // 11011 = 11011110 + 230, // 11100 = 11100110 + 239, // 11101 = 11101111 + 247, // 11110 = 11110111 + 255 // 11111 = 11111111 +}; + +const unsigned char Four2Eight[16] = +{ + 0, // 0000 = 00000000 + 17, // 0001 = 00010001 + 34, // 0010 = 00100010 + 51, // 0011 = 00110011 + 68, // 0100 = 01000100 + 85, // 0101 = 01010101 + 102, // 0110 = 01100110 + 119, // 0111 = 01110111 + 136, // 1000 = 10001000 + 153, // 1001 = 10011001 + 170, // 1010 = 10101010 + 187, // 1011 = 10111011 + 204, // 1100 = 11001100 + 221, // 1101 = 11011101 + 238, // 1110 = 11101110 + 255 // 1111 = 11111111 +}; + +const unsigned char Three2Four[8] = +{ + 0, // 000 = 0000 + 2, // 001 = 0010 + 4, // 010 = 0100 + 6, // 011 = 0110 + 9, // 100 = 1001 + 11, // 101 = 1011 + 13, // 110 = 1101 + 15, // 111 = 1111 +}; + +const unsigned char Three2Eight[8] = +{ + 0, // 000 = 00000000 + 36, // 001 = 00100100 + 73, // 010 = 01001001 + 109, // 011 = 01101101 + 146, // 100 = 10010010 + 182, // 101 = 10110110 + 219, // 110 = 11011011 + 255, // 111 = 11111111 +}; +const unsigned char Two2Eight[4] = +{ + 0, // 00 = 00000000 + 85, // 01 = 01010101 + 170, // 10 = 10101010 + 255 // 11 = 11111111 +}; + +const unsigned char One2Four[2] = +{ + 0, // 0 = 0000 + 15, // 1 = 1111 +}; + +const unsigned char One2Eight[2] = +{ + 0, // 0 = 00000000 + 255, // 1 = 11111111 +}; + +inline unsigned short RGBA8888_RGBA4444( unsigned int color ) +{ + return ((color & 0xF0000000) >> 28) | ((color & 0x00F00000) >> 16) | + ((color & 0x0000F000) >> 4) | ((color & 0x000000F0) << 8); +} + +inline unsigned int RGBA5551_RGBA8888( unsigned short color ) +{ + int rgba; + char *p = (char*)&rgba; + color = (color >> 8) | (color << 8); + p[3] = One2Eight[color & 1]; + p[2] = Five2Eight[color >> 1 & 0x1f]; + p[1] = Five2Eight[color >> 6 & 0x1f]; + p[0] = Five2Eight[color >> 11 & 0x1f]; + return rgba; +} + +// Just swaps the word +inline unsigned short RGBA5551_RGBA5551( unsigned short color ) +{ + return (color >> 8) | (color << 8); +} + +inline unsigned int IA88_RGBA8888( unsigned short color ) +{ + return (color & 0xFF) | ((color & 0xFF) << 8) | (color << 16); +} + +inline unsigned short IA88_RGBA4444( unsigned short color ) +{ + unsigned char b = color & 0xf0; + return (color >> 12) | b | (b << 4) | (b << 8); +} + +inline unsigned short IA44_RGBA4444( unsigned char color ) +{ + unsigned char b = color >> 4; + return color | (b << 8) | (b << 12); +} + +inline unsigned int IA44_RGBA8888( unsigned char color ) +{ + unsigned char b1 = color >> 4; + unsigned char b2 = color & 0x0f; + return b1 | (b1 << 4) | (b1 << 8) | (b1 << 12) | (b1 << 16) | (b1 << 20) | (b2 << 24) | (b2 << 28); +} + +inline unsigned short IA31_RGBA4444( unsigned char color ) +{ + unsigned char t = Three2Four[color >> 1]; + return One2Four[color & 1] | (t << 4) | (t << 8) | (t << 12); +} + +inline unsigned int IA31_RGBA8888( unsigned char color ) +{ + unsigned char t = Three2Eight[color >> 1]; + return t | (t << 8) | (t << 16) | (One2Eight[color & 1] << 24); +} + +inline unsigned short I8_RGBA4444( unsigned char color ) +{ + color &= 0xf0; + return (color >> 4) | color | (color << 4) | (color << 8); +} + +inline unsigned int I8_RGBA8888( unsigned char color ) +{ + return color | (color << 8) | (color << 16) | (color << 24); +} + +inline unsigned short I4_RGBA4444( unsigned char color ) +{ + color &= 0x0f; + return color | (color << 4) | (color << 8) | (color << 12); +} + +inline unsigned int I4_RGBA8888( unsigned char color ) +{ + unsigned char b = Four2Eight[color]; + return b | (b << 8) | (b << 16) | (b << 24); +} + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp new file mode 100755 index 0000000..80e432e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp @@ -0,0 +1,411 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "AdvancedCombinerManager.h" +#include "CombinerStructs.h" +#include "ExtensionChecker.h" +#include "MultiTexturingExt.h" +#include "AdvancedTexEnvCombiner.h" +#include "SimpleTexEnvCombiner.h" +#include "DummyCombiner.h" +#include "CombinerStageMerger.h" +#include "CombinerStageCreator.h" +#include "RomDetector.h" +#include "m64p.h" +#include "OpenGL.h" + +static int saRGBExpanded[] = +{ + COMBINED, TEXEL0, TEXEL1, PRIMITIVE, + SHADE, ENVIRONMENT, ONE, NOISE, + ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO +}; + +static int sbRGBExpanded[] = +{ + COMBINED, TEXEL0, TEXEL1, PRIMITIVE, + SHADE, ENVIRONMENT, CENTER, K4, + ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO +}; + +static int mRGBExpanded[] = +{ + COMBINED, TEXEL0, TEXEL1, PRIMITIVE, + SHADE, ENVIRONMENT, SCALE, COMBINED_ALPHA, + TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA, + ENV_ALPHA, LOD_FRACTION, PRIM_LOD_FRAC, K5, + ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO, ZERO +}; + +static int aRGBExpanded[] = +{ + COMBINED, TEXEL0, TEXEL1, PRIMITIVE, + SHADE, ENVIRONMENT, ONE, ZERO +}; + +static int saAExpanded[] = +{ + COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, + SHADE_ALPHA, ENV_ALPHA, ONE, ZERO +}; + +static int sbAExpanded[] = +{ + COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, + SHADE_ALPHA, ENV_ALPHA, ONE, ZERO +}; + +static int mAExpanded[] = +{ + LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, + SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO, +}; + +static int aAExpanded[] = +{ + COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, + SHADE_ALPHA, ENV_ALPHA, ONE, ZERO +}; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +AdvancedCombinerManager::AdvancedCombinerManager() +{ + currentTexEnv = 0; + m_combiner = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +AdvancedCombinerManager::~AdvancedCombinerManager() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Selects sutible combiner and initializes it +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::initialize() +{ + currentTexEnv = 0; + + //Select Combiner + switch ( ROMDetector::getSingleton().getCombinerType() ) + { + case CT_DUMMY: + m_combiner = new DummyCombiner(); + break; + + case CT_SIMPLE: + m_combiner = new SimpleTexEnvCombiner(); + break; + + case CT_ADVANCED: + default: + m_combiner = new AdvancedTexEnvCombiner(); + break; + } + + //init combiner + m_combiner->initialize(); +} + +//----------------------------------------------------------------------------- +//! Dispose +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::dispose() +{ + if ( m_combiner ) { delete m_combiner; m_combiner = 0; } + m_combinerCache.dispose(); +} + +//----------------------------------------------------------------------------- +//! Select Combine +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::selectCombine(unsigned int cycleType) +{ + //Hack for the Banjo-Tooie shadow + if ( cycleType == G_CYC_1CYCLE && m_combineData.mux == 0x00ffe7ffffcf9fcfLL ) + { + m_combineData.mux = 71943244815007743LL; + m_combiner->setBlendColor(0,0,0,0); + m_combiner->setPrimColor(0,0,0,0); + m_combiner->setEnvColor(0,0,0,0); + m_combiner->setFillColor(0,0,0,0); + } + + CachedCombiner* old = m_combinerCache.findCachedCombiner(m_combineData.mux); + + if ( old == 0 ) + { + //Cound not find an old combiner + this->update(cycleType); //Create a new combiner + } + else + { + currentTexEnv = old->compiled; + } + + //Set Texture Enviroment + this->endTextureUpdate(); +} + +//----------------------------------------------------------------------------- +//! Update Combine Colors +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::updateCombineColors() +{ + m_combiner->setTextureEnviromentColors( currentTexEnv ); +} + +//----------------------------------------------------------------------------- +//! Update +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::update(unsigned int cycleType) +{ + int numCycles; + + Combiner colorCombiner; + Combiner alphaCombiner; + + //Set number of cycles + if ( cycleType == G_CYC_2CYCLE ) + { + numCycles = 2; + colorCombiner.numStages = 2; + alphaCombiner.numStages = 2; + } + else + { + numCycles = 1; + colorCombiner.numStages = 1; + alphaCombiner.numStages = 1; + } + + CombineCycle colorCycle[2]; + CombineCycle alphaCycle[2]; + + // Decode and expand the combine mode into a more general form + colorCycle[0].loadValue = saRGBExpanded[m_combineData.saRGB0]; + colorCycle[0].subValue = sbRGBExpanded[m_combineData.sbRGB0]; + colorCycle[0].multValue = mRGBExpanded[m_combineData.mRGB0]; + colorCycle[0].addValue = aRGBExpanded[m_combineData.aRGB0]; + colorCycle[1].loadValue = saRGBExpanded[m_combineData.saRGB1]; + colorCycle[1].subValue = sbRGBExpanded[m_combineData.sbRGB1]; + colorCycle[1].multValue = mRGBExpanded[m_combineData.mRGB1]; + colorCycle[1].addValue = aRGBExpanded[m_combineData.aRGB1]; + + alphaCycle[0].loadValue = saAExpanded[m_combineData.saA0]; + alphaCycle[0].subValue = sbAExpanded[m_combineData.sbA0]; + alphaCycle[0].multValue = mAExpanded[m_combineData.mA0]; + alphaCycle[0].addValue = aAExpanded[m_combineData.aA0]; + alphaCycle[1].loadValue = saAExpanded[m_combineData.saA1]; + alphaCycle[1].subValue = sbAExpanded[m_combineData.sbA1]; + alphaCycle[1].multValue = mAExpanded[m_combineData.mA1]; + alphaCycle[1].addValue = aAExpanded[m_combineData.aA1]; + + //For each cycle + for (int i=0; icreateNewTextureEnviroment(&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 (0.0 - 1.0) +//----------------------------------------------------------------------------- +float* AdvancedCombinerManager::getFillColor() +{ + return m_combiner->getFillColor(); +} + +//----------------------------------------------------------------------------- +//* Get Blend Color +//! @return Blend Color as (0.0 - 1.0) +//----------------------------------------------------------------------------- +float* AdvancedCombinerManager::getBlendColor() +{ + return m_combiner->getBlendColor(); +} + +//----------------------------------------------------------------------------- +//* Get Prim Color +//! @return Prim Color as (0.0 - 1.0) +//----------------------------------------------------------------------------- +float* AdvancedCombinerManager::getPrimColor() +{ + return m_combiner->getPrimColor(); +} + +//----------------------------------------------------------------------------- +//! Set Fill Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setFillColor (float r, float g, float b, float a) +{ + m_combiner->setFillColor(r,g,b,a); +} + +//----------------------------------------------------------------------------- +//! Set Blend Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setBlendColor(float r, float g, float b, float a) +{ + m_combiner->setBlendColor(r,g,b,a); +} + +//----------------------------------------------------------------------------- +//! Set Prim Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setPrimColor (float r, float g, float b, float a) +{ + m_combiner->setPrimColor(r,g,b,a); +} + +//----------------------------------------------------------------------------- +//! Set Environment Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setEnvColor (float r, float g, float b, float a) +{ + m_combiner->setEnvColor(r,g,b,a); +} + +//----------------------------------------------------------------------------- +//* Set Prim LOD Min +//! @param primLodMin +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin) +{ + m_combiner->setPrimLodMin(primLodMin); +}; + +//----------------------------------------------------------------------------- +//* Set Prim LOD Frac +//! @param primLodFrac +//----------------------------------------------------------------------------- +void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac) +{ + m_combiner->setPrimLodFrac(primLodFrac); +}; diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h new file mode 100755 index 0000000..49ed3c0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h @@ -0,0 +1,103 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef ADVANCED_COMBINER_MANAGER_H_ +#define ADVANCED_COMBINER_MANAGER_H_ + +#include "GBIDefs.h" +#include "CombinerStructs.h" +#include "CombinerCache.h" + +//Forward declarations +struct TexEnvCombiner; +struct CombineCycle; +struct CombinerStage; +struct Combiner; +class AdvancedTexEnvCombiner; +class CombinerCache; +class CombinerBase; + +//***************************************************************************** +//! Advanced Texture Environment Combiner +//! Class used to select sutible combiners and sending input to selected +//! Combiners. +//***************************************************************************** +class AdvancedCombinerManager +{ +public: + + //Constructor / Destructor + AdvancedCombinerManager(); + ~AdvancedCombinerManager(); + + //Initialize / Dispose + void initialize(); + void dispose(); + + //Set Mux + void setMux(unsigned long long muxs, unsigned int cycleType); + void setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType); + + //Select Combiner + void selectCombine(unsigned int cycleType); + + //Update + void update(unsigned int cycleType); + void updateCombineColors(); + + //Begin / End Texture update + void beginTextureUpdate(); + void endTextureUpdate(); + + //Get Combiner Colors which will be assigned to vertices + void getCombinerColor(float out[4]); + void getSecondaryCombinerColor(float out[4]); + + //Set / Get Colors + void setFillColor (float r, float g, float b, float a); + void setBlendColor(float r, float g, float b, float a); + void setPrimColor (float r, float g, float b, float a); + void setEnvColor (float r, float g, float b, float a); + float* getFillColor(); + float* getBlendColor(); + float* getPrimColor(); + + //Set Prim LOD + void setPrimLodMin(unsigned int primLodMin); + void setPrimLodFrac(float primLodFrac); + + //! @return True if combiner wish to use texture channel 0 + bool getUsesTexture0() { return currentTexEnv->usesT0; } + + //! @return True if combiner wish to use texture channel 1 + bool getUsesTexture1() { return currentTexEnv->usesT1; } + +private: + + //Private Members + CombineData m_combineData; //!< Combiner Input (How to combine colors andset up enviroment) + TexEnvCombiner* currentTexEnv; //!< Texture Enviroment + CombinerBase* m_combiner; //!< Combiner + CombinerCache m_combinerCache; //!< Cache used to store old combiners for reuse + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp new file mode 100755 index 0000000..5d32a5d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp @@ -0,0 +1,590 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include +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 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; iusedUnits ) || (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; inumStages; i++) + { + for (int j = 0; j < alphaCombiner->stage[i].numOps; j++) + { + float sb = 0.0f; + + if (alphaCombiner->stage[i].op[j].param1 == PRIMITIVE_ALPHA) + sb = m_primColor[3]; + else if (alphaCombiner->stage[i].op[j].param1 == ENV_ALPHA) + sb = m_envColor[3]; + else if (alphaCombiner->stage[i].op[j].param1 == ONE) + sb = 1.0f; + + if (((alphaCombiner->stage[i].numOps - j) >= 3) && + (alphaCombiner->stage[i].op[j].op == SUB) && + (alphaCombiner->stage[i].op[j+1].op == MUL) && + (alphaCombiner->stage[i].op[j+2].op == ADD) && + (sb > 0.5f) && + (ARB_texture_env_combine)) + { + envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA; + envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA; + + if (alphaCombiner->stage[i].op[j].param1 == ONE) + { + SetAlphaCombinerValues( curUnit, arg0, envCombiner->alpha[curUnit].arg0.source, GL_ONE_MINUS_SRC_ALPHA ); + } + else + { + envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB; + SetAlphaCombinerValues( curUnit, arg1, envCombiner->alpha[curUnit].arg0.source, GL_SRC_ALPHA ); + SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 ); + + curUnit++; + } + + j++; + + envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA; + envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA; + + envCombiner->alpha[curUnit].combine = GL_MODULATE; + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + + curUnit++; + j++; + + envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA; + envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA; + + envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB; + SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 ); + + curUnit++; + } + else + { + envCombiner->usesT0 |= alphaCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA; + envCombiner->usesT1 |= alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA; + + switch (alphaCombiner->stage[i].op[j].op) + { + case LOAD: + if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) && + (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0)) + curUnit++; + + envCombiner->alpha[curUnit].combine = GL_REPLACE; + + SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 ); + break; + case SUB: + if (!ARB_texture_env_combine) + break; + + if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) && + (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0)) + curUnit++; + + if ((j > 0) && (alphaCombiner->stage[i].op[j-1].op == LOAD) && (alphaCombiner->stage[i].op[j-1].param1 == ONE)) + { + SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 ); + envCombiner->alpha[curUnit].arg0.operand = GL_ONE_MINUS_SRC_ALPHA; + } + else if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE)) + { + curUnit--; + SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand ); + envCombiner->alpha[curUnit].combine = GL_MODULATE_SUBTRACT_ATI; + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + curUnit++; + } + else + { + envCombiner->alpha[curUnit].combine = GL_SUBTRACT_ARB; + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + curUnit++; + } + break; + case MUL: + if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) && + (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0)) + curUnit++; + + envCombiner->alpha[curUnit].combine = GL_MODULATE; + + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + curUnit++; + break; + case ADD: + if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) && + (alphaCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA) && (curUnit == 0)) + curUnit++; + + if ((ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->alpha[curUnit - 1].combine == GL_MODULATE)) + { + curUnit--; + SetAlphaCombinerValues( curUnit, arg2, envCombiner->alpha[curUnit].arg1.source, envCombiner->alpha[curUnit].arg1.operand ); + envCombiner->alpha[curUnit].combine = GL_MODULATE_ADD_ATI; + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + } + else + { + envCombiner->alpha[curUnit].combine = GL_ADD; + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param1 ); + } + curUnit++; + break; + case INTERPOLATE: + envCombiner->usesT0 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL0_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA); + envCombiner->usesT1 |= (alphaCombiner->stage[i].op[j].param2 == TEXEL1_ALPHA) || (alphaCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA); + + envCombiner->alpha[curUnit].combine = GL_INTERPOLATE_ARB; + + SetAlphaCombinerArg( curUnit, arg0, alphaCombiner->stage[i].op[j].param1 ); + SetAlphaCombinerArg( curUnit, arg1, alphaCombiner->stage[i].op[j].param2 ); + SetAlphaCombinerArg( curUnit, arg2, alphaCombiner->stage[i].op[j].param3 ); + + curUnit++; + break; + } + } + } + } + + envCombiner->usedUnits = max( curUnit, 1 ); + + curUnit = 0; + for (int i = 0; i < colorCombiner->numStages; i++) + { + for (int j = 0; j < colorCombiner->stage[i].numOps; j++) + { + float sb = 0.0f; + + if (colorCombiner->stage[i].op[j].param1 == PRIMITIVE) + sb = (m_primColor[0] + m_primColor[2] + m_primColor[1]) / 3.0f; + else if (colorCombiner->stage[i].op[j].param1 == ENVIRONMENT) + sb = (m_envColor[0] + m_envColor[2] + m_envColor[1]) / 3.0f; + + // This helps with problems caused by not using signed values between texture units + if (((colorCombiner->stage[i].numOps - j) >= 3) && + (colorCombiner->stage[i].op[j].op == SUB) && + (colorCombiner->stage[i].op[j+1].op == MUL) && + (colorCombiner->stage[i].op[j+2].op == ADD) && + (sb > 0.5f) && + (ARB_texture_env_combine)) + { + envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA)); + envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)); + + envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB; + SetColorCombinerValues( curUnit, arg1, envCombiner->color[curUnit].arg0.source, envCombiner->color[curUnit].arg0.operand ); + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + + curUnit++; + j++; + + envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA)); + envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)); + + envCombiner->color[curUnit].combine = GL_MODULATE; + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + + curUnit++; + j++; + + envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA)); + envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)); + + envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB; + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + + curUnit++; + } + else + { + envCombiner->usesT0 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL0) || (colorCombiner->stage[i].op[j].param1 == TEXEL0_ALPHA)); + envCombiner->usesT1 |= ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)); + + switch (colorCombiner->stage[i].op[j].op) + { + case LOAD: + if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) && + ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0)) + curUnit++; + + envCombiner->color[curUnit].combine = GL_REPLACE; + + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + break; + case SUB: + if (!ARB_texture_env_combine) + break; + + if (!(ARB_texture_env_crossbar || NV_texture_env_combine4) && + ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0)) + curUnit++; + + if ((j > 0) && (colorCombiner->stage[i].op[j-1].op == LOAD) && (colorCombiner->stage[i].op[j-1].param1 == ONE)) + { + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + envCombiner->color[curUnit].arg0.operand = GL_ONE_MINUS_SRC_COLOR; + } + else if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE)) + { + curUnit--; + SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand ); + envCombiner->color[curUnit].combine = GL_MODULATE_SUBTRACT_ATI; + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + curUnit++; + } + else + { + envCombiner->color[curUnit].combine = GL_SUBTRACT_ARB; + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + curUnit++; + } + break; + case MUL: + if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) && + ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0)) + curUnit++; + + envCombiner->color[curUnit].combine = GL_MODULATE; + + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + curUnit++; + break; + case ADD: + if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) && + ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param1 == TEXEL1_ALPHA)) && (curUnit == 0)) + curUnit++; + + // ATI_texture_env_combine3 adds GL_MODULATE_ADD_ATI; saves texture units + if (( ATI_texture_env_combine3) && (curUnit > 0) && (envCombiner->color[curUnit - 1].combine == GL_MODULATE)) + { + curUnit--; + SetColorCombinerValues( curUnit, arg2, envCombiner->color[curUnit].arg1.source, envCombiner->color[curUnit].arg1.operand ); + envCombiner->color[curUnit].combine = GL_MODULATE_ADD_ATI; + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + } + else + { + envCombiner->color[curUnit].combine = GL_ADD; + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param1 ); + } + curUnit++; + break; + case INTERPOLATE: + envCombiner->usesT0 |= (colorCombiner->stage[i].op[j].param2 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0) || (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA); + envCombiner->usesT1 |= (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA); + + if (!( ARB_texture_env_crossbar || NV_texture_env_combine4) && + ((colorCombiner->stage[i].op[j].param1 == TEXEL1) || (colorCombiner->stage[i].op[j].param2 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1) || (colorCombiner->stage[i].op[j].param3 == TEXEL1_ALPHA)) && (curUnit == 0)) + { + if (colorCombiner->stage[i].op[j].param1 == TEXEL0) + { + envCombiner->color[curUnit].combine = GL_REPLACE; + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + colorCombiner->stage[i].op[j].param1 = COMBINED; + } + if (colorCombiner->stage[i].op[j].param2 == TEXEL0) + { + envCombiner->color[curUnit].combine = GL_REPLACE; + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param2 ) + + colorCombiner->stage[i].op[j].param2 = COMBINED; + } + if (colorCombiner->stage[i].op[j].param3 == TEXEL0) + { + envCombiner->color[curUnit].combine = GL_REPLACE; + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 ); + colorCombiner->stage[i].op[j].param3 = COMBINED; + } + if (colorCombiner->stage[i].op[j].param3 == TEXEL0_ALPHA) + { + envCombiner->color[curUnit].combine = GL_REPLACE; + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param3 ); + colorCombiner->stage[i].op[j].param3 = COMBINED_ALPHA; + } + + curUnit++; + } + + envCombiner->color[curUnit].combine = GL_INTERPOLATE_ARB; + + SetColorCombinerArg( curUnit, arg0, colorCombiner->stage[i].op[j].param1 ); + SetColorCombinerArg( curUnit, arg1, colorCombiner->stage[i].op[j].param2 ); + SetColorCombinerArg( curUnit, arg2, colorCombiner->stage[i].op[j].param3 ); + + curUnit++; + break; + } + } + } + } + + envCombiner->usedUnits = max( (unsigned short)curUnit, envCombiner->usedUnits ); + return envCombiner; +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h new file mode 100755 index 0000000..eac08d5 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h @@ -0,0 +1,166 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef ADVANCED_TEX_ENV_COMBINER_H_ +#define ADVANCED_TEX_ENV_COMBINER_H_ + +#include "CombinerBase.h" +#include "CombinerStructs.h" + +struct TexEnvCombiner; + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#ifndef HAVE_GLES + #define GL_COMBINE_ARB 0x8570 + #define GL_COMBINE_RGB_ARB 0x8571 + #define GL_COMBINE_ALPHA_ARB 0x8572 + #define GL_SOURCE0_RGB_ARB 0x8580 + #define GL_SOURCE1_RGB_ARB 0x8581 + #define GL_SOURCE2_RGB_ARB 0x8582 + #define GL_SOURCE0_ALPHA_ARB 0x8588 + #define GL_SOURCE1_ALPHA_ARB 0x8589 + #define GL_SOURCE2_ALPHA_ARB 0x858A + #define GL_OPERAND0_RGB_ARB 0x8590 + #define GL_OPERAND1_RGB_ARB 0x8591 + #define GL_OPERAND2_RGB_ARB 0x8592 + #define GL_OPERAND0_ALPHA_ARB 0x8598 + #define GL_OPERAND1_ALPHA_ARB 0x8599 + #define GL_OPERAND2_ALPHA_ARB 0x859A + #define GL_RGB_SCALE_ARB 0x8573 + #define GL_ADD_SIGNED_ARB 0x8574 + #define GL_INTERPOLATE_ARB 0x8575 + #define GL_CONSTANT_ARB 0x8576 + #define GL_PRIMARY_COLOR_ARB 0x8577 + #define GL_PREVIOUS_ARB 0x8578 + #define GL_SUBTRACT_ARB 0x84E7 +#endif +#endif +#define SetColorCombinerValues( n, a, s, o ) \ + envCombiner->color[n].a.source = s; \ + envCombiner->color[n].a.operand = o + +#define SetAlphaCombinerValues( n, a, s, o ) \ + envCombiner->alpha[n].a.source = s; \ + envCombiner->alpha[n].a.operand = o + +#define SetAlphaCombinerArg( n, a, i ) \ + if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \ + { \ + if ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i)) \ + { \ + envCombiner->alpha[n].constant = i; \ + envCombiner->alpha[n].a.source = GL_CONSTANT_ARB; \ + envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \ + } \ + else if ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i)) \ + { \ + envCombiner->vertex.alpha = i; \ + envCombiner->alpha[n].a.source = GL_PRIMARY_COLOR_ARB; \ + envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \ + } \ + } \ + else \ + { \ + envCombiner->alpha[n].a.source = TexEnvArgs[i].source; \ + envCombiner->alpha[n].a.operand = GL_SRC_ALPHA; \ + } + +#define SetColorCombinerArg( n, a, i ) \ + if (TexEnvArgs[i].source == GL_CONSTANT_ARB) \ + { \ + if ((i > 5) && ((envCombiner->alpha[n].constant == COMBINED) || (envCombiner->alpha[n].constant == i))) \ + { \ + envCombiner->alpha[n].constant = i; \ + envCombiner->color[n].a.source = GL_CONSTANT_ARB; \ + envCombiner->color[n].a.operand = GL_SRC_ALPHA; \ + } \ + else if ((i > 5) && ((envCombiner->vertex.alpha == COMBINED) || (envCombiner->vertex.alpha == i))) \ + { \ + envCombiner->vertex.alpha = i; \ + envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \ + envCombiner->color[n].a.operand = GL_SRC_ALPHA; \ + } \ + else if ((envCombiner->color[n].constant == COMBINED) || (envCombiner->color[n].constant == i)) \ + { \ + envCombiner->color[n].constant = i; \ + envCombiner->color[n].a.source = GL_CONSTANT_ARB; \ + envCombiner->color[n].a.operand = GL_SRC_COLOR; \ + } \ + else if ( ATIX_texture_env_route && ((envCombiner->vertex.secondaryColor == COMBINED) || (envCombiner->vertex.secondaryColor == i))) \ + { \ + envCombiner->vertex.secondaryColor = i; \ + envCombiner->color[n].a.source = GL_SECONDARY_COLOR_ATIX; \ + envCombiner->color[n].a.operand = GL_SRC_COLOR; \ + } \ + else if ((envCombiner->vertex.color == COMBINED) || (envCombiner->vertex.color == i))\ + { \ + envCombiner->vertex.color = i; \ + envCombiner->color[n].a.source = GL_PRIMARY_COLOR_ARB; \ + envCombiner->color[n].a.operand = GL_SRC_COLOR; \ + } \ + } \ + else \ + { \ + envCombiner->color[n].a.source = TexEnvArgs[i].source; \ + envCombiner->color[n].a.operand = TexEnvArgs[i].operand; \ + } + +//***************************************************************************** +//! Advanced Texture Environment Combiner +//! Class used to combine colors by setting texture enviroment using OpenGL +//***************************************************************************** +class AdvancedTexEnvCombiner : public CombinerBase +{ +public: + + //Constructor / Destructor + AdvancedTexEnvCombiner(); + ~AdvancedTexEnvCombiner(); + + //Initialize + void initialize(); + + //Begin / End Texture Update + void beginTextureUpdate(); + void endTextureUpdate(TexEnvCombiner* texEnv); + + //Sets texture enviorment colors + void setTextureEnviromentColors(TexEnvCombiner* texEnv); + + //Create New Texture Environment + TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner); + + //Sets texture enviorment + void setTextureEnviroment(TexEnvCombiner* texEnv); + +private: + + //Extensions + bool ARB_texture_env_combine; + bool ARB_texture_env_crossbar; + bool ATI_texture_env_combine3; + bool ATIX_texture_env_route; + bool NV_texture_env_combine4; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp new file mode 100755 index 0000000..c968949 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp @@ -0,0 +1,183 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "CombinerBase.h" +#include "CombinerStructs.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +CombinerBase::CombinerBase() +{ + m_fillColor[0] = m_blendColor[0] = m_primColor[0] = m_envColor[0] = 0; + m_fillColor[1] = m_blendColor[1] = m_primColor[1] = m_envColor[1] = 0; + m_fillColor[2] = m_blendColor[2] = m_primColor[2] = m_envColor[2] = 0; + m_fillColor[3] = m_blendColor[3] = m_primColor[3] = m_envColor[3] = 1; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +CombinerBase::~CombinerBase() +{ + +} + +//----------------------------------------------------------------------------- +//! Set Fill Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void CombinerBase::setFillColor (float r, float g, float b, float a) +{ + m_fillColor[0] = r; + m_fillColor[1] = g; + m_fillColor[2] = b; + m_fillColor[3] = a; +} + +//----------------------------------------------------------------------------- +//! Set Blend Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void CombinerBase::setBlendColor(float r, float g, float b, float a) +{ + m_blendColor[0] = r; + m_blendColor[1] = g; + m_blendColor[2] = b; + m_blendColor[3] = a; +} + +//----------------------------------------------------------------------------- +//! Set Prim Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void CombinerBase::setPrimColor (float r, float g, float b, float a) +{ + m_primColor[0] = r; + m_primColor[1] = g; + m_primColor[2] = b; + m_primColor[3] = a; +} + +//----------------------------------------------------------------------------- +//! Set Enviroment Color +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void CombinerBase::setEnvColor(float r, float g, float b, float a) +{ + m_envColor[0] = r; + m_envColor[1] = g; + m_envColor[2] = b; + m_envColor[3] = a; +} + +//----------------------------------------------------------------------------- +//! Get Combiner Color +//! @param[in] colorSource From which colorsource to retrive color values +//! \arg \c PRIMITIVE Get color from primative color +//! \arg \c ENVIRONMENT Get color from environment color +//! \arg \c PRIMITIVE_ALPHA Get color from primatives alpha value +//! \arg \c ENV_ALPHA Get color from environment colors alpha value +//! \arg \c PRIM_LOD_FRAC Get color from primative-LOD-frac value +//! \arg \c ONE Get white color +//! \arg \c ZERO Get black color +//! @param[in] alphaSource From which alphasource to retrive alpha value +//! \arg \c PRIMITIVE_ALPHA Get alpha value from primitive colors alpha value +//! \arg \c ENV_ALPHA Get alpha value from environment colors alpha value +//! \arg \c PRIM_LOD_FRAC Get alpha value from primative-LOD-frac value +//! \arg \c ONE Set alpha value to 1.0 +//! \arg \c ZERO Set alpha value to 0.0 +//! @param[out] out The combiner color with color and alpha value +//----------------------------------------------------------------------------- +void CombinerBase::getCombinerColor(float out[4], short colorSrc, short alphaSrc) +{ + //Set color values + switch ( colorSrc ) + { + case PRIMITIVE: + out[0] = m_primColor[0]; + out[1] = m_primColor[1]; + out[2] = m_primColor[2]; + break; + case ENVIRONMENT: + out[0] = m_envColor[0]; + out[1] = m_envColor[1]; + out[2] = m_envColor[2]; + break; + case PRIMITIVE_ALPHA: + out[0] = m_primColor[3]; + out[1] = m_primColor[3]; + out[2] = m_primColor[3]; + break; + case ENV_ALPHA: + out[0] = m_envColor[3]; + out[1] = m_envColor[3]; + out[2] = m_envColor[3]; + break; + case PRIM_LOD_FRAC: + out[0] = m_primLodFrac; + out[1] = m_primLodFrac; + out[2] = m_primLodFrac; + break; + case ONE: + out[0] = 1.0f; + out[1] = 1.0f; + out[2] = 1.0f; + break; + case ZERO: + out[0] = 0.0f; + out[1] = 0.0f; + out[2] = 0.0f; + break; + } + + //Set alpha value + switch ( alphaSrc ) + { + case PRIMITIVE_ALPHA: + out[3] = m_primColor[3]; + break; + case ENV_ALPHA: + out[3] = m_envColor[3]; + break; + case PRIM_LOD_FRAC: + out[3] = m_primLodFrac; + break; + case ONE: + out[3] = 1.0f; + break; + case ZERO: + out[3] = 0.0f; + break; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h new file mode 100755 index 0000000..a6b4451 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef COMBINER_BASE_H_ +#define COMBINER_BASE_H_ + +#include "CombinerStructs.h" + +//Forward declarations +struct TexEnvCombiner; + +//***************************************************************************** +//* CombinerBase +//! Base class and interface for combiners +//! @see AdvancedTexEnvCombiner +//! @see SimpleTexEnvCombiner +//! @see DummyCombiner +//***************************************************************************** +class CombinerBase +{ +public: + + //Constructor / Destructor + CombinerBase(); + ~CombinerBase(); + + //Set colors + void setFillColor(float r, float g, float b, float a); + void setBlendColor(float r, float g, float b, float a); + void setPrimColor(float r, float g, float b, float a); + void setEnvColor(float r, float g, float b, float a); + + //Set prim LOD + void setPrimLodMin(unsigned int primLodMin) { m_primLodMin = primLodMin; }; + void setPrimLodFrac(float primLodFrac) { m_primLodFrac = primLodFrac; }; + +public: + + //Get Colors + //---------- + + //! Get Blend Color + //! @retval float* Returns blend color as channels (0.0-1.0) + float* getBlendColor() { return m_blendColor; }; + + //! Get Fill Color + //! @retval float* Returns fill color as channels (0.0-1.0) + float* getFillColor() { return m_fillColor; }; + + //! Get Prim Color + //! @retval float* Returns prim color as channels (0.0-1.0) + float* getPrimColor() { return m_primColor; }; + + //! Get Environment Color + //! @retval float* Returns environment color as 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] ; //!< + float m_blendColor[4]; //!< + float m_primColor[4]; //!< + float m_envColor[4]; //!< + + //Prim + unsigned int m_primLodMin; + float m_primLodFrac; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp new file mode 100755 index 0000000..3456182 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "CombinerCache.h" + +//----------------------------------------------------------------------------- +//* New Compiled Combiner +//! Function used to add decoded mux values and the result of them to the list. +//----------------------------------------------------------------------------- +void CombinerCache::newCompiledCombiner(unsigned long long mux, TexEnvCombiner* compiled) +{ + //Create new Combiner + CachedCombiner* newCombiner = new CachedCombiner(); + newCombiner->mux = mux; + newCombiner->compiled = compiled; + + //Add Combiner to list + m_cachedCombiners.push_back(newCombiner); +} + +//----------------------------------------------------------------------------- +//* New Compiled Combiner +//! Function used to retrive decoded mux values and the result of them to the list. +//----------------------------------------------------------------------------- +CachedCombiner* CombinerCache::findCachedCombiner(unsigned long long mux) +{ + for (CombinerList::iterator it = m_cachedCombiners.begin(); it!=m_cachedCombiners.end(); ++it) + { + if ( (*it)->mux == mux ) + { + return (*it); //Found old combiner!! + } + } + + return 0; //Could not find it +} + +//----------------------------------------------------------------------------- +//* Dispose +//! Destroys all values in list. +//----------------------------------------------------------------------------- +void CombinerCache::dispose() +{ + for (CombinerList::iterator it = m_cachedCombiners.begin(); it!=m_cachedCombiners.end(); ++it) + { + delete (*it)->compiled; + delete (*it); + } + + m_cachedCombiners.clear(); +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h new file mode 100755 index 0000000..f63157e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef COMBINER_CACHE_H_ +#define COMBINER_CACHE_H_ + +#include "CombinerStructs.h" +#include + +//***************************************************************************** +//* 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 CombinerList; //!< Type used to store combiled texture combiners + CombinerList m_cachedCombiners; //!< List of cached combiners + +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp new file mode 100755 index 0000000..acb458f --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp @@ -0,0 +1,110 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +//***************************************************************************** +// +// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64. +// http://gln64.emulation64.com/ +// +//***************************************************************************** + +#include "CombinerStageCreator.h" + +//----------------------------------------------------------------------------- +//* Set Stage +//! Function used to set combiner stage, tries to simplify and optimize as +//! much as possible. +//! From glN64 +//! @param[in] combineCycle Values to be added/subracted/multiplied and interpolated. +//! @param[out] stageOut Simplified combine cycle with combiner formula. +//----------------------------------------------------------------------------- +void setStage(CombineCycle* combineCycle, CombinerStage* stageOut) +{ + // Load the first operand + stageOut->op[0].op = LOAD; + stageOut->op[0].param1 = combineCycle->loadValue; + stageOut->numOps = 1; + + // If we're just subtracting zero, skip it + if (combineCycle->subValue != ZERO) + { + if (combineCycle->subValue == stageOut->op[0].param1) + stageOut->op[0].param1 = ZERO; + else + { + //Subract operation + stageOut->op[1].op = SUB; + stageOut->op[1].param1 = combineCycle->subValue; + stageOut->numOps++; + } + } + + //Multiply operation + if ((stageOut->numOps > 1) || (stageOut->op[0].param1 != ZERO)) + { + if (combineCycle->multValue == ZERO) + { + stageOut->numOps = 1; + stageOut->op[0].op = LOAD; + stageOut->op[0].param1 = ZERO; + } + else + { + if ( stageOut->numOps == 1 && stageOut->op[0].param1 == ONE ) + { + //LOAD + stageOut->op[0].param1 = combineCycle->multValue; + } + else + { + //MULT + stageOut->op[stageOut->numOps].op = MUL; + stageOut->op[stageOut->numOps].param1 = combineCycle->multValue; + stageOut->numOps++; + } + } + } + + //Don't bother adding zero + if (combineCycle->addValue != ZERO) + { + // If all we have so far is zero, then load this instead + if ((stageOut->numOps == 1) && (stageOut->op[0].param1 == ZERO)) + { + stageOut->op[0].param1 = combineCycle->addValue; + } + else + { + stageOut->op[stageOut->numOps].op = ADD; + stageOut->op[stageOut->numOps].param1 = combineCycle->addValue; + stageOut->numOps++; + } + } + + // Handle interpolation + if ((stageOut->numOps == 4) && (stageOut->op[1].param1 == stageOut->op[3].param1)) + { + stageOut->numOps = 1; + stageOut->op[0].op = INTERPOLATE; + stageOut->op[0].param2 = stageOut->op[1].param1; + stageOut->op[0].param3 = stageOut->op[2].param1; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h new file mode 100755 index 0000000..c2e44aa --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef COMBINER_STAGE_CREATOR_H_ +#define COMBINER_STAGE_CREATOR_H_ + +#include "CombinerStructs.h" + +//Function used to set combiner stage +void setStage(CombineCycle* combineCycle, CombinerStage* stageOut); + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp new file mode 100755 index 0000000..74156e4 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp @@ -0,0 +1,115 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +//***************************************************************************** +// +// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64. +// http://gln64.emulation64.com/ +// +//***************************************************************************** + +#include "CombinerStructs.h" + +//----------------------------------------------------------------------------- +//* Merge Stages +//! Try two merge to stages into one +//! From glN64 +//----------------------------------------------------------------------------- +void mergeStages(Combiner* c) +{ + + // If all we have is a load in the first stage we can just replace + // each occurance of COMBINED in the second stage with it + if ((c->stage[0].numOps == 1) && (c->stage[0].op[0].op == LOAD)) + { + int combined = c->stage[0].op[0].param1; + + for (int i = 0; i < c->stage[1].numOps; i++) + { + c->stage[0].op[i].op = c->stage[1].op[i].op; + c->stage[0].op[i].param1 = (c->stage[1].op[i].param1 == COMBINED) ? combined : c->stage[1].op[i].param1; + c->stage[0].op[i].param2 = (c->stage[1].op[i].param2 == COMBINED) ? combined : c->stage[1].op[i].param2; + c->stage[0].op[i].param3 = (c->stage[1].op[i].param3 == COMBINED) ? combined : c->stage[1].op[i].param3; + } + + c->stage[0].numOps = c->stage[1].numOps; + c->numStages = 1; + } + // We can't do any merging on an interpolation + else if (c->stage[1].op[0].op != INTERPOLATE) + { + int numCombined = 0; + + // See how many times the first stage is used in the second one + for (int i = 0; i < c->stage[1].numOps; i++) + if (c->stage[1].op[i].param1 == COMBINED) + numCombined++; + + // If it's not used, just replace the first stage with the second + if (numCombined == 0) + { + for (int i = 0; i < c->stage[1].numOps; i++) + { + c->stage[0].op[i].op = c->stage[1].op[i].op; + c->stage[0].op[i].param1 = c->stage[1].op[i].param1; + c->stage[0].op[i].param2 = c->stage[1].op[i].param2; + c->stage[0].op[i].param3 = c->stage[1].op[i].param3; + } + c->stage[0].numOps = c->stage[1].numOps; + + c->numStages = 1; + } + // If it's only used once + else if (numCombined == 1) + { + // It's only used in the load, so stack on the ops from stage 2 on stage 1 + if (c->stage[1].op[0].param1 == COMBINED) + { + for (int i = 1; i < c->stage[1].numOps; i++) + { + c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[i].op; + c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[i].param1; + c->stage[0].numOps++; + } + + c->numStages = 1; + } + // Otherwise, if it's used in the second op, and that op isn't SUB + // we can switch the parameters so it works out to tack the ops onto stage 1 + else if ((c->stage[1].op[1].param1 == COMBINED) && (c->stage[1].op[1].op != SUB)) + { + c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[1].op; + c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[0].param1; + c->stage[0].numOps++; + + // If there's another op, tack it onto stage 1 too + if (c->stage[1].numOps > 2) + { + c->stage[0].op[c->stage[0].numOps].op = c->stage[1].op[2].op; + c->stage[0].op[c->stage[0].numOps].param1 = c->stage[1].op[2].param1; + c->stage[0].numOps++; + } + + c->numStages = 1; + } + } + } +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h new file mode 100755 index 0000000..829412e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef COMBINER_STAGE_MERGER_H_ +#define COMBINER_STAGE_MERGER_H_ + +struct Combiner; + +//Tries to merge the two stages in combiner +void mergeStages(Combiner* c); + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h new file mode 100755 index 0000000..ae0f68c --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef COMBINER_STRUCTS_H_ +#define COMBINER_STRUCTS_H_ + +#include "m64p.h" +#include "OpenGL.h" + +// Internal combiner commands +#define LOAD 0 +#define SUB 1 +#define MUL 2 +#define ADD 3 +#define INTERPOLATE 4 + +// Internal generalized combiner inputs + +#define COMBINED 0 +#define TEXEL0 1 +#define TEXEL1 2 +#define PRIMITIVE 3 +#define SHADE 4 +#define ENVIRONMENT 5 +#define CENTER 6 +#define SCALE 7 +#define COMBINED_ALPHA 8 +#define TEXEL0_ALPHA 9 +#define TEXEL1_ALPHA 10 +#define PRIMITIVE_ALPHA 11 +#define SHADE_ALPHA 12 +#define ENV_ALPHA 13 +#define LOD_FRACTION 14 +#define PRIM_LOD_FRAC 15 +#define NOISE 16 +#define K4 17 +#define K5 18 +#define ONE 19 +#define ZERO 20 + +//* Combiner data +//! Defines how mux-values are coded. +//TODO: check this size against GCC when i'm awake +struct CombineData +{ + union + { + struct + { + // muxs1 + unsigned aA1 : 3; + unsigned sbA1 : 3; + unsigned aRGB1 : 3; + unsigned aA0 : 3; + unsigned sbA0 : 3; + unsigned aRGB0 : 3; + unsigned mA1 : 3; + unsigned saA1 : 3; + unsigned sbRGB1 : 4; + unsigned sbRGB0 : 4; + + // muxs0 + unsigned mRGB1 : 5; + unsigned saRGB1 : 4; + unsigned mA0 : 3; + unsigned saA0 : 3; + unsigned mRGB0 : 5; + unsigned saRGB0 : 4; + }; + + struct + { + unsigned int muxs1, muxs0; + }; + + unsigned long long mux; + }; +}; + +//! Combiner operation +struct CombinerOp +{ + int op; + int param1; + int param2; + int param3; +}; + +//! Combiner Stage with combiner operations +struct CombinerStage +{ + int numOps; + CombinerOp op[6]; +}; + +//! Combiner with combiner stages +struct Combiner +{ + int numStages; + CombinerStage stage[2]; +}; + +//! Combiner cycle +struct CombineCycle +{ + int loadValue; //!< Load + int addValue; //!< Addition + int subValue; //!< Subract + int multValue; //!< Multiplication +}; + + +//***************************************************************************** +//! Texture Environment Combiner Argument +//! Difines a color source and mathimatical operation to be performed +//***************************************************************************** +struct TexEnvCombinerArg +{ + GLenum source; + GLenum operand; +}; + +//***************************************************************************** +//! Texture Environment Combiner Stage +//***************************************************************************** +struct TexEnvCombinerStage +{ + unsigned short constant; + bool used; + GLenum combine; + TexEnvCombinerArg arg0, arg1, arg2; + unsigned short outputTexture; +}; + +//***************************************************************************** +//* Texture Environment Combiner +//! Stores information how graphics API should combine colors and set +//! Texture environment. +//***************************************************************************** +struct TexEnvCombiner +{ + bool usesT0, usesT1, usesNoise; + + GLint mode; + + unsigned short usedUnits; + + struct + { + unsigned short color, secondaryColor, alpha; + } vertex; + + TexEnvCombinerStage color[8]; + TexEnvCombinerStage alpha[8]; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp new file mode 100755 index 0000000..29ff59d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp @@ -0,0 +1,83 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "DummyCombiner.h" +#include "CombinerStructs.h" +#include "ExtensionChecker.h" +#include "MultiTexturingExt.h" + +//----------------------------------------------------------------------------- +//* Initialize +//! Checks if multitexturing is supported +//----------------------------------------------------------------------------- +void DummyCombiner::initialize() +{ + ARB_multitexture = isExtensionSupported("GL_ARB_multitexture"); +} + +//----------------------------------------------------------------------------- +//* Create New Texture Enviroment +//! Allocates a new texture enviroment +//! @param[in] colorCombiner How to combine and get a color +//! @param[in] alphaCombiner How to combine and get an alpha value +//! @return The texture enviroment that was created +//----------------------------------------------------------------------------- +TexEnvCombiner* DummyCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner) +{ + TexEnvCombiner* texEnv = new TexEnvCombiner(); + texEnv->usesT0 = false; + texEnv->usesT1 = false; + texEnv->mode = GL_REPLACE; + texEnv->vertex.color = COMBINED; + texEnv->vertex.alpha = COMBINED; + + //For each stage in alpha combiner + for (int i = 0; i < alphaCombiner->numStages; i++) + { + //For each operation in stage + for (int j = 0; j < alphaCombiner->stage[i].numOps; j++) + { + CombinerOp* op = &colorCombiner->stage[i].op[j]; + + if ( op->param1 == TEXEL0 ) + { + texEnv->usesT0 = true; + } + } + } + return texEnv; +} + +//----------------------------------------------------------------------------- +//* Set Texture Enviroment +//! Sets OpenGL (enables texturing) +//----------------------------------------------------------------------------- +void DummyCombiner::setTextureEnviroment(TexEnvCombiner* texEnv) +{ + //Enable Texturing + if ( ARB_multitexture ) + glActiveTextureARB( GL_TEXTURE0_ARB ); + + if ( texEnv->usesT0 ) + glEnable( GL_TEXTURE_2D ); + else + glDisable( GL_TEXTURE_2D ); +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h new file mode 100755 index 0000000..3bf5ee0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef DUMMY_COMBINER_H_ +#define DUMMY_COMBINER_H_ + +//Include +#include "CombinerBase.h" //baseclass for combiners + +//Forward declarations +struct TexEnvCombiner; +struct Combiner; + +//***************************************************************************** +//* Dummy Combiner +//! Very simple combiner that does as little as possible +//***************************************************************************** +class DummyCombiner : public CombinerBase +{ +public: + + //Constructor / Destructor + DummyCombiner() {} + ~DummyCombiner() {} + + //Initialize + void initialize(); + + //Begin / End Texture Update + void beginTextureUpdate() {} + void endTextureUpdate(TexEnvCombiner* texEnv) {} + + //Sets texture enviorment colors + void setTextureEnviromentColors(TexEnvCombiner* texEnv) {} + + //Create New Texture Environment + TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner); + + //Sets texture enviorment + void setTextureEnviroment(TexEnvCombiner* texEnv); + +private: + + bool ARB_multitexture; //!< Extension supported? + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp new file mode 100755 index 0000000..c5d5c4e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp @@ -0,0 +1,251 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "SimpleTexEnvCombiner.h" +#include "CombinerStructs.h" +#include "MultiTexturingExt.h" +#include "ExtensionChecker.h" +#include "m64p.h" +#include "OpenGL.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +SimpleTexEnvCombiner::SimpleTexEnvCombiner() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +SimpleTexEnvCombiner::~SimpleTexEnvCombiner() +{ +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Checks if multitexturing is supported +//----------------------------------------------------------------------------- +void SimpleTexEnvCombiner::initialize() +{ + ARB_multitexture = isExtensionSupported("GL_ARB_multitexture"); +} + +//----------------------------------------------------------------------------- +//* Begin Texture Update +//! Called before texture channels are updated on the RDP +//----------------------------------------------------------------------------- +void SimpleTexEnvCombiner::beginTextureUpdate() +{ + //Ignore? +} + +//----------------------------------------------------------------------------- +//* End Texture Update +//! Called after texture channels are updated on the RDP +//! @param[in] texEnv Texture Environment +//----------------------------------------------------------------------------- +void SimpleTexEnvCombiner::endTextureUpdate(TexEnvCombiner* texEnv) +{ + //Ignore +} + +//----------------------------------------------------------------------------- +//! Set Texture Envirorment Colors +//! @param[in] texEnv Texture Environment +//----------------------------------------------------------------------------- +void SimpleTexEnvCombiner::setTextureEnviromentColors(TexEnvCombiner* texEnv) +{ + //Ignore +} + +//----------------------------------------------------------------------------- +//* Set Texture Environment +//! Enables texturing and sets texture environment in OpenGL +//! @param[in] texEnv Texture Environment +//----------------------------------------------------------------------------- +void SimpleTexEnvCombiner::setTextureEnviroment(TexEnvCombiner* texEnv) +{ + if ( ARB_multitexture ) + glActiveTextureARB( GL_TEXTURE0_ARB ); + + if (texEnv->usesT0 || texEnv->usesT1) + glEnable( GL_TEXTURE_2D ); + else + glDisable( GL_TEXTURE_2D ); + + //Set Mode + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv->mode); +} + +//----------------------------------------------------------------------------- +//* Create New Texture Enviornment +//! Allocates a new texture enviroment +//! @param[in] colorCombiner How to combine and get a color +//! @param[in] alphaCombiner How to combine and get an alpha value +//! @return The texture enviroment that was created +//----------------------------------------------------------------------------- +TexEnvCombiner* SimpleTexEnvCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner) +{ + TexEnvCombiner* texEnv = new TexEnvCombiner(); + + bool m_usesTexture0 = false; + bool m_usesTexture1 = false; + int mode = GL_REPLACE; + unsigned short m_color = COMBINED; + unsigned short m_alpha = COMBINED; + + //For each stage in alpha combiner + for (int i = 0; i < alphaCombiner->numStages; i++) + { + //For each operation in stage + for (int j = 0; j < alphaCombiner->stage[i].numOps; j++) + { + CombinerOp* op = &alphaCombiner->stage[i].op[j]; + + //Apply operation + switch ( alphaCombiner->stage[i].op[j].op ) + { + case LOAD: + if ( op->param1 != TEXEL0_ALPHA && op->param1 != TEXEL1_ALPHA ) + { + m_alpha = op->param1; + m_usesTexture0 = false; + m_usesTexture1 = false; + } + else + { + mode = GL_REPLACE; + m_usesTexture0 = op->param1 == TEXEL0_ALPHA; + m_usesTexture1 = op->param1 == TEXEL1_ALPHA; + } + break; + case MUL: { + CombinerOp* prevOp = &alphaCombiner->stage[i].op[j-1]; + + if (((op->param1 == TEXEL0_ALPHA) || (op->param1 == TEXEL1_ALPHA)) && + ((prevOp->param1 != TEXEL0_ALPHA) || (prevOp->param1 != TEXEL1_ALPHA))) + { + mode = GL_MODULATE; + } + else if ( ( op->param1 != TEXEL0_ALPHA || op->param1 != TEXEL1_ALPHA) && + (prevOp->param1 == TEXEL0_ALPHA || prevOp->param1 == TEXEL1_ALPHA) ) + { + m_alpha = op->param1; + mode = GL_MODULATE; + } + } + break; + } + } + } + + + //For each stage in colorCombiner + for (int i = 0; i < colorCombiner->numStages; i++) + { + for (int j = 0; j < colorCombiner->stage[i].numOps; j++) + { + CombinerOp* op = &colorCombiner->stage[i].op[j]; + + switch ( colorCombiner->stage[i].op[j].op ) + { + case LOAD: + if (op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA) + { + if ( mode == GL_MODULATE ) + m_color = ONE; + + m_usesTexture0 = true; + m_usesTexture1 = false; + } + else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA ) + { + if ( mode == GL_MODULATE ) + m_color = ONE; + + m_usesTexture0 = false; + m_usesTexture1 = true; + } + else + { + m_color = op->param1; + m_usesTexture0 = m_usesTexture1 = false; + } + break; + case MUL: + if ( op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA ) + { + if (!m_usesTexture0 && !m_usesTexture1) + { + mode = GL_MODULATE; + m_usesTexture0 = true; + m_usesTexture1 = false; + } + } + else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA ) + { + if (!m_usesTexture0 && !m_usesTexture1) + { + mode = GL_MODULATE; + m_usesTexture0 = false; + m_usesTexture1 = true; + } + } + else if ( m_usesTexture0 || m_usesTexture1 ) + { + mode = GL_MODULATE; + m_color = op->param1; + } + break; + case INTERPOLATE: + if ((op->param1 == TEXEL0) && + ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) && + (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) && + (op->param3 == TEXEL0_ALPHA)) + { + mode = GL_DECAL; + m_color = op->param2; + m_usesTexture0 = true; + m_usesTexture1 = false; + } + else if ((op->param1 == TEXEL0) && + ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) && + (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) && + (op->param3 == TEXEL0_ALPHA)) + { + mode = GL_DECAL; + m_color = op->param2; + m_usesTexture0 = false; + m_usesTexture1 = true; + } + break; + } + } + } + + texEnv->usesT0 = m_usesTexture0; + texEnv->usesT1 = m_usesTexture1; + texEnv->mode = mode; + texEnv->vertex.color = m_color; + texEnv->vertex.alpha = m_alpha; + return texEnv; +} diff --git a/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h new file mode 100755 index 0000000..765c9f8 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef SIMPLE_TEX_ENV_COMBINER_H_ +#define SIMPLE_TEX_ENV_COMBINER_H_ + +#include "GBIDefs.h" +#include "CombinerStructs.h" +#include "CombinerBase.h" + +//Forward declarations +struct CombineCycle; +struct CombinerStage; +struct Combiner; + +//***************************************************************************** +//! Simple Texture Environment Combiner +//! Uses glTexEnvi to set texture environment i OpenGL. +//***************************************************************************** +class SimpleTexEnvCombiner : public CombinerBase +{ +public: + + //Constructor / Destructor + SimpleTexEnvCombiner(); + ~SimpleTexEnvCombiner(); + + //Initialize + void initialize(); + + //Begin / End Texture Update + void beginTextureUpdate(); + void endTextureUpdate(TexEnvCombiner* texEnv); + + //Sets texture enviorment colors + void setTextureEnviromentColors(TexEnvCombiner* texEnv); + + //Create New Texture Environment + TexEnvCombiner* createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner); + + //Sets texture enviorment + void setTextureEnviroment(TexEnvCombiner* texEnv); + +private: + + bool ARB_multitexture; //!< Multitexture Extension supported? + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp b/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp new file mode 100755 index 0000000..90aec28 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp @@ -0,0 +1,219 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "DisplayListParser.h" +#include "Memory.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "OpenGLRenderer.h" +#include "GBIDefs.h" + +//----------------------------------------------------------------------------- +//* Task +//! Definition of tasks that needs to be performed by the RSP +//! Used to process the dlist by the RSP (Reality Signal Processor) +//! Placed in DMEM at adress 0x04000fc0 +//----------------------------------------------------------------------------- +typedef struct +{ + unsigned int type; + unsigned int flags; + unsigned int ucode_boot; + unsigned int ucode_boot_size; + unsigned int ucode; + unsigned int ucode_size; + unsigned int ucode_data; + unsigned int ucode_data_size; + unsigned int dram_stack; + unsigned int dram_stack_size; + unsigned int output_buff; + unsigned int output_buff_size; + unsigned int data_ptr; + unsigned int data_size; + unsigned int yield_data_ptr; + unsigned int yield_data_size; +} Task_t; + +typedef union { + Task_t t; + unsigned long long force_structure_alignment; +} Task; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +DisplayListParser::DisplayListParser() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +DisplayListParser::~DisplayListParser() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +bool DisplayListParser::initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory) +{ + //Save pointers + m_rsp = rsp; + m_rdp = rdp; + m_gbi = gbi; + m_memory = memory; + + //Reset display list + m_DListStackPointer = 0; + for (int i=0; igetDMEM(TASK_ADDRESS_RELATIVE_DMEM)); + + + //Select UCode + m_gbi->selectUCode(task->t.ucode, task->t.ucode_data, task->t.ucode_size, task->t.ucode_data_size); + + //Parse DList + m_DListStackPointer = 0; + m_DlistStack[m_DListStackPointer].pc = (unsigned int)task->t.data_ptr; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; + + // The main loop + while( m_DListStackPointer >= 0 ) + { + //Cast memory pointer + //uint32* RDRAMu32 = (unsigned int*)graphicsInfo.RDRAM; + unsigned int* RDRAMu32 = m_memory->getRDRAMint32(); + + //Get ucode argument from memory (vertices, textures, matrices...) + MicrocodeArgument* ucodeArg = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)]; + + //Increment program counter + m_DlistStack[m_DListStackPointer].pc += 8; + + //Call function to execute command + m_gbi->m_cmds[(ucodeArg->cmd)](ucodeArg); + + //Get next command + MicrocodeArgument* ucodeNext = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)]; + + //If this was a rendering command + if ( ucodeArg->cmd == GBI::G_TRI1 || + ucodeArg->cmd == GBI::G_TRI2 || + ucodeArg->cmd == GBI::G_TRI4 || + ucodeArg->cmd == GBI::G_QUAD || + ucodeArg->cmd == GBI::G_DMA_TRI ) + { + //If next is not a rendering command + if ( ucodeNext->cmd != GBI::G_TRI1 && + ucodeNext->cmd != GBI::G_TRI2 && + ucodeNext->cmd != GBI::G_TRI4 && + ucodeNext->cmd != GBI::G_QUAD && + ucodeNext->cmd != GBI::G_DMA_TRI ) + { + OpenGLRenderer::getSingleton().render(); + } + } + + //?? + if ( m_DListStackPointer >= 0 && --m_DlistStack[m_DListStackPointer].countdown < 0 ) + { + m_DListStackPointer--; + } + } + + //Trigger interupts + m_rdp->triggerInterrupt(); + m_rsp->triggerInterrupt(); +} + +//----------------------------------------------------------------------------- +//! Get next word +//----------------------------------------------------------------------------- +unsigned int DisplayListParser::getNextWord() +{ + unsigned int word = *(unsigned int*)m_memory->getRDRAM( this->getPC() + 4 ); + this->increasePC(8); + return word; +} + +//----------------------------------------------------------------------------- +//!< @param segmentAddress Used to retrive RDRAM address witch is used to set program counter +//----------------------------------------------------------------------------- +void DisplayListParser::displayList(unsigned int segmentAddress) +{ + unsigned int address = m_memory->getRDRAMAddress(segmentAddress); + + if ( (address + 8) > m_memory->getRDRAMSize() ) { + return; + } + + if ( m_DListStackPointer < (MAX_DL_STACK_SIZE - 1)) + { + m_DListStackPointer++; + m_DlistStack[m_DListStackPointer].pc = address; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; + } +} + +//----------------------------------------------------------------------------- +//! Branch Display List +//----------------------------------------------------------------------------- +void DisplayListParser::branchDisplayList(unsigned int dl) +{ + unsigned int address = m_memory->getRDRAMAddress( dl ); + + if ( (address + 8) > m_memory->getRDRAMSize() ) { + return; + } + + m_DlistStack[m_DListStackPointer].pc = address; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; +} + +//----------------------------------------------------------------------------- +//! DMA Display List +//----------------------------------------------------------------------------- +void DisplayListParser::DMADisplayList( unsigned int w0, unsigned int w1 ) +{ + //unsigned int dwAddr = (w1);//RSPSegmentAddr((gfx->words.w1)); + unsigned int dwAddr = m_memory->getRDRAMAddress(w1);//RSPSegmentAddr((gfx->words.w1)); + + { + m_DListStackPointer++; + m_DlistStack[m_DListStackPointer].pc = dwAddr; + m_DlistStack[m_DListStackPointer].countdown = (((w0)>>16)&0xFF); + } +} diff --git a/source/mupen64plus-video-arachnoid/src/DisplayListParser.h b/source/mupen64plus-video-arachnoid/src/DisplayListParser.h new file mode 100755 index 0000000..0a7412d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/DisplayListParser.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef DISPLAYLIST_PARSER_H_ +#define DISPLAYLIST_PARSER_H_ + +//Forward declaration +class Memory; +class RSP; +class RDP; +class GBI; + +#define MAX_DL_COUNT 100000 //!< Maximum display list count +#define TASK_ADDRESS_RELATIVE_DMEM 0x0FC0 +//----------------------------------------------------------------------------- +//! The display list PC stack. +//----------------------------------------------------------------------------- +typedef struct +{ + unsigned int pc; + int countdown; +} DListStack; + +//***************************************************************************** +//* DisplayListParser +//! Class for parsing and managing the displaylist +//***************************************************************************** +class DisplayListParser +{ +public: + //Constructor / Destructor + DisplayListParser(); + ~DisplayListParser(); + + //Initialize + bool initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory); + + //Process/Parse the display list + void processDisplayList(); + + //Display list funcitons + void branchDisplayList(unsigned int dl); + void displayList(unsigned int segmentAddress); + void DMADisplayList( unsigned int w0, unsigned int w1 ); + //! End display list + void endDisplayList() { --m_DListStackPointer; } + + //! Get Program Counter + unsigned int getPC() { return m_DlistStack[m_DListStackPointer].pc; } + + //! Set Program Counter + void setPC(unsigned int pc) { m_DlistStack[m_DListStackPointer].pc = pc; } + + //! Increase Program Counter + void increasePC(int increment) { m_DlistStack[m_DListStackPointer].pc += increment; } + + //Get Next Word + unsigned int getNextWord(); + + //! Get Current Display List + DListStack& getCurrentDlist() { return m_DlistStack[m_DListStackPointer]; } + +private: + + //Pointers + RSP* m_rsp; //! Pointer to Reality Signal Processor + RDP* m_rdp; //! Pointer to Reality Drawing Processor + GBI* m_gbi; //! Pointer to Graphics Binary Interface + Memory* m_memory; //! Pointer to Memory + + //Stack used for processing the Display List + int m_DListStackPointer; //!< Current size of Display List stack + static const int MAX_DL_STACK_SIZE = 32; //!< Maximum size of Display List stack + DListStack m_DlistStack[MAX_DL_STACK_SIZE]; //!< Stack used for processing the Display List +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp new file mode 100755 index 0000000..af1363e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.cpp @@ -0,0 +1,57 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "m64p.h" +#include "OpenGL.h" +#include "ExtensionChecker.h" + +//----------------------------------------------------------------------------- +//! Is Extension Supported +//----------------------------------------------------------------------------- +bool isExtensionSupported( const char *extension ) +{ + const GLubyte *extensions = NULL; + const GLubyte *start; + GLubyte *where, *terminator; + + where = (GLubyte *) strchr(extension, ' '); + if (where || *extension == '\0') + return false; + + extensions = glGetString(GL_EXTENSIONS); + + start = extensions; + for (;;) + { + where = (GLubyte *) strstr((const char *) start, extension); + if (!where) + break; + + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return true; + + start = terminator; + } + + return false; +} diff --git a/source/mupen64plus-video-arachnoid/src/ExtensionChecker.h b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.h new file mode 100755 index 0000000..3623066 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ExtensionChecker.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef EXTENSION_CHECKER_H +#define EXTENSION_CHECKER_H_ + +bool isExtensionSupported( const char *extension ); + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/FogManager.cpp b/source/mupen64plus-video-arachnoid/src/FogManager.cpp new file mode 100755 index 0000000..0625d3b --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/FogManager.cpp @@ -0,0 +1,199 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "FogManager.h" +#include "ExtensionChecker.h" +#include "m64p.h" +#include "OpenGL.h" + +#ifndef GL_GLEXT_VERSION + //----------------------------------------------------------------------------- + // EXT_fog_coord functions + //----------------------------------------------------------------------------- + #ifndef GL_EXT_fog_coord + #define GL_EXT_fog_coord 1 + #if defined(GL_GLEXT_PROTOTYPES) && !defined(HAVE_GLES) + extern void APIENTRY glFogCoordfEXT (GLfloat); + extern void APIENTRY glFogCoordfvEXT (const GLfloat *); + extern void APIENTRY glFogCoorddEXT (GLdouble); + extern void APIENTRY glFogCoorddvEXT (const GLdouble *); + extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); + #endif + + typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); + typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); + typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); + typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); + + #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 + #define GL_FOG_COORDINATE_EXT 0x8451 + #define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + #endif + + PFNGLFOGCOORDFEXTPROC glFogCoordfEXT; + PFNGLFOGCOORDFVEXTPROC glFogCoordfvEXT; + PFNGLFOGCOORDDEXTPROC glFogCoorddEXT; + PFNGLFOGCOORDDVEXTPROC glFogCoorddvEXT; + PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointerEXT; +#endif + +#ifdef HAVE_GLES +#define glFogi glFogf +#endif + +//----------------------------------------------------------------------------- +//! Static Variables +//----------------------------------------------------------------------------- +bool FogManager::m_fogExtensionsSupported = false; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +FogManager::FogManager() +{ + m_multiplier = 0; + m_offset = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +FogManager::~FogManager() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Initializes fog extensions +//----------------------------------------------------------------------------- +void FogManager::initialize() +{ + m_multiplier = 0; + m_offset = 0; + + //Initialize extensions + static bool fogExtensionInitialized = false; + if ( !fogExtensionInitialized ) + { +#ifndef HAVE_GLES + m_fogExtensionsSupported = isExtensionSupported("GL_EXT_fog_coord"); + if ( m_fogExtensionsSupported ) + { +#ifndef GL_GLEXT_VERSION + glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)wglGetProcAddress( "glFogCoordfEXT" ); + glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)wglGetProcAddress( "glFogCoordfvEXT" ); + glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)wglGetProcAddress( "glFogCoorddEXT" ); + glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)wglGetProcAddress( "glFogCoorddvEXT" ); + glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)wglGetProcAddress( "glFogCoordPointerEXT" ); +#endif + fogExtensionInitialized = true; + } +#endif + } + +#ifndef HAVE_GLES + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); +#endif +} + +//----------------------------------------------------------------------------- +//! Dispose +//----------------------------------------------------------------------------- +void FogManager::dispose() +{ +} + +//----------------------------------------------------------------------------- +//* SetFogCoordPointer +//! Function used to set vertex based fog +//! @param[in] type Specifies the datatype of each fog coordinate in the array. +//! @param[in] stride Specifies the byte offset between consecutive fog coordinates +//! @param[in] pointer Specifies a pointer to the first component of the first fog coordinate in the array +//! http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glFogCoordPointerEXT.htm +//----------------------------------------------------------------------------- +void FogManager::setFogCoordPointer(unsigned int type, int stride, const void* pointer) +{ + if ( m_fogExtensionsSupported ) + { + glFogCoordPointerEXT(type, stride, pointer); + } +} + +//----------------------------------------------------------------------------- +//* Enable Fog Coord Array +//! Function used to enable vertex based fog +//! @see disableFogCoordArray() +//----------------------------------------------------------------------------- +void FogManager::enableFogCoordArray() +{ + if ( m_fogExtensionsSupported ) + { + glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT); + } +} + +//----------------------------------------------------------------------------- +//* Disable Fog Coord Array +//! Function used to disable vertex based fog +//! @see enableFogCoordArray() +//----------------------------------------------------------------------------- +void FogManager::disableFogCoordArray() +{ + if ( m_fogExtensionsSupported ) + { + glDisableClientState(GL_FOG_COORDINATE_ARRAY_EXT); + } +} + +//----------------------------------------------------------------------------- +//* Set Linear Fog +//! Function used to set linear fog using a linear fog equation +//! Equation for linear fog is: +//! fog = (end - z) / (end - start) +//! where z is the distance in eye coordinates from the origin to the fragment being fogged +//! @param start Specifies start (near) distance used in the linear fog equation. +//! The initial near distance is 0. +//! @param end Specifies end (the far) distance used in the linear fog equation. +//! The initial far distance is 1. +//! http://www.hmug.org/man/3/glFogi.php +//----------------------------------------------------------------------------- +void FogManager::setLinearFog(float start, float end) +{ + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogf(GL_FOG_START, start); + glFogf(GL_FOG_END, end); +} + +//----------------------------------------------------------------------------- +//* Set Fog Color +//! @param r The red component of the fog color +//! @param g The green component of the fog color +//! @param b The blue component of the fog color +//! @param a The alpha component of the fog color +//----------------------------------------------------------------------------- +void FogManager::setFogColor(float r, float g, float b, float a) +{ + float fogColor[4] = { r,g,b,a }; + glFogfv(GL_FOG_COLOR, fogColor ); +} diff --git a/source/mupen64plus-video-arachnoid/src/FogManager.h b/source/mupen64plus-video-arachnoid/src/FogManager.h new file mode 100755 index 0000000..9669d2f --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/FogManager.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef FOG_MANAGER_H_ +#define FOG_MANAGER_H_ + +//***************************************************************************** +//* Fog Manager +//! Class for setting fog using OpenGL +//! @details This manager has support for vertex based using OpenGL Extensions +//***************************************************************************** +class FogManager +{ +public: + + //Constructor / Destructor + FogManager(); + ~FogManager(); + + //Initialize / Dispose + void initialize(); + void dispose(); + + //Set Fog settings + void setLinearFog(float start=0, float end=255); + void setFogColor(float r, float g, float b, float a); + + //Extensions (for vertex based fog) + void setFogCoordPointer(unsigned int type, int stride, const void* pointer); + void enableFogCoordArray(); + void disableFogCoordArray(); + + //Get/Set N64 Settings + void setFogSettings(float multiplier, float offset) { m_multiplier = multiplier; m_offset = offset; } + float getMultiplier() { return m_multiplier; } + float getOffset() { return m_offset; } + +public: + + //! Is fog extension supported? + static bool fogExtensionsSupported() { return m_fogExtensionsSupported; } + +private: + + static bool m_fogExtensionsSupported; //!< Is fog extension supported + float m_multiplier; //!< Fog multiplier + float m_offset; //!< Fog offset + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp b/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp new file mode 100755 index 0000000..8a99ee4 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp @@ -0,0 +1,247 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "GBI.h" +#include "GBIDefs.h" +#include "RSP.h" +#include "RDP.h" +#include "UCodeSelector.h" +#include "UCodeIdentificationData.h" +#include "OpenGLManager.h" +#include "Logger.h" +#include "m64p.h" + +//----------------------------------------------------------------------------- +//! Static Variables +//----------------------------------------------------------------------------- +unsigned int GBI::G_MOVEMEM, GBI::G_MOVEWORD; +unsigned int GBI::G_RDPHALF_1, GBI::G_RDPHALF_2, GBI::G_RDPHALF_CONT; +unsigned int GBI::G_SPNOOP; +unsigned int GBI::G_SETOTHERMODE_H, GBI::G_SETOTHERMODE_L; +unsigned int GBI::G_DL, GBI::G_ENDDL, GBI::G_CULLDL, GBI::G_BRANCH_Z; +unsigned int GBI::G_LOAD_UCODE; + +unsigned int GBI::G_MTX, GBI::G_POPMTX; +unsigned int GBI::G_GEOMETRYMODE, GBI::G_SETGEOMETRYMODE, GBI::G_CLEARGEOMETRYMODE; +unsigned int GBI::G_TEXTURE; +unsigned int GBI::G_DMA_IO, GBI::G_DMA_DL, GBI::G_DMA_TRI, GBI::G_DMA_MTX, GBI::G_DMA_VTX, GBI::G_DMA_OFFSETS; +unsigned int GBI::G_SPECIAL_1, GBI::G_SPECIAL_2, GBI::G_SPECIAL_3; +unsigned int GBI::G_VTX, GBI::G_MODIFYVTX, GBI::G_VTXCOLORBASE; +unsigned int GBI::G_TRI1, GBI::G_TRI2, GBI::G_TRI4; +unsigned int GBI::G_QUAD, GBI::G_LINE3D; +unsigned int GBI::G_RESERVED0, GBI::G_RESERVED1, GBI::G_RESERVED2, GBI::G_RESERVED3; +unsigned int GBI::G_SPRITE2D_BASE; +unsigned int GBI::G_BG_1CYC, GBI::G_BG_COPY; +unsigned int GBI::G_OBJ_RECTANGLE, GBI::G_OBJ_SPRITE, GBI::G_OBJ_MOVEMEM; +unsigned int GBI::G_SELECT_DL, GBI::G_OBJ_RENDERMODE, GBI::G_OBJ_RECTANGLE_R; +unsigned int GBI::G_OBJ_LOADTXTR, GBI::G_OBJ_LDTX_SPRITE, GBI::G_OBJ_LDTX_RECT, GBI::G_OBJ_LDTX_RECT_R; +unsigned int GBI::G_RDPHALF_0; + +unsigned int GBI::G_MTX_STACKSIZE; +unsigned int GBI::G_MTX_MODELVIEW; +unsigned int GBI::G_MTX_PROJECTION; +unsigned int GBI::G_MTX_MUL; +unsigned int GBI::G_MTX_LOAD; +unsigned int GBI::G_MTX_NOPUSH; +unsigned int GBI::G_MTX_PUSH; + +unsigned int GBI::G_TEXTURE_ENABLE; +unsigned int GBI::G_SHADING_SMOOTH; +unsigned int GBI::G_CULL_FRONT; +unsigned int GBI::G_CULL_BACK; +unsigned int GBI::G_CULL_BOTH; +unsigned int GBI::G_CLIPPING; + +unsigned int GBI::G_MV_VIEWPORT; + +unsigned int GBI::G_MWO_aLIGHT_1, GBI::G_MWO_bLIGHT_1; +unsigned int GBI::G_MWO_aLIGHT_2, GBI::G_MWO_bLIGHT_2; +unsigned int GBI::G_MWO_aLIGHT_3, GBI::G_MWO_bLIGHT_3; +unsigned int GBI::G_MWO_aLIGHT_4, GBI::G_MWO_bLIGHT_4; +unsigned int GBI::G_MWO_aLIGHT_5, GBI::G_MWO_bLIGHT_5; +unsigned int GBI::G_MWO_aLIGHT_6, GBI::G_MWO_bLIGHT_6; +unsigned int GBI::G_MWO_aLIGHT_7, GBI::G_MWO_bLIGHT_7; +unsigned int GBI::G_MWO_aLIGHT_8, GBI::G_MWO_bLIGHT_8; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +GBI::GBI() +{ + m_ucodeSelector = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +GBI::~GBI() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//* Initialize +//----------------------------------------------------------------------------- +bool GBI::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp) +{ + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; + + //Reset Binary Interface + for(int i=0; i<256; ++i) + { + m_cmds[i] = (GBIFunc)GBI::unknownInstruction; + } + + //Add RDP Instructions + m_rdpInsructions.initialize(m_rdp, dlp); + + m_cmds[G_SETCIMG] = (GBIFunc)RDPInstructions::RDP_SetCImg; + m_cmds[G_SETZIMG] = (GBIFunc)RDPInstructions::RDP_SetZImg; + m_cmds[G_SETTIMG] = (GBIFunc)RDPInstructions::RDP_SetTImg; + m_cmds[G_SETTILE] = (GBIFunc)RDPInstructions::RDP_SetTile; + m_cmds[G_LOADTILE] = (GBIFunc)RDPInstructions::RDP_LoadTile; + m_cmds[G_LOADBLOCK] = (GBIFunc)RDPInstructions::RDP_LoadBlock; + m_cmds[G_SETTILESIZE] = (GBIFunc)RDPInstructions::RDP_SetTileSize; + m_cmds[G_LOADTLUT] = (GBIFunc)RDPInstructions::RDP_LoadTLUT; + m_cmds[G_FILLRECT] = (GBIFunc)RDPInstructions::RDP_FillRect; + m_cmds[G_TEXRECTFLIP] = (GBIFunc)RDPInstructions::RDP_TexRectFlip; + m_cmds[G_TEXRECT] = (GBIFunc)RDPInstructions::RDP_TexRect; + m_cmds[G_SETENVCOLOR] = (GBIFunc)RDPInstructions::RDP_SetEnvColor; + m_cmds[G_SETPRIMCOLOR] = (GBIFunc)RDPInstructions::RDP_SetPrimColor; + m_cmds[G_SETBLENDCOLOR] = (GBIFunc)RDPInstructions::RDP_SetBlendColor; + m_cmds[G_SETFOGCOLOR] = (GBIFunc)RDPInstructions::RDP_SetFogColor; + m_cmds[G_SETFILLCOLOR] = (GBIFunc)RDPInstructions::RDP_SetFillColor; + m_cmds[G_SETCOMBINE] = (GBIFunc)RDPInstructions::RDP_SetCombine; + m_cmds[G_RDPSETOTHERMODE] = (GBIFunc)RDPInstructions::RDP_SetOtherMode; + m_cmds[G_SETPRIMDEPTH] = (GBIFunc)RDPInstructions::RDP_SetPrimDepth; + m_cmds[G_SETSCISSOR] = (GBIFunc)RDPInstructions::RDP_SetScissor; + m_cmds[G_SETCONVERT] = (GBIFunc)RDPInstructions::RDP_SetConvert; + m_cmds[G_SETKEYR] = (GBIFunc)RDPInstructions::RDP_SetKeyR; + m_cmds[G_SETKEYGB] = (GBIFunc)RDPInstructions::RDP_SetKeyGB; + m_cmds[G_NOOP] = (GBIFunc)RDPInstructions::RDP_NoOp; + m_cmds[G_RDPFULLSYNC] = (GBIFunc)RDPInstructions::RDP_FullSync; + m_cmds[G_RDPTILESYNC] = (GBIFunc)RDPInstructions::RDP_TileSync; + m_cmds[G_RDPPIPESYNC] = (GBIFunc)RDPInstructions::RDP_PipeSync; + m_cmds[G_RDPLOADSYNC] = (GBIFunc)RDPInstructions::RDP_LoadSync; + + m_ucodeSelector = new UCodeSelector(); + if ( !m_ucodeSelector->initialize(memory) ) { + return false; + } + + //Initilize Ucode + + m_ucode0.initialize(m_rsp, m_rdp, memory, dlp); //F3D + m_ucode1.initialize(this, m_rsp, m_rdp, memory); //F3DEX + m_ucode2.initialize(this, m_rsp, m_rdp, memory, dlp); //Golden Eye + m_ucode4.initialize(this, m_rsp); //Wave Race 64 + m_ucode5.initialize(this, m_rsp, m_rdp, memory, dlp); //F3DEX2 + m_ucode6.initialize(this, m_rsp, m_rdp, memory, dlp); //Diddy Kong Racing + m_ucode7.initialize(m_rsp); + m_ucode9.initialize(m_rsp); //Perfect Dark + m_ucode10.initialize(this, m_rsp, m_rdp, memory, dlp); + + m_previusUCodeStart = -1; + + return true; +} + +//----------------------------------------------------------------------------- +// Dispose +//----------------------------------------------------------------------------- +void GBI::dispose() +{ + if ( m_ucodeSelector ) { delete m_ucodeSelector; m_ucodeSelector = 0; } + + m_previusUCodeStart = -1; +} + +//----------------------------------------------------------------------------- +// Select UCode +//----------------------------------------------------------------------------- +void GBI::selectUCode( unsigned int ucStart, + unsigned int ucDStart, + unsigned int ucSize, + unsigned int ucDSize) +{ + if ( m_previusUCodeStart == ucStart ) + { + return; //Already have correct ucode no need to find one + } + m_previusUCodeStart = ucStart; + + //Identify ucode + unsigned int ucode = m_ucodeSelector->checkUCode(ucStart, ucDStart, ucSize, ucDSize); + + //Unsupported ucodes + if ( ucode >= 6 || ucode == 3 ) + { + //MessageBox(0, + // "This graphics plugin does not support this game, please try another.", + // "Arachnoid Graphics Plugin", + // MB_OK|MB_SETFOREGROUND ); + } + + //if ( ucode == 5 ) + //{ + // OpenGLManager::getSingleton().setForceDisableCulling(true); //Do not support Face Culling? + //} + + //Set Ucode + switch ( ucode ) + { + case 0 : m_ucode0.initializeGBI(this); break; //F3D - Super Mario 64 + case 1 : m_ucode1.initializeGBI(); break; //F3DEX - Mario Kart, Star Fox 64, Bomberman 64, ... + case 2 : m_ucode2.initializeGBI(); break; // - Golden Eye + case 3 : //S2DEX - Chou Snobow Kids, V-Rally Edition 99, Zelda Majoras Mask + case 4 : m_ucode4.initializeGBI(); break; // - Wave Racer 64 + case 5 : m_ucode5.initializeGBI(); break; //F3DEX2 - Donkey Kong 64, Fighter's Destiny 2, Mario Golf 64, F-Zero X, Paper Mario, ... + case 6 : m_ucode6.initializeGBI(); break; // - Diddy Kong Racing + case 7 : m_ucode7.initializeGBI(this); break; // - Yoshi's Story + case 8 : // - Puzzle Master 64 + case 9 : m_ucode9.initializeGBI(this); break; // - Perfect Dark + case 10 : m_ucode10.initializeGBI(); // - Conker The Bad Fur Day + case 11 : m_ucode6.initializeGBI(); break; // - Jet Force Gemini + case 12 : m_ucode1.initializeGBI(); break; // - 1080 + default : + //m_ucode5.initializeGBI(this); break; //F3DEX2 + //m_ucode1.initializeGBI(this); + m_ucode0.initializeGBI(this); + break; + } + +} + +//----------------------------------------------------------------------------- +//! Unknown Instruction +//! This function will be called when the GBI can't find the correct function +//! to call. +//----------------------------------------------------------------------------- +void GBI::unknownInstruction(MicrocodeArgument* arg) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("GBI - Unknown Function", M64MSG_WARNING); + warned = true; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBI.h b/source/mupen64plus-video-arachnoid/src/GBI/GBI.h new file mode 100755 index 0000000..f6cc898 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GBI/GBI.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef GRAPHIC_BINARY_INTERFACE_H_ +#define GRAPHIC_BINARY_INTERFACE_H_ + + +#include "UCodeDefs.h" +#include "UCode0.h" //Super Mario 64 +#include "UCode1.h" //Games like Mario Kart 64, Starfox 64 +#include "UCode2.h" //Golden Eye +#include "UCode4.h" //Wave Race 64 +#include "UCode5.h" //Newer Games +#include "UCode6.h" //Diddy Kong Racing +#include "UCode7.h" //Yoshi's Story +#include "UCode9.h" //Perfect Dark +#include "UCode10.h" //Conker Bad Fur Day +#include "RDPInstructions.h" + +class RSP; +class RDP; +class Memory; +class UCodeSelector; + +// Allows easier setting of GBI commands +#define GBI_SetGBI( command, value, target, function ) \ + command = value; \ + target[command] = function + +// Useful macros for decoding GBI command's parameters +#define _SHIFTL( v, s, w ) (((unsigned int)v & ((0x01 << w) - 1)) << s) +#define _SHIFTR( v, s, w ) (((unsigned int)v >> s) & ((0x01 << w) - 1)) + + +//----------------------------------------------------------------------------- +//* GBI Func +//! Definition for GBI function pointers +//----------------------------------------------------------------------------- +typedef void (*GBIFunc)( MicrocodeArgument* ); + +//----------------------------------------------------------------------------- +//* GBI +//! Defines the Graphical Binary Interface meaning how the graphic +//! processors should operate. +//----------------------------------------------------------------------------- +class GBI +{ +public: + //Constructor / Deconstructor + GBI(); + ~GBI(); + + bool initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp); + void dispose(); + void selectUCode( unsigned int ucStart, + unsigned int ucDStart, + unsigned int ucSize, + unsigned int ucDSize); + + //Dummy instruction + static void unknownInstruction(MicrocodeArgument* arg); + + static unsigned int G_MOVEMEM, G_MOVEWORD; + static unsigned int G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT; + static unsigned int G_SPNOOP; + static unsigned int G_SETOTHERMODE_H, G_SETOTHERMODE_L; + static unsigned int G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z; + static unsigned int G_LOAD_UCODE; + + static unsigned int G_MTX, G_POPMTX; + static unsigned int G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE; + static unsigned int G_TEXTURE; + static unsigned int G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_OFFSETS; + static unsigned int G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3; + static unsigned int G_VTX, G_MODIFYVTX, G_VTXCOLORBASE; + static unsigned int G_TRI1, G_TRI2, G_TRI4; + static unsigned int G_QUAD, G_LINE3D; + static unsigned int G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3; + static unsigned int G_SPRITE2D_BASE; + static unsigned int G_BG_1CYC, G_BG_COPY; + static unsigned int G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM; + static unsigned int G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R; + static unsigned int G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R; + static unsigned int G_RDPHALF_0; + + static unsigned int G_MTX_STACKSIZE; + static unsigned int G_MTX_MODELVIEW; + static unsigned int G_MTX_PROJECTION; + static unsigned int G_MTX_MUL; + static unsigned int G_MTX_LOAD; + static unsigned int G_MTX_NOPUSH; + static unsigned int G_MTX_PUSH; + + static unsigned int G_TEXTURE_ENABLE; + static unsigned int G_SHADING_SMOOTH; + static unsigned int G_CULL_FRONT; + static unsigned int G_CULL_BACK; + static unsigned int G_CULL_BOTH; + static unsigned int G_CLIPPING; + + static unsigned int G_MV_VIEWPORT; + + static unsigned int G_MWO_aLIGHT_1, G_MWO_bLIGHT_1; + static unsigned int G_MWO_aLIGHT_2, G_MWO_bLIGHT_2; + static unsigned int G_MWO_aLIGHT_3, G_MWO_bLIGHT_3; + static unsigned int G_MWO_aLIGHT_4, G_MWO_bLIGHT_4; + static unsigned int G_MWO_aLIGHT_5, G_MWO_bLIGHT_5; + static unsigned int G_MWO_aLIGHT_6, G_MWO_bLIGHT_6; + static unsigned int G_MWO_aLIGHT_7, G_MWO_bLIGHT_7; + static unsigned int G_MWO_aLIGHT_8, G_MWO_bLIGHT_8; + +public: + + //Function pointer list + GBIFunc m_cmds[256]; //! Function pointers to diffrent GBI instructions + + //Pointers + RSP* m_rsp; //!< Pointer to Reality Signal Processor + RDP* m_rdp; //!< Pointer to Reality Drawing Processor + Memory* m_memory; //!< Pointer to Memory manager (handles RDRAM, Texture Memory...) + + //RDP Instruction + RDPInstructions m_rdpInsructions; + + //UCode selector + UCodeSelector* m_ucodeSelector; //!< Selects apropriete ucode depending on rom. + + //UCodes + UCode0 m_ucode0; //!< UCode for F3D (Super Mario 64) + UCode1 m_ucode1; //!< UCode for F3DEX (Mario Kart 64, Star Fox 64, Fighter's Destiny...) + UCode2 m_ucode2; //!< UCode for Golden Eye + UCode4 m_ucode4; //!< UCode for Wave Racer 64 + UCode5 m_ucode5; //!< UCode for F3DEX2 + UCode6 m_ucode6; //!< UCode for Diddy Kong Racing + UCode7 m_ucode7; //!< UCode for Yoshi's Story + UCode9 m_ucode9; //!< UCode for Perfect Dark + UCode10 m_ucode10; //!< UCode for Conker Bad Fur Day + + //Previus ucode + unsigned int m_previusUCodeStart; +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h b/source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h new file mode 100755 index 0000000..1d9fe9a --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GBI/GBIDefs.h @@ -0,0 +1,323 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef GBI_DEFINITIONS_H_ +#define GBI_DEFINITIONS_H_ + +#include "GBI.h" + + +//TODO Write comments for each group + +#define G_NOOP 0x00 + +// These GBI commands are common to all ucodes + +#define G_SETCIMG 0xFF /* -1 */ +#define G_SETZIMG 0xFE /* -2 */ +#define G_SETTIMG 0xFD /* -3 */ +#define G_SETCOMBINE 0xFC /* -4 */ +#define G_SETENVCOLOR 0xFB /* -5 */ +#define G_SETPRIMCOLOR 0xFA /* -6 */ +#define G_SETBLENDCOLOR 0xF9 /* -7 */ +#define G_SETFOGCOLOR 0xF8 /* -8 */ +#define G_SETFILLCOLOR 0xF7 /* -9 */ +#define G_FILLRECT 0xF6 /* -10 */ +#define G_SETTILE 0xF5 /* -11 */ +#define G_LOADTILE 0xF4 /* -12 */ +#define G_LOADBLOCK 0xF3 /* -13 */ +#define G_SETTILESIZE 0xF2 /* -14 */ +#define G_LOADTLUT 0xF0 /* -16 */ +#define G_RDPSETOTHERMODE 0xEF /* -17 */ +#define G_SETPRIMDEPTH 0xEE /* -18 */ +#define G_SETSCISSOR 0xED /* -19 */ +#define G_SETCONVERT 0xEC /* -20 */ +#define G_SETKEYR 0xEB /* -21 */ +#define G_SETKEYGB 0xEA /* -22 */ +#define G_RDPFULLSYNC 0xE9 /* -23 */ +#define G_RDPTILESYNC 0xE8 /* -24 */ +#define G_RDPPIPESYNC 0xE7 /* -25 */ +#define G_RDPLOADSYNC 0xE6 /* -26 */ +#define G_TEXRECTFLIP 0xE5 /* -27 */ +#define G_TEXRECT 0xE4 /* -28 */ + +#define G_TRI_FILL 0xC8 /* fill triangle: 11001000 */ +#define G_TRI_SHADE 0xCC /* shade triangle: 11001100 */ +#define G_TRI_TXTR 0xCA /* texture triangle: 11001010 */ +#define G_TRI_SHADE_TXTR 0xCE /* shade, texture triangle: 11001110 */ +#define G_TRI_FILL_ZBUFF 0xC9 /* fill, zbuff triangle: 11001001 */ +#define G_TRI_SHADE_ZBUFF 0xCD /* shade, zbuff triangle: 11001101 */ +#define G_TRI_TXTR_ZBUFF 0xCB /* texture, zbuff triangle: 11001011 */ +#define G_TRI_SHADE_TXTR_ZBUFF 0xCF /* shade, txtr, zbuff trngl: 11001111 */ + +#define G_MV_MMTX 2 +#define G_MV_PMTX 6 +#define G_MV_LIGHT 10 +#define G_MV_POINT 12 +#define G_MV_MATRIX 14 + +#define G_MW_MATRIX 0x00 +#define G_MW_NUMLIGHT 0x02 +#define G_MW_CLIP 0x04 +#define G_MW_SEGMENT 0x06 +#define G_MW_FOG 0x08 +#define G_MW_LIGHTCOL 0x0A +#define G_MW_FORCEMTX 0x0C +#define G_MW_POINTS 0x0C +#define G_MW_PERSPNORM 0x0E + +#define G_MWO_POINT_RGBA 0x10 +#define G_MWO_POINT_ST 0x14 +#define G_MWO_POINT_XYSCREEN 0x18 +#define G_MWO_POINT_ZSCREEN 0x1C + +//Move Memory Defines +#define G_MV_LOOKATY 0x82 +#define G_MV_LOOKATX 0x84 +#define G_MV_L0 0x86 +#define G_MV_L1 0x88 +#define G_MV_L2 0x8a +#define G_MV_L3 0x8c +#define G_MV_L4 0x8e +#define G_MV_L5 0x90 +#define G_MV_L6 0x92 +#define G_MV_L7 0x94 +#define G_MV_TXTATT 0x96 +#define G_MV_MATRIX_1 0x9E +#define G_MV_MATRIX_2 0x98 +#define G_MV_MATRIX_3 0x9A +#define G_MV_MATRIX_4 0x9C + + + +// Image formats +#define G_IM_FMT_RGBA 0 +#define G_IM_FMT_YUV 1 +#define G_IM_FMT_CI 2 +#define G_IM_FMT_IA 3 +#define G_IM_FMT_I 4 + +// Image sizes +#define G_IM_SIZ_4b 0 +#define G_IM_SIZ_8b 1 +#define G_IM_SIZ_16b 2 +#define G_IM_SIZ_32b 3 +#define G_IM_SIZ_DD 5 + +#define G_TX_MIRROR 0x1 +#define G_TX_CLAMP 0x2 + + + +// +#define G_DL_PUSH 0x00 +#define G_DL_NOPUSH 0x01 + +enum TextureMode +{ + TM_NORMAL = 0, + TM_TEXRECT = 1, + TM_BGIMAGE = 2, + TM_FRAMEBUFFER = 3, +}; + + +enum LoadType +{ + LOADTYPE_BLOCK = 0, + LOADTYPE_TILE = 1, +}; + +/* + * G_SETOTHERMODE_L sft: shift count + */ +#define G_MDSFT_ALPHACOMPARE 0 +#define G_MDSFT_ZSRCSEL 2 +#define G_MDSFT_RENDERMODE 3 +#define G_MDSFT_BLENDER 16 + +/* + * G_SETOTHERMODE_H sft: shift count + */ +#define G_MDSFT_BLENDMASK 0 /* unsupported */ +#define G_MDSFT_ALPHADITHER 4 +#define G_MDSFT_RGBDITHER 6 + +#define G_MDSFT_COMBKEY 8 +#define G_MDSFT_TEXTCONV 9 +#define G_MDSFT_TEXTFILT 12 +#define G_MDSFT_TEXTLUT 14 +#define G_MDSFT_TEXTLOD 16 +#define G_MDSFT_TEXTDETAIL 17 +#define G_MDSFT_TEXTPERSP 19 +#define G_MDSFT_CYCLETYPE 20 +#define G_MDSFT_COLORDITHER 22 /* unsupported in HW 2.0 */ +#define G_MDSFT_PIPELINE 23 + +/* G_SETOTHERMODE_H gPipelineMode */ +#define G_PM_1PRIMITIVE 1 +#define G_PM_NPRIMITIVE 0 + +//G_SETOTHERMODE_H gSetCycleType +enum G_CYCLE_TYPE { + G_CYC_1CYCLE = 0, + G_CYC_2CYCLE = 1, + G_CYC_COPY = 2, + G_CYC_FILL = 3, +}; + +/* G_SETOTHERMODE_H gSetTexturePersp */ +#define G_TP_NONE 0 +#define G_TP_PERSP 1 + +/* G_SETOTHERMODE_H gSetTextureDetail */ +#define G_TD_CLAMP 0 +#define G_TD_SHARPEN 1 +#define G_TD_DETAIL 2 + +/* G_SETOTHERMODE_H gSetTextureLOD */ +#define G_TL_TILE 0 +#define G_TL_LOD 1 + +/* G_SETOTHERMODE_H gSetTextureLUT */ +#define G_TT_NONE 0 +#define G_TT_RGBA16 2 +#define G_TT_IA16 3 + +/* G_SETOTHERMODE_H gSetTextureFilter */ +#define G_TF_POINT 0 +#define G_TF_AVERAGE 3 +#define G_TF_BILERP 2 + +/* G_SETOTHERMODE_H gSetTextureConvert */ +#define G_TC_CONV 0 +#define G_TC_FILTCONV 5 +#define G_TC_FILT 6 + +/* G_SETOTHERMODE_H gSetCombineKey */ +#define G_CK_NONE 0 +#define G_CK_KEY 1 + +/* G_SETOTHERMODE_H gSetColorDither */ +#define G_CD_MAGICSQ 0 +#define G_CD_BAYER 1 +#define G_CD_NOISE 2 + +#define G_CD_DISABLE 3 +#define G_CD_ENABLE G_CD_NOISE /* HW 1.0 compatibility mode */ + +/* G_SETOTHERMODE_H gSetAlphaDither */ +#define G_AD_PATTERN 0 +#define G_AD_NOTPATTERN 1 +#define G_AD_NOISE 2 +#define G_AD_DISABLE 3 + +/* G_SETOTHERMODE_L gSetAlphaCompare */ +#define G_AC_NONE 0 +#define G_AC_THRESHOLD 1 +#define G_AC_DITHER 3 + +/* G_SETOTHERMODE_L gSetDepthSource */ +#define G_ZS_PIXEL 0 +#define G_ZS_PRIM 1 + +/* G_SETOTHERMODE_L gSetRenderMode */ +#define AA_EN 1 +#define Z_CMP 1 +#define Z_UPD 1 +#define IM_RD 1 +#define CLR_ON_CVG 1 +#define CVG_DST_CLAMP 0 +#define CVG_DST_WRAP 1 +#define CVG_DST_FULL 2 +#define CVG_DST_SAVE 3 +#define ZMODE_OPA 0 +#define ZMODE_INTER 1 +#define ZMODE_XLU 2 +#define ZMODE_DEC 3 +#define CVG_X_ALPHA 1 +#define ALPHA_CVG_SEL 1 +#define FORCE_BL 1 +#define TEX_EDGE 0 // not used + +#define G_SC_NON_INTERLACE 0 +#define G_SC_EVEN_INTERLACE 2 +#define G_SC_ODD_INTERLACE 3 + + +#define GBI_InitFlags( ucode ) \ + GBI::G_MTX_STACKSIZE = ucode##_MTX_STACKSIZE; \ + GBI::G_MTX_MODELVIEW = ucode##_MTX_MODELVIEW; \ + GBI::G_MTX_PROJECTION = ucode##_MTX_PROJECTION; \ + GBI::G_MTX_MUL = ucode##_MTX_MUL; \ + GBI::G_MTX_LOAD = ucode##_MTX_LOAD; \ + GBI::G_MTX_NOPUSH = ucode##_MTX_NOPUSH; \ + GBI::G_MTX_PUSH = ucode##_MTX_PUSH; \ +\ + GBI::G_TEXTURE_ENABLE = ucode##_TEXTURE_ENABLE; \ + GBI::G_SHADING_SMOOTH = ucode##_SHADING_SMOOTH; \ + GBI::G_CULL_FRONT = ucode##_CULL_FRONT; \ + GBI::G_CULL_BACK = ucode##_CULL_BACK; \ + GBI::G_CULL_BOTH = ucode##_CULL_BOTH; \ + GBI::G_CLIPPING = ucode##_CLIPPING; \ +\ + GBI::G_MV_VIEWPORT = ucode##_MV_VIEWPORT; \ + /* \ + GBI::G_MWO_aLIGHT_1 = ucode##_MWO_aLIGHT_1; \ + GBI::G_MWO_bLIGHT_1 = ucode##_MWO_bLIGHT_1; \ + GBI::G_MWO_aLIGHT_2 = ucode##_MWO_aLIGHT_2; \ + GBI::G_MWO_bLIGHT_2 = ucode##_MWO_bLIGHT_2; \ + GBI::G_MWO_aLIGHT_3 = ucode##_MWO_aLIGHT_3; \ + GBI::G_MWO_bLIGHT_3 = ucode##_MWO_bLIGHT_3; \ + GBI::G_MWO_aLIGHT_4 = ucode##_MWO_aLIGHT_4; \ + GBI::G_MWO_bLIGHT_4 = ucode##_MWO_bLIGHT_4; \ + GBI::G_MWO_aLIGHT_5 = ucode##_MWO_aLIGHT_5; \ + GBI::G_MWO_bLIGHT_5 = ucode##_MWO_bLIGHT_5; \ + GBI::G_MWO_aLIGHT_6 = ucode##_MWO_aLIGHT_6; \ + GBI::G_MWO_bLIGHT_6 = ucode##_MWO_bLIGHT_6; \ + GBI::G_MWO_aLIGHT_7 = ucode##_MWO_aLIGHT_7; \ + GBI::G_MWO_bLIGHT_7 = ucode##_MWO_bLIGHT_7; \ + GBI::G_MWO_aLIGHT_8 = ucode##_MWO_aLIGHT_8; \ + GBI::G_MWO_bLIGHT_8 = ucode##_MWO_bLIGHT_8; \ + */ + + +// Fixed point conversion factors +#define FIXED2FLOATRECIP1 0.5f +#define FIXED2FLOATRECIP2 0.25f +#define FIXED2FLOATRECIP3 0.125f +#define FIXED2FLOATRECIP4 0.0625f +#define FIXED2FLOATRECIP5 0.03125f +#define FIXED2FLOATRECIP6 0.015625f +#define FIXED2FLOATRECIP7 0.0078125f +#define FIXED2FLOATRECIP8 0.00390625f +#define FIXED2FLOATRECIP9 0.001953125f +#define FIXED2FLOATRECIP10 0.0009765625f +#define FIXED2FLOATRECIP11 0.00048828125f +#define FIXED2FLOATRECIP12 0.00024414063f +#define FIXED2FLOATRECIP13 0.00012207031f +#define FIXED2FLOATRECIP14 6.1035156e-05f +#define FIXED2FLOATRECIP15 3.0517578e-05f +#define FIXED2FLOATRECIP16 1.5258789e-05f + +#define _FIXED2FLOAT( v, b ) ((float)v * FIXED2FLOATRECIP##b) + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp new file mode 100755 index 0000000..38da3d5 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp @@ -0,0 +1,495 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "GraphicsPlugin.h" +#include "VI.h" //Video interface +#include "Memory.h" //Access to memory (RDRAM, Texture Memory) +#include "OpenGLRenderer.h" //Renderer +#include "FrameBuffer.h" //Framebuffer +#include "DisplayListParser.h" //Displaylist parser +#include "FogManager.h" //Fog +#include "RSP.h" //Reality Signal Processor +#include "RDP.h" //Reality Drawing Processor +#include "GBI.h" //Graphics Binary Interface +#include "ConfigMap.h" //Configuration +#include "Logger.h" //Debug logger +#include "RomDetector.h" +#include +#ifdef HAVE_GLES +#include "eglport.h" +#include +#include +#endif + +//FrameBuffer framebuffer01; +//FrameBuffer framebuffer02; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +GraphicsPlugin::GraphicsPlugin() +: m_openGLMgr( OpenGLManager::getSingleton() ) +{ + m_vi = 0; + m_initialized = false; + m_updateConfig = false; + m_fogManager = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +GraphicsPlugin::~GraphicsPlugin() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------- +bool GraphicsPlugin::initialize(GFX_INFO* graphicsInfo) +{ + //Initialize video output + if (CoreVideo_Init() != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not initialize video.", M64MSG_ERROR); + return false; + } + + //Save pointer to graphics info + m_graphicsInfo = graphicsInfo; + + m_numDListProcessed = 0; + + //Detect what rom it is + m_romDetector = &ROMDetector::getSingleton(); + m_romDetector->initialize( m_graphicsInfo->HEADER ); +#ifdef HAVE_GLES + SDL_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, SDL_FULLSCREEN); + SDL_ShowCursor(SDL_DISABLE); + EGL_Open(m_config->fullscreenWidth, m_config->fullscreenHeight); +#else + if (m_config->multiSampling > 0) + { + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1); + if (m_config->multiSampling <= 2) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2); + else if (m_config->multiSampling <= 4) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4); + else if (m_config->multiSampling <= 8) + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8); + else + CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16); + } + + if (CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1) != M64ERR_SUCCESS || + CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32) != M64ERR_SUCCESS || + CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 24) != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not set video attributes.", M64MSG_ERROR); + return false; + } + + if (CoreVideo_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, + m_config->startFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, (m64p_video_flags) 0) != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not set video mode.", M64MSG_ERROR); + return false; + } + + CoreVideo_SetCaption("Arachnoid"); +#endif + //Initialize Video Interface + m_vi = new VI(); + m_vi->calcSize(m_graphicsInfo); + + //Initialize Memory + m_memory = new Memory(); + if ( !m_memory->initialize(m_graphicsInfo->RDRAM, m_graphicsInfo->DMEM) ) + { + return false; + } + + m_displayListParser = new DisplayListParser(); + m_displayListParser->initialize(&m_rsp, &m_rdp, &m_gbi, m_memory); + + //Init OpenGL + if ( !m_openGLMgr.initialize(m_config->startFullscreen, m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate, true, false) ) + { + Logger::getSingleton().printMsg("Unable to initialize OpenGL", M64MSG_ERROR); + return false; + } + + + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + + //Initialize Fog Manager + m_fogManager = new FogManager(); + m_fogManager->initialize(); + + + + //Initialize Texture Cache + //! @todo Not "hardcode" TextureBitDepth. + m_textureCache.initialize(&m_rsp, &m_rdp, m_memory, 16); + m_textureCache.setMipmap( m_config->mipmapping ); + + //Initialize OpenGL Renderer + if ( !OpenGLRenderer::getSingleton().initialize(&m_rsp, &m_rdp, &m_textureCache, m_vi, m_fogManager) ) + { + Logger::getSingleton().printMsg("Unable to initialize OpenGL Renderer", M64MSG_ERROR); + return false; + } + + //Initialize Processors + m_rdp.initialize(m_graphicsInfo, &m_rsp, m_memory, &m_gbi, &m_textureCache, m_vi, m_displayListParser, m_fogManager); + m_rsp.initialize(m_graphicsInfo, &m_rdp, m_memory, m_vi, m_displayListParser, m_fogManager); + m_gbi.initialize(&m_rsp, &m_rdp, m_memory, m_displayListParser); + + + //Set Background color + m_openGLMgr.setClearColor(0.0f, 0.0f, 0.0f); + m_openGLMgr.setLighting(false); + glDisable(GL_LIGHTING); + m_openGLMgr.setCullMode(false, true); + m_openGLMgr.setWireFrame(m_config->wireframe); + + //Initialize framebuffer + //framebuffer01.initialize(width, height); + // framebuffer02.initialize(width, height); + + m_initialized = true; + return true; +} + +//----------------------------------------------------------------------------- +// Dispose +//----------------------------------------------------------------------------- +void GraphicsPlugin::dispose() +{ + //Dispose of Textures + m_textureCache.dispose(); + + //Dispose of member objects + if ( m_vi ) { delete m_vi; m_vi = 0; } + if ( m_memory ) { delete m_memory; m_memory = 0; } + if ( m_displayListParser ) { delete m_displayListParser; m_displayListParser = 0; } + if ( m_fogManager ) { delete m_fogManager; m_fogManager = 0; } + + m_gbi.dispose(); + m_rdp.dispose(); + m_rsp.dispose(); + + //Dispose of OpenGL + //framebuffer01.dispose(); + // framebuffer02.dispose(); + m_openGLMgr.dispose(); + + if (m_initialized) +#ifdef HAVE_GLES + { + EGL_Close(); + SDL_Quit(); // *SEB* *TODO* Close Subsystem only? + } +#else + CoreVideo_Quit(); +#endif + + m_initialized = false; +} + +void renderMotionBlur() +{ + ///glPushMatrix(); + + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glEnable(GL_BLEND); + glColor4f(1, 1, 1, 0.9f); //Alpha blending + +// framebuffer01.render2(); + + glColor4f(1, 1, 1, 1.0f); //Alpha blending + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + //glPopMatrix(); +} + +bool animate(int frameRate) +{ + static clock_t lastTime; + clock_t currentTime = clock() * 1000 / CLOCKS_PER_SEC; + clock_t elapsedTime = currentTime - lastTime; + if (elapsedTime > ((clock_t)1000 / frameRate)) + { + lastTime = currentTime; + return true; + } + return false; + +#if 0 + //Todo: test against new version + static float lastTime = 0.0f; + float elapsedTime = 0.0; + float currentTime = GetTickCount() * 0.001f; + elapsedTime = currentTime - lastTime; + + if( elapsedTime > (1.0f / frameRate) ) + { + lastTime = currentTime; + return true; + } + + return false; +#endif + +} + +void renderQuad() +{ + static float dt = 0; + dt += 0.2f; + + //glDisable(GL_CULL_FACE); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + // glRotatef(dt, 0, 1, 0); + { +#ifdef HAVE_GLES +//*SEB* *TODO* +#else + glBegin(GL_QUADS); + { + glColor3f(1,0,0); glVertex3f(-1,-1,0); + glColor3f(1,1,0); glVertex3f( 1,-1,0); + glColor3f(0,1,1); glVertex3f( 1, 1,0); + glColor3f(0,0,1); glVertex3f(-1, 1,0); + } + glEnd(); +#endif + } + glPopMatrix(); +} + +void renderRedBox(float x, float y, float z, float width, float height, float length) +{ + static float dt = 0; + dt += 10.6f; + glRotatef(dt, 1,1,1); + x = x - width / 2; + y = y - height / 2; + z = z - length / 2; +#ifdef HAVE_GLES +//*SEB* *TODO* +#else + glBegin(GL_QUADS); + glColor3f(1,0,0); + glVertex3f(x, y, z); + glVertex3f(x, y + height, z); + glVertex3f(x + width, y + height, z); + glVertex3f(x + width, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x, y + height, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y, z + length); + glVertex3f(x, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x + width, y, z + length); + glVertex3f(x + width, y, z); + glVertex3f(x, y + height, z); + glVertex3f(x, y + height, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y + height, z); + glVertex3f(x, y, z); + glVertex3f(x, y, z + length); + glVertex3f(x, y + height, z + length); + glVertex3f(x, y + height, z); + glVertex3f(x + width, y, z); + glVertex3f(x + width, y, z + length); + glVertex3f(x + width, y + height, z + length); + glVertex3f(x + width, y + height, z); + glColor3f(1,1,1); + glEnd(); +#endif +} + +//----------------------------------------------------------------------------- +// ProcessDisplayList +//----------------------------------------------------------------------------- +void GraphicsPlugin::processDisplayList() +{ + if ( (m_numDListProcessed == 1 && m_romDetector->getClearType() == CT_AFTER_ONE_DISPLAY_LIST) || + (m_numDListProcessed == 2 && m_romDetector->getClearType() == CT_AFTER_TWO_DISPLAY_LIST) || + (m_numDListProcessed == 3 && m_romDetector->getClearType() == CT_AFTER_THREE_DISPLAY_LIST) ) + { + bool scissors = OpenGLManager::getSingleton().getScissorEnabled(); + OpenGLManager::getSingleton().setScissorEnabled(false); + glClear(GL_COLOR_BUFFER_BIT); + m_numDListProcessed = 0; + OpenGLManager::getSingleton().setScissorEnabled(scissors); + } + + //Update Config? + if ( m_updateConfig ) + { + m_vi->calcSize(m_graphicsInfo); + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + OpenGLManager::getSingleton().setViewport(0, 0, m_config->windowWidth, m_config->windowHeight); + m_openGLMgr.setWireFrame( m_config->wireframe ); + _setTextureCacheSize( m_config->textureCacheSize ); + m_updateConfig = false; + + //if ( OpenGLManager::getSingleton().getFullscreen() ) + //{ + // //Initialize framebuffer + // FrameBuffer::getSingleton().dispose(); + // FrameBuffer::getSingleton().initialize(m_config->fullscreenWidth, m_config->fullscreenHeight); + //} + //else + //{ + // //Initialize framebuffer + // FrameBuffer::getSingleton().dispose(); + // FrameBuffer::getSingleton().initialize(m_config->windowWidth, m_config->windowHeight); + //} + + + } + + //Get Video Interface Size + m_vi->calcSize(m_graphicsInfo); + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); + OpenGLManager::getSingleton().setForceDisableCulling( ROMDetector::getSingleton().getDisableFaceCulling() ); + + //Render Scene + OpenGLManager::getSingleton().beginRendering(); + OpenGLManager::getSingleton().setTextureing2D(true); + glEnable(GL_DEPTH_TEST); + { + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_rsp.reset(); + m_rdp.reset(); + m_openGLMgr.setCullMode(false, true); + m_displayListParser->processDisplayList(); + } + + //Clear Screen? + m_numDListProcessed++; + + //glFlush(); +// OpenGLManager::getSingleton().endRendering(); + OpenGLManager::getSingleton().setDrawFlag(); + //Take screenshot? +} + +//----------------------------------------------------------------------------- +// Update Screen +//----------------------------------------------------------------------------- +void GraphicsPlugin::drawScreen() +{ + OpenGLManager::getSingleton().endRendering(); +} + +void GraphicsPlugin::setDrawScreenSignal() +{ + m_rdp.signalUpdate(); +} + +//----------------------------------------------------------------------------- +// Video Interface Status Changed +//----------------------------------------------------------------------------- +void GraphicsPlugin::viStatusChanged() +{ + //Get new VI Size + m_vi->calcSize( m_graphicsInfo ); + + //Re Calculate Scale + m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight()); +} + +//----------------------------------------------------------------------------- +// Toggle Fullscreen +//----------------------------------------------------------------------------- +void GraphicsPlugin::toggleFullscreen() +{ + if ( m_initialized ) + { + CoreVideo_ToggleFullScreen(); + } +} + +//----------------------------------------------------------------------------- +// Take Screenshot +//----------------------------------------------------------------------------- +void GraphicsPlugin::takeScreenshot(void *dest, int *width, int *height, int front) +{ + *width = m_config->windowWidth; + *height = m_config->windowHeight; + if (dest) + { +#ifndef HAVE_GLES + if (front) + glReadBuffer(GL_FRONT); + else + glReadBuffer(GL_BACK); +#endif + glReadPixels(0, 0, *width, *height, GL_RGB, GL_UNSIGNED_BYTE, dest); + } +} + +//----------------------------------------------------------------------------- +// Update Configuration +//----------------------------------------------------------------------------- +void GraphicsPlugin::updateConfig() +{ + m_updateConfig = true; + + //For project 64, Give config dialog time to close before continueing +#ifdef WIN32 + Sleep(300); +#endif + //Resize Window + _setWindowMode(m_config->windowWidth, m_config->windowHeight); + + //Reinitialize OpenGL + OpenGLManager::getSingleton().resize(m_config->windowWidth, m_config->windowHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate); +} + +//----------------------------------------------------------------------------- +// Set Window Mode +//----------------------------------------------------------------------------- +void GraphicsPlugin::_setWindowMode(int width, int height) +{ + if ( m_initialized ) + { + //TODO: is this function needed? + //m_windowMgr->resizeWindow(width, height); + } +} + +//----------------------------------------------------------------------------- +// Set Texture Cache Size +//----------------------------------------------------------------------------- +void GraphicsPlugin::_setTextureCacheSize(int sizeInBytes) +{ + +} diff --git a/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h new file mode 100755 index 0000000..ba2ddf0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/GraphicsPlugin.h @@ -0,0 +1,103 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef GRAPHICS_PLUGIN_H_ +#define GRAPHICS_PLUGIN_H_ + +#include "TextureCache.h" +#include "OpenGLManager.h" //Initializes OpenGL and handles OpenGL states +#include "RSP.h" +#include "RDP.h" + +//Forward declarations +//struct GFX_INFO; +class VI; +class Memory; +class DisplayListParser; +class FogManager; +class ROMDetector; +struct ConfigMap; + +//***************************************************************************** +//* Graphics Plugin +//! Main class for application +//***************************************************************************** +class GraphicsPlugin +{ +public: + + //Constructor / Destructor + GraphicsPlugin(); + ~GraphicsPlugin(); + + //Set Configuration + void setConfig(ConfigMap* config) { m_config = config; } + void updateConfig(); + + //Function called when rom will be opened + bool initialize(GFX_INFO* graphicsInfo); + + //Render + void processDisplayList(); + void drawScreen(); + void setDrawScreenSignal(); + + //Toggle Fullscreen + void toggleFullscreen(); + + //Take Screenshot + void takeScreenshot(void *dest, int *width, int *height, int front); + + //Called when the video interface has been changed + void viStatusChanged(); + + //Function called when rom will be closed + void dispose(); + +private: + + //Config Options + void _setWindowMode(int width, int height); + void _setTextureCacheSize(int sizeInBytes); + + void _motionBlur(); + +private: + + GFX_INFO* m_graphicsInfo; //!< Information about window, memory... + RSP m_rsp; //!< Reality Signal Processor, does transform, clipping, lighting, triangle setup + RDP m_rdp; //!< Reality Drawing Processor + GBI m_gbi; //!< Graphics Binary Interface, handles mapping of GBI-commands + VI* m_vi; //!< Video Interface + Memory* m_memory; //!< Handle RDRAM, Texture Memory and Segments + TextureCache m_textureCache; //!< Save used texture for reuse + ROMDetector* m_romDetector; //!< + OpenGLManager& m_openGLMgr; //!< Handles initialization of OpenGL and OpenGL states. + DisplayListParser* m_displayListParser; //!< Parses and performs instructions from emulator + ConfigMap* m_config; //!< Settings from config dialog/file + FogManager* m_fogManager; //!< Handles fog extension + bool m_updateConfig; //!< Does configuration need to be updated? + bool m_initialized; //!< Have graphics plugin been initialized? + int m_numDListProcessed; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/Memory.cpp b/source/mupen64plus-video-arachnoid/src/Memory.cpp new file mode 100755 index 0000000..f4f8002 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Memory.cpp @@ -0,0 +1,72 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "Memory.h" + +//----------------------------------------------------------------------------- +//* Static variables +//----------------------------------------------------------------------------- +unsigned long long Memory::m_TMEM[512] = {0}; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +Memory::Memory() +{ + +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +Memory::~Memory() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Saves pointers to memory areas, resets segment register, and detects +//! size of RDRAM. +//! @param RDRAM Pointer to "Rambus Dynamic Random Access Memory" +//! @param DMEM Pointer to "RSP Data Memory" +//----------------------------------------------------------------------------- +bool Memory::initialize(unsigned char* RDRAM, unsigned char* DMEM) +{ + //Save pointer to memory + m_RDRAM = RDRAM; + m_DMEM = DMEM; + + //Reset Segment + for (int i=0; i<16; ++i) + { + m_segments[i] = 0; + } + + //Reset Texture Memory + //for (int i=0; i<512; ++i) + //{ + // m_TMEM[i] = 0; + //} + + m_RDRAMSize = 0x800000; + return true; +} diff --git a/source/mupen64plus-video-arachnoid/src/Memory.h b/source/mupen64plus-video-arachnoid/src/Memory.h new file mode 100755 index 0000000..792dc0a --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/Memory.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef MEMORY_H_ +#define MEMORY_H_ + +//***************************************************************************** +//* Memory +//! Handle RDRAM, Texture Memory and Segments +//***************************************************************************** +class Memory +{ +public: + + //Constructor / Destructor + Memory(); + ~Memory(); + + //Initialize + bool initialize(unsigned char* RDRAM, unsigned char* DMEM); + + //Get RDRAM + + unsigned char* getRDRAM(int address=0) { return &m_RDRAM[address]; } + unsigned int* getRDRAMint32() { return (unsigned int*)m_RDRAM; } + unsigned int getRDRAMSize() { return m_RDRAMSize; } + + //Get DMEM + unsigned char* getDMEM(int address=0) { return &m_DMEM[address]; } + + //Get Texture memory + static unsigned long long* getTextureMemory(int address=0) { return &m_TMEM[address]; } + + //Get Segment adress + unsigned int getRDRAMAddress(unsigned int segmentAddress) + { + return (m_segments[(segmentAddress >> 24) & 0x0F] + (segmentAddress & 0x00FFFFFF)) & 0x00FFFFFF; + } + + void setSegment(unsigned int address, unsigned int value) + { + if ( address >= 16 ) { + //ERROR + return; + } + + m_segments[address] = value; + } + +private: + + unsigned char* m_RDRAM; //!< Rambus Dynamic Random Access Memory + unsigned char* m_DMEM; //!< RSP Data Memory + static unsigned long long m_TMEM[512]; //!< Texture Memory + unsigned int m_segments[16]; //!< Temporary memory for storing segment values + unsigned int m_RDRAMSize; //!< Size of RDRAM + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp new file mode 100755 index 0000000..13aa92f --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp @@ -0,0 +1,56 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "MultiTexturingExt.h" +#include "ExtensionChecker.h" + + +//Multi Texturing functions +#if !defined(GL_GLEXT_VERSION) && !defined(HAVE_GLES) +PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; +PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; +PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB; +#endif +bool g_MultiTextureARBSupport = false; + +//----------------------------------------------------------------------------- +//! Function for initializeing multitextureing extensions +//----------------------------------------------------------------------------- +bool initializeMultiTexturingExtensions() +{ + //Initialize Extentions +#ifdef HAVE_GLES + g_MultiTextureARBSupport = true; + return true; +#else + g_MultiTextureARBSupport = isExtensionSupported("GL_ARB_multitexture"); + if ( g_MultiTextureARBSupport ) + { +#ifndef GL_GLEXT_VERSION + glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress( "glActiveTextureARB" ); + glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress( "glClientActiveTextureARB" ); + glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress( "glMultiTexCoord2fARB" ); +#endif + return true; + } + return false; +#endif +} diff --git a/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h new file mode 100755 index 0000000..ba55214 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/MultiTexturingExt.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef MULTI_TEXTURING_EXTENSION_H_ +#define MULTI_TEXTURING_EXTENSION_H_ + +#include "m64p.h" +#include "OpenGL.h" + +#ifndef GL_GLEXT_VERSION + //Multi Texturing Definitions + #if !defined(GL_ARB_multitexture) && !defined(HAVE_GLES) + #define GL_TEXTURE0_ARB 0x84C0 + #define GL_TEXTURE1_ARB 0x84C1 + #define GL_TEXTURE2_ARB 0x84C2 + #define GL_TEXTURE3_ARB 0x84C3 + #define GL_TEXTURE4_ARB 0x84C4 + #define GL_TEXTURE5_ARB 0x84C5 + #define GL_TEXTURE6_ARB 0x84C6 + #define GL_TEXTURE7_ARB 0x84C7 + #define GL_TEXTURE8_ARB 0x84C8 + #define GL_TEXTURE9_ARB 0x84C9 + #define GL_TEXTURE10_ARB 0x84CA + #define GL_TEXTURE11_ARB 0x84CB + #define GL_TEXTURE12_ARB 0x84CC + #define GL_TEXTURE13_ARB 0x84CD + #define GL_TEXTURE14_ARB 0x84CE + #define GL_TEXTURE15_ARB 0x84CF + #define GL_TEXTURE16_ARB 0x84D0 + #define GL_TEXTURE17_ARB 0x84D1 + #define GL_TEXTURE18_ARB 0x84D2 + #define GL_TEXTURE19_ARB 0x84D3 + #define GL_TEXTURE20_ARB 0x84D4 + #define GL_TEXTURE21_ARB 0x84D5 + #define GL_TEXTURE22_ARB 0x84D6 + #define GL_TEXTURE23_ARB 0x84D7 + #define GL_TEXTURE24_ARB 0x84D8 + #define GL_TEXTURE25_ARB 0x84D9 + #define GL_TEXTURE26_ARB 0x84DA + #define GL_TEXTURE27_ARB 0x84DB + #define GL_TEXTURE28_ARB 0x84DC + #define GL_TEXTURE29_ARB 0x84DD + #define GL_TEXTURE30_ARB 0x84DE + #define GL_TEXTURE31_ARB 0x84DF + #define GL_ACTIVE_TEXTURE_ARB 0x84E0 + #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 + #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + #endif + + //Multitexturing Functions + #if !defined(GL_ARB_multitexture) && !defined(HAVE_GLES) + #define GL_ARB_multitexture 1 + #ifdef GL_GLEXT_PROTOTYPES + extern void APIENTRY glActiveTextureARB (GLenum); + extern void APIENTRY glClientActiveTextureARB (GLenum); + extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); + extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); + extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); + extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); + extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); + extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); + extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); + extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); + extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); + extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); + extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); + extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); + extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); + extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); + extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); + extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); + extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); + extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); + extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); + extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); + extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); + extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); + extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); + extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); + extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); + extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); + extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); + extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); + extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); + extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); + extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); + extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); + #endif /* GL_GLEXT_PROTOTYPES */ + typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); + typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); + typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); + typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); + typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + + extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; + extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; + extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB; + #endif +#endif +extern bool g_MultiTextureARBSupport; + +//Function for initializing multitexturing extensions +bool initializeMultiTexturingExtensions(); + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/N64Games.h b/source/mupen64plus-video-arachnoid/src/N64Games.h new file mode 100755 index 0000000..6e7f43e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/N64Games.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef N64_GAMES_H_ +#define N64_GAMES_H_ + +//List of N64 Games +enum N64_ROM_ID +{ + UNKNOWN_ROM, + _1080_SNOWBOARDING, + BANJO_KAZOOIE, + BANJO_TOOIE, + BOMBERMAN_64, + CONKERS_BAD_FUR_DAY, + DIDDY_KONG_RACING, + DONKEY_KONG_64, + DR_MARIO, + FIGHTERS_DESTINY, + FIGHTER_DESTINY_2, + F_ZERO_X, + GOLDEN_EYE, + LEGEND_OF_ZELDA_OCARINA_OF_TIME, + MARIO_KART_64, + PAPER_MARIO, + PERFECT_DARK, + SUPER_MARIO_64, + SUPER_SMASH_BROS, + STAR_FOX_64, + SOUTH_PARK_RALLY, + WAVE_RACE_64, + WORLD_DRIVER_CHAMPOINSHIP, + YOSHIS_STORY, +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/OpenGL.h b/source/mupen64plus-video-arachnoid/src/OpenGL.h new file mode 100755 index 0000000..7d991e1 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/OpenGL.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ +#ifndef OPENGL_H +#define OPENGL_H + +#ifndef WIN32 + #define GL_GLEXT_PROTOTYPES +#endif +#if defined(__MACOSX__) +#include +#elif defined(__MACOS__) +#include +#else +#ifdef HAVE_GLES +#include +#include "eglport.h" +#include +#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 +#endif +#endif +#ifndef WIN32 + #include +#endif + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp b/source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp new file mode 100755 index 0000000..cf434a7 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/OpenGLManager.cpp @@ -0,0 +1,349 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "OpenGLManager.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +OpenGLManager::OpenGLManager() +{ + m_forceDisableCulling = false; +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Initializes OpenGL. +// +//! @param fullscreen will render scene in fullscreen if true +//! @param width width of window or width of screen resolution +//! @param height height of window or height of screen resolution +//! @param bitDepth bitDepth to use +//! @param refreshRate refresh frequency to use +//! @param vSync limits frame rate to the monitor's refresh frequency +//! @param hideCursor hides mouse coursor if true +//----------------------------------------------------------------------------- +bool OpenGLManager::initialize(bool fullscreen, int width, int height, int bitDepth, int refreshRate, bool vSync, bool hideCursor) +{ + m_width = width; + m_height = height; + m_bitDepth = bitDepth; + m_refreshRate = refreshRate; + m_fullscreen = fullscreen; + m_renderingCallback = NULL; + //Set OpenGL Settings + setClearColor(0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + //Set render states + setCullMode(false, true); + setTextureing2D(false); + setLighting(false); + + return true; +} + +//----------------------------------------------------------------------------- +// Set Viewport +//----------------------------------------------------------------------------- +void OpenGLManager::setViewport( int x, int y, int width, int height, float zNear, float zFar ) +{ + glViewport(x, y, width, height); + + //glViewport( gSP.viewport.x * OGL.scaleX, + // (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset, + // gSP.viewport.width * OGL.scaleX, + // gSP.viewport.height * OGL.scaleY + // ); + + //glDepthRange( 0.0f, 1.0f );//gSP.viewport.nearz, gSP.viewport.farz ); + glDepthRange( zNear, zFar ); +} + +//----------------------------------------------------------------------------- +//* Set Scissor +//! glScissor defines a rectangle, called the scissor box, in window coordinates. +//! Only pixels inside the box are allowed to be modified. +//! glScissor(0,0,1,1) allows modification of only the lower left pixel in the window +//! glScissor(0,0,0,0) doesn't allow modification of any pixels in the window. +//! +//! @param x,y Specify the lower left corner of the box. Defualt (0, 0). +//! @param width,height Specify the width and height of the box. +//----------------------------------------------------------------------------- +void OpenGLManager::setScissor(int x, int y, int width, int height) +{ + glScissor(x,y, width, height); +} + + +//----------------------------------------------------------------------------- +// Resize +//----------------------------------------------------------------------------- +void OpenGLManager::resize(int width, int height, int bitDepth, int refreshRate) +{ +#if 0 + dispose(); + initialize(m_fullscreen, width, height, bitDepth, refreshRate, true, false); +#endif +} + +//----------------------------------------------------------------------------- +// Toggle Fullscreen +//----------------------------------------------------------------------------- +bool OpenGLManager::toggleFullscreen() +{ +#if 0 + dispose(); + return initialize(!m_fullscreen, m_width, m_height, m_bitDepth, m_refreshRate, true, !m_fullscreen); +#endif + return false; +} + +//----------------------------------------------------------------------------- +//* Start Rendering +//! Should be called before you render everything with OpenGL +//----------------------------------------------------------------------------- +void OpenGLManager::beginRendering() +{ + glDepthMask( true ); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +} + +//----------------------------------------------------------------------------- +//* End Rendering +//! Should be called after you have rendered everything with OpenGL +//----------------------------------------------------------------------------- +void OpenGLManager::endRendering() +{ + glFinish(); + if (m_renderingCallback) + m_renderingCallback(m_drawFlag); + if (m_drawFlag) { + m_drawFlag = 0; +#ifdef HAVE_GLES + EGL_SwapBuffers(); +#else + CoreVideo_GL_SwapBuffers(); +#endif + } + //glFlush(); +} + +//----------------------------------------------------------------------------- +// Set Wireframe +//----------------------------------------------------------------------------- +void OpenGLManager::setWireFrame(bool wireframe) +{ + m_wireframe = wireframe; +#ifndef HAVE_GLES + if ( wireframe ) + { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } +#endif +} + +//----------------------------------------------------------------------------- +// Set ZBuffer Enabled +//----------------------------------------------------------------------------- +void OpenGLManager::setZBufferEnabled(bool enable) +{ + if ( enable ) + { + glEnable( GL_DEPTH_TEST ); + } + else + { + glDisable( GL_DEPTH_TEST ); + } +} + +//----------------------------------------------------------------------------- +// Get ZBuffer Enabled +//----------------------------------------------------------------------------- +bool OpenGLManager::getZBufferEnabled() +{ + return (glIsEnabled(GL_DEPTH_TEST) == GL_TRUE); +} + +//----------------------------------------------------------------------------- +// Set Lighting +//----------------------------------------------------------------------------- +void OpenGLManager::setLighting(bool lighting) +{ + m_lighting = lighting; + if ( lighting ) { + //glEnable(GL_LIGHTING); We dont use this type of lighting (Nintendo 64 specific) + } + else { + glDisable(GL_LIGHTING); + } +} + +//----------------------------------------------------------------------------- +// Get Lighting +//----------------------------------------------------------------------------- +bool OpenGLManager::getLightingEnabled() +{ + return m_lighting; + //return (glIsEnabled(GL_LIGHTING) == GL_TRUE); We dont use this type of lighting (Nintendo 64 specific) +} + +//----------------------------------------------------------------------------- +// Set Fog +//----------------------------------------------------------------------------- +void OpenGLManager::setFogEnabled(bool fog) +{ + if ( fog ) + glEnable(GL_FOG); + else + glDisable(GL_FOG); +} + +//----------------------------------------------------------------------------- +// Get Fog +//----------------------------------------------------------------------------- +bool OpenGLManager::getFogEnabled() +{ + return (glIsEnabled(GL_FOG) == GL_TRUE); +} + +//----------------------------------------------------------------------------- +// Set Texturing +//----------------------------------------------------------------------------- +void OpenGLManager::setTextureing2D(bool textureing) +{ + if ( textureing ) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); +} + +//----------------------------------------------------------------------------- +// Get Texturing +//----------------------------------------------------------------------------- +bool getTextureing2DEnabled() +{ + return (glIsEnabled(GL_TEXTURE_2D) == GL_TRUE); +} + +//----------------------------------------------------------------------------- +// Set Alpha Test Enabled +//----------------------------------------------------------------------------- +void OpenGLManager::setAlphaTest(bool alphaTestEnable) +{ + if ( alphaTestEnable ) + glEnable(GL_ALPHA_TEST); + else + glDisable(GL_ALPHA_TEST); +} + +//----------------------------------------------------------------------------- +// Get Alpha Test Enabled +//----------------------------------------------------------------------------- +bool getAlphaTestEnabled() +{ + return (glIsEnabled(GL_ALPHA_TEST) == GL_TRUE); +} + +//----------------------------------------------------------------------------- +// Scissor +//----------------------------------------------------------------------------- +void OpenGLManager::setScissorEnabled(bool enable) +{ + if ( enable ) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); +} + +bool OpenGLManager::getScissorEnabled() +{ + return (glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE); +} + +//----------------------------------------------------------------------------- +// Set Cull Mode +//----------------------------------------------------------------------------- +void OpenGLManager::setCullMode(bool cullFront, bool cullBack) +{ + if( cullFront && cullBack ) + { + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT_AND_BACK); + } + else if( cullFront ) + { + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + } + else if( cullBack ) + { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } + else + { + glDisable(GL_CULL_FACE); + } + + //Override Face Culling? + if ( m_forceDisableCulling ) + { + glDisable(GL_CULL_FACE); + } +} + +//----------------------------------------------------------------------------- +//* Dispose +//! Restores old display settings and destroys the rendering context +//----------------------------------------------------------------------------- +void OpenGLManager::dispose() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +OpenGLManager::~OpenGLManager() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//! 2D coordinats are in proportion to N64 viewport (vi), but we use +//! a viewport of another size, there for we need to scale the coordinats. +//! This function calculates that scale. +//! @param viWidth The videointerface width that defines the n64 resolution +//! @param viHeight The videointerface height that defines the n64 resolution +//----------------------------------------------------------------------------- +void OpenGLManager::calcViewScale(int viWidth, int viHeight) +{ + m_scaleX = m_width / (float)viWidth; + m_scaleY = m_height / (float)viHeight; +} diff --git a/source/mupen64plus-video-arachnoid/src/OpenGLManager.h b/source/mupen64plus-video-arachnoid/src/OpenGLManager.h new file mode 100755 index 0000000..3359cf2 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/OpenGLManager.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef OPEN_GL_Manager_H_ +#define OPEN_GL_Manager_H_ + +//OpenGL includes +#include "m64p.h" +#include "OpenGL.h" + +//***************************************************************************** +//* OpenGL Manager Class +//! Singelton class for initializing OpenGL and contolling OpenGL states. +//***************************************************************************** +class OpenGLManager +{ +public: + + //Destructor + ~OpenGLManager(); + + //Singleton Instance + static OpenGLManager& getSingleton() + { + static OpenGLManager instance; + return instance; + } + + //Functions + bool initialize(bool fullscreen, int width, int height, int bitDepth, int refreshRate, bool vSync, bool hideCursor); + void dispose(); + void resize(int width, int height, int bitDepth, int refreshRate); + bool toggleFullscreen(); + void beginRendering(); + void endRendering(); + + //Fog + void setFogEnabled(bool fog); + bool getFogEnabled(); + + //Light + void setLighting(bool lighting); + bool getLightingEnabled(); + + //Textureing + void setTextureing2D(bool textureing); + bool getTextureing2DEnabled(); + + //Depth Testing + void setZBufferEnabled(bool enable); + bool getZBufferEnabled(); + + //Alpha Test + void setAlphaTest(bool alphaTestEnable); + bool getAlphaTestEnabled(); + + //Wireframe + void setWireFrame(bool wireframe); + + //Culling + void setCullMode(bool cullFront, bool cullBack); + void setForceDisableCulling(bool force) { m_forceDisableCulling = force; } + + //Set Viewport + void setViewport(int x, int y, int width, int height, float zNear=0.0f, float zFar=1.0f); + + //Set Scissor + void setScissorEnabled(bool enable); + bool getScissorEnabled(); + void setScissor(int x, int y, int width, int height); + + //! Sets the backround color of OpenGL viewport + void setClearColor(float r, float g, float b) { glClearColor(r, g, b, 1.0f); } + + //Set callback from the M64P core + void setRenderingCallback(void(*callback)(int)) { m_renderingCallback = callback; } + + //Set draw flag for rendering callback + void setDrawFlag() { m_drawFlag = 1; } + +public: + + //N64 Specifics + void calcViewScale(int viWidth, int viHeight); + float getViewScaleX() { return m_scaleX; } + float getViewScaleY() { return m_scaleY; } + +public: + + //Gets + + int getWidth() { return m_width; } + int getHeight() { return m_height; } + bool getFullscreen() { return m_fullscreen; } + +private: + + //Constructor + OpenGLManager(); + +private: + + bool m_wireframe; //!< Wireframe mode enabled? + bool m_lighting; //!< Lighting enabled? + int m_width; //!< Display widht + int m_height; //!< Display height + int m_bitDepth; //!< Fullscreen bitdepth + int m_refreshRate; //!< Fullscreen refresh rate + float m_scaleX; //!< DisplayWidth aka WindowWidth / viWidth (n64 specific) + float m_scaleY; //!< DisplayHeight aka WindowHeight / viHeight (n64 specific) + bool m_fullscreen; //!< Fullscreen mode or window mode? + bool m_forceDisableCulling; //!< Culling cant be enabled if this is true + + void (*m_renderingCallback)(int); //Rendering callback from the core + int m_drawFlag; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp b/source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp new file mode 100755 index 0000000..e000582 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RDP/RDP.cpp @@ -0,0 +1,923 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RDP.h" +#include "GBIDefs.h" +#include "GBI.h" +#include "RSP.h" +#include "DisplayListParser.h" +#include "assembler.h" +#include "OpenGLRenderer.h" +#include "TextureCache.h" +#include "VI.h" +#include "Memory.h" +#include "OpenGLManager.h" +#include "OpenGL2DRenderer.h" +#include "AdvancedCombinerManager.h" +#include "FogManager.h" +#include "Logger.h" +#include "MathLib.h" +#include "RomDetector.h" +#include "m64p.h" +#include "OpenGL.h" +#include +using std::max; + +//----------------------------------------------------------------------------- +//! Defines +//----------------------------------------------------------------------------- +#define MI_INTR_DP 0x00000020 //!< RDP Interrupt signal + +//----------------------------------------------------------------------------- +//! Static Variables +//----------------------------------------------------------------------------- +Memory* RDP::m_memory = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +RDP::RDP() +{ + m_graphicsInfo = 0; + m_changedTiles = false; + m_textureMode = TM_NORMAL; + m_loadType = LOADTYPE_BLOCK; + m_tmemChanged = false; + m_textureLUT = 0; + m_texRectWidth = 1; + m_texRectHeight = 1; + m_displayListParser = 0; + m_primitiveZ = 0; + m_combinerMgr = 0; + m_textureLoader = 0; + m_openGL2DRenderer = 0; + m_screenUpdatePending= false; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +RDP::~RDP() +{ +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Sets pointers to managers and initializes objects +//----------------------------------------------------------------------------- +bool RDP::initialize(GFX_INFO* graphicsInfo, RSP* rsp, Memory* memory, GBI* gbi, TextureCache* textureCache, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr) +{ + //Set pointers + m_graphicsInfo = graphicsInfo; + m_rsp = rsp; + m_vi = vi; + m_memory = memory; + m_displayListParser = displayListParser; + m_textureCache = textureCache; + m_fogMgr = fogMgr; + + //Create combiner manager + m_combinerMgr = new AdvancedCombinerManager(); + m_combinerMgr->initialize(); + + //Create texture loader + m_textureLoader = new TextureLoader(); + m_textureLoader->initialize(this, m_memory); + + //Create OpenGL 2D Renderer + m_openGL2DRenderer = new OpenGL2DRenderer(); + m_openGL2DRenderer->initialize(vi); + + return true; +} + +//----------------------------------------------------------------------------- +//* Dispose +//! Delets all allocated memory +//----------------------------------------------------------------------------- +void RDP::dispose() +{ + if ( m_combinerMgr ) { delete m_combinerMgr; m_combinerMgr = 0; } + if ( m_textureLoader ) { delete m_textureLoader; m_textureLoader = 0; } + if ( m_openGL2DRenderer ) { delete m_openGL2DRenderer; m_openGL2DRenderer = 0; } +} + +//----------------------------------------------------------------------------- +//* Update States +//! Sets OpenGL states, updates combiner, activates textures, sets blender +//----------------------------------------------------------------------------- +void RDP::updateStates() +{ + //Depth Compare + if (m_otherMode.depthCompare) + glDepthFunc( GL_LEQUAL ); + else + glDepthFunc( GL_ALWAYS ); + + //Depth Update + if (m_otherMode.depthUpdate) + glDepthMask( true ); + else + glDepthMask( false ); + + // Depth Mode + if (m_otherMode.depthMode == ZMODE_DEC) + { + glEnable( GL_POLYGON_OFFSET_FILL ); + glPolygonOffset( -3.0f, -3.0f ); + } + else + { + glDisable( GL_POLYGON_OFFSET_FILL ); + } + + // Alpha Compare + if ((m_otherMode.alphaCompare == G_AC_THRESHOLD) && !(m_otherMode.alphaCvgSel)) + { + glEnable( GL_ALPHA_TEST ); + glAlphaFunc( (m_combinerMgr->getBlendColor()[3] > 0.0f) ? GL_GEQUAL : GL_GREATER, m_combinerMgr->getBlendColor()[3] ); + } + // Used in TEX_EDGE and similar render modes + else if (m_otherMode.cvgXAlpha) + { + glEnable( GL_ALPHA_TEST ); + glAlphaFunc( GL_GEQUAL, 0.5f ); // Arbitrary number -- gives nice results though + } + else + glDisable( GL_ALPHA_TEST ); + + //Combiner + if ( m_updateCombiner ) + { + if ( m_otherMode.cycleType == G_CYC_COPY) + { + m_combinerMgr->setMux(72057594037727865LL, m_otherMode.cycleType); //Only normal texturing + m_combinerMgr->selectCombine(m_otherMode.cycleType); + } + else if ( m_otherMode.cycleType == G_CYC_FILL ) + { + m_combinerMgr->setMux( 72057594037828926LL, m_otherMode.cycleType ); + m_combinerMgr->selectCombine(m_otherMode.cycleType); + } + else + { + m_combinerMgr->selectCombine(m_otherMode.cycleType); + } + m_updateCombiner = false; + m_updateCombineColors = true; + } + + if ( m_updateCombineColors ) + { + m_combinerMgr->updateCombineColors(); + m_updateCombineColors = false; + } + + //Texturing + if ( m_changedTiles || m_tmemChanged || m_rsp->getTexturesChanged() ) + { + m_combinerMgr->beginTextureUpdate(); + + //Update Texture channel 0 + if ( m_combinerMgr->getUsesTexture0() ) + { + //Enable texture 0 + m_textureCache->update(0); + m_rsp->setTexturesChanged(false); + m_changedTiles = false; + m_tmemChanged = false; + } + else + { + //Disable texture 0 + glActiveTextureARB( GL_TEXTURE0_ARB + 0 ); + glDisable(GL_TEXTURE_2D); + } + + //Update Texture channel 1 + if ( m_combinerMgr->getUsesTexture1() ) + { + //Enable texture 1 + m_textureCache->update(1); + m_rsp->setTexturesChanged(false); + m_changedTiles = false; + m_tmemChanged = false; + } + else + { + //Disable textureing 1 + glActiveTextureARB( GL_TEXTURE0_ARB + 1 ); + glDisable(GL_TEXTURE_2D); + } + + m_combinerMgr->endTextureUpdate(); + } + + // Blending + if ( (m_otherMode.forceBlender) && + (m_otherMode.cycleType != G_CYC_COPY) && + (m_otherMode.cycleType != G_CYC_FILL) && + !(m_otherMode.alphaCvgSel)) + { + glEnable( GL_BLEND ); + switch (m_otherMode.l >> 16) + { + case 0x0448: // Add + case 0x055A: + glBlendFunc( GL_ONE, GL_ONE ); + break; + case 0x0C08: // 1080 Sky + case 0x0F0A: // Used LOTS of places + glBlendFunc( GL_ONE, GL_ZERO ); + break; + case 0xC810: // Blends fog + case 0xC811: // Blends fog + case 0x0C18: // Standard interpolated blend + case 0x0C19: // Used for antialiasing + case 0x0050: // Standard interpolated blend + case 0x0055: // Used for antialiasing + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + break; + case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this? + case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right... + glBlendFunc( GL_ZERO, GL_ONE ); + break; + default: + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + break; + } + } + else + glDisable( GL_BLEND ); + + if (m_otherMode.cycleType == G_CYC_FILL) + { + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glEnable( GL_BLEND ); + } +} + +//----------------------------------------------------------------------------- +//* Reset +//! Resets all states on RDP +//----------------------------------------------------------------------------- +void RDP::reset() +{ + setTextureFiltering( G_TF_POINT ); + setRenderMode(0); +} + +//----------------------------------------------------------------------------- +//* Trigger Interrupt +//! Tell emulator that the RDP is idle +//----------------------------------------------------------------------------- +void RDP::triggerInterrupt() +{ + *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_DP; + m_graphicsInfo->CheckInterrupts(); +} + +//----------------------------------------------------------------------------- +//* Set Alpha Compare Mode +//----------------------------------------------------------------------------- +void RDP::setAlphaCompareMode(unsigned int mode) +{ + m_otherMode.alphaCompare = mode; + OpenGLManager::getSingleton().setAlphaTest( m_otherMode.alphaCompare != 0 ); +} + +//----------------------------------------------------------------------------- +//* Set Render Mode +//----------------------------------------------------------------------------- +void RDP::setRenderMode(unsigned int w1) +{ + unsigned int mode1 = (w1 & 0xCCCCFFFF); + unsigned int mode2 = (w1 & 0x3333FFFF); + + m_otherMode.l &= 0x00000007; + m_otherMode.l |= mode1 | mode2; +} + +//############################################################################# +// UCODE FUNCTIONS: +//############################################################################# + +//***************************************************************************** +// Combiner Mode +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Set Combine +//! Sets all combiner variables on combiner that tells it how to combine +//! the diffrent colors and textures. +//----------------------------------------------------------------------------- +void RDP::RDP_SetCombine(MicrocodeArgument* ucode) +{ + int mux0 = _SHIFTR( ucode->w0, 0, 24 ); + int mux1 = ucode->w1; + m_combinerMgr->setMux(mux0, mux1, (G_CYCLE_TYPE)m_otherMode.cycleType); + + m_updateCombiner = true; +} + +//***************************************************************************** +// Colors +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Set Environment Color +//! Sets Environment Color on combiner +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void RDP::RDP_SetEnvColor(float r, float g, float b, float a) +{ + m_combinerMgr->setEnvColor(r, g, b, a); + m_updateCombineColors = true; +} + +//----------------------------------------------------------------------------- +//* Set Prim Color +//! Sets Prim Color on combiner +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//! @param primLodMin +//! @param primLevel +//----------------------------------------------------------------------------- +void RDP::RDP_SetPrimColor(float r, float g, float b, float a, unsigned int primLodMin, unsigned int primLevel) +{ + int primLodFrac = max(primLevel, primLodMin); + m_combinerMgr->setPrimLodMin(primLodMin); + m_combinerMgr->setPrimLodFrac(primLodFrac / 255.0f); + m_combinerMgr->setPrimColor(r, g, b, a); + m_updateCombineColors = true; +} + +//----------------------------------------------------------------------------- +//* Set Blend Color +//! Sets Blend Color on combiner +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void RDP::RDP_SetBlendColor(float r, float g, float b, float a) +{ + m_combinerMgr->setBlendColor(r, g, b, a); + m_updateCombineColors = true; +} + +//----------------------------------------------------------------------------- +//* Set Fill Color +//! Sets Fill Color on combiner +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void RDP::RDP_SetFillColor(float r, float g, float b, float a) +{ + m_combinerMgr->setFillColor(r, g, b, a); + m_updateCombineColors = true; +} + +//----------------------------------------------------------------------------- +//* Set Fog Color +//! Sets fog color used when rendering fog +//! @param r Red component of color (0.0 - 1.0) +//! @param g Green component of color (0.0 - 1.0) +//! @param b Blue component of color (0.0 - 1.0) +//! @param a Alpha component of color (0.0 - 1.0) +//----------------------------------------------------------------------------- +void RDP::RDP_SetFogColor(float r, float g, float b, float a) +{ + m_fogMgr->setFogColor(r, g, b, a); +} + +//***************************************************************************** +// Misc +//***************************************************************************** + +//----------------------------------------------------------------------------- +//! Set Other Mode +//----------------------------------------------------------------------------- +void RDP::RDP_SetOtherMode(MicrocodeArgument* ucode) +{ + unsigned int mode0 = _SHIFTR( ucode->w0, 0, 24 ); + unsigned int mode1 = ucode->w1; + + m_otherMode.h = mode0; + m_otherMode.l = mode1; +} + +//----------------------------------------------------------------------------- +//! Set Prim Depth +//----------------------------------------------------------------------------- +void RDP::RDP_SetPrimDepth(unsigned int dwZ, unsigned int dwDZ) +{ + unsigned int primitiveDepth = dwZ & 0x7FFF; + + //Convert to float + m_primitiveZ = (float)(primitiveDepth)/(float)0x8000; + } + +//----------------------------------------------------------------------------- +//! Set Scissor +//----------------------------------------------------------------------------- +void RDP::RDP_SetScissor(int x0, int y0, int x1, int y1, int mode) +{ + //Get Scale + float vsx = OpenGLManager::getSingleton().getViewScaleX(); + float vsy = OpenGLManager::getSingleton().getViewScaleY(); + + //Get Offset + int offset = 0; //TODO: height offset? + + //Set Scissor + OpenGLManager::getSingleton().setScissor( + x0 * vsx, + (m_vi->getHeight() - y1) * vsy + offset, + (x1 - x0) * vsx, + (y1 - y0) * vsy + ); +} + +//----------------------------------------------------------------------------- +//* Set Full Sync +//! Called when RDP is finished +//----------------------------------------------------------------------------- +void RDP::RDP_FullSync() +{ + this->triggerInterrupt(); +} + +//***************************************************************************** +// Rendering +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Fill Rect +//! Renders a rectangle +//----------------------------------------------------------------------------- +void RDP::RDP_FillRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1) +{ + //Logger::getSingleton() << "RDP_FillRect: " << (int)x0 << " " << (int)y0 << " " << (int)x1 << " " << (int)y1 << "\n"; + + //Increase rectangle size? + if( m_otherMode.cycleType >= G_CYC_COPY ) + { + x1++; + y1++; + } + + //Clear Depth Buffer? + if ( m_depthImageInfo.rdramAddress == m_colorImageInfo.rdramAddress ) + { + //Clear the Z Buffer + updateStates(); + glDepthMask( true ); + glClear(GL_DEPTH_BUFFER_BIT); + + // Depth update + if (m_otherMode.depthUpdate) + { + glDepthMask(GL_TRUE); + } + else + { + glDepthMask(GL_FALSE); + } + + return; + } + + //Clear Color Buffer? + if ( m_otherMode.cycleType == G_CYC_FILL) + { + if ( x0 == 0 && y0 == 0 && x1 == m_vi->getWidth() && y1 == m_vi->getHeight() ) + { + const float* fillColor = m_combinerMgr->getFillColor(); + glClearColor(fillColor[0], fillColor[1], fillColor[2], fillColor[3]); + bool scissor = OpenGLManager::getSingleton().getScissorEnabled(); + OpenGLManager::getSingleton().setScissorEnabled(false); + glClear(GL_COLOR_BUFFER_BIT); + OpenGLManager::getSingleton().setScissorEnabled(scissor); + return; + } + } + + //Update States + this->updateStates(); + + //Ignore fill rects? + if ( ROMDetector::getSingleton().getIgnoreFillRects() ) + { + return; + } + + //Disable Scissor + glDisable( GL_SCISSOR_TEST ); + + //Set Viewport + //int oldViewport[4]; + //glGetIntegerv(GL_VIEWPORT, oldViewport); + //glViewport(0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() ); + glDepthRange(0.0f, 1.0f); + + //Get depth and color + float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0; //TODO: Use RSP viewport nearz? + float* color = m_otherMode.cycleType == G_CYC_FILL ? m_combinerMgr->getFillColor() : m_combinerMgr->getPrimColor(); + + //Render rectangle + m_openGL2DRenderer->renderQuad(color, x0, y0, x1, y1, depth); + + //Reset viewport + //glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); + + //Reset Scissor + glEnable( GL_SCISSOR_TEST ); +} + +//----------------------------------------------------------------------------- +// Texture Rectangle Flip +//----------------------------------------------------------------------------- +void RDP::RDP_TexRectFlip(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, + unsigned int tileno, unsigned int dwS, unsigned int dwT, int nDSDX, int nDTDY) +{ + Logger::getSingleton().printMsg("RDP_TexRect"); + + float fS0 = (float)dwS / 32.0f; + float fT0 = (float)dwT / 32.0f; + + float fDSDX = (float)nDSDX / 1024.0f; + float fDTDY = (float)nDTDY / 1024.0f; + + if (m_otherMode.cycleType == G_CYC_COPY) + { + fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once. + dwXH++; + dwYH++; + } + else if (m_otherMode.cycleType == G_CYC_FILL ) + { + dwXH++; + dwYH++; + } + + float fS1 = fS0 + (fDSDX * (dwYH - dwYL)); + float fT1 = fT0 + (fDTDY * (dwXH - dwXL)); + + //Set Current Texture tiles + m_rsp->setTile( m_textureLoader->getTile(tileno), 0); + if ( tileno < 7 ) + { + m_rsp->setTile( m_textureLoader->getTile(tileno + 1), 1); + } + else { + m_rsp->setTile( m_textureLoader->getTile(tileno), 1); + } + + m_texRectWidth = (unsigned int)fS1; + m_texRectHeight = (unsigned int)fT1; + + //Update States + this->updateStates(); + + float t0u0 = 0, t0v0 = 0, t0u1 =0, t0v1 = 0; + if ( m_textureCache->getCurrentTexture(0) ) + { + t0u0 = (fS0) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_textureLoader->getTile(tileno)->uls; + t0v0 = (fT0) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_textureLoader->getTile(tileno)->ult; + t0u1 = t0u0 + (fDSDX * (dwYH - dwYL))*m_textureCache->getCurrentTexture(0)->shiftScaleS; + t0v1 = t0v0 + (fDTDY * (dwXH - dwXL))*m_textureCache->getCurrentTexture(0)->shiftScaleT; + } + + _textureRectangleFlip(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno); + + //Restore RSP Tile + int rspTile = m_rsp->getTexture().tile; + m_rsp->setTile( m_textureLoader->getTile(tileno), 0); + m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1); +} + +//----------------------------------------------------------------------------- +//* Texture Rect +//! Not this command use 128bits and not 64 bits wich could cause some +//! problems with the program counter. +//----------------------------------------------------------------------------- +void RDP::RDP_TexRect(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, + unsigned int tileno, unsigned short dwS, unsigned short dwT, unsigned short nDSDX, unsigned short nDTDY) +{ + Logger::getSingleton().printMsg("RDP_TexRect"); + + glEnable(GL_TEXTURE_2D); + + //Convert to signed + short s16S = *(short*)(&dwS); + short s16T = *(short*)(&dwT); + short s16DSDX = *(short*)(&nDSDX); + short s16DTDY = *(short*)(&nDTDY); + + //Convert to float + float s = s16S / 32.0f; + float t = s16T / 32.0f; + float dsdx = s16DSDX / 1024.0f; + float dtdy = s16DTDY / 1024.0f; + + + float ulx = (float)dwXH; + float uly = (float)dwYH; + float lrx = (float)dwXL; + float lry = (float)dwYL; + + int tile = tileno; + + _textureRectangle(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy, false); +} + +//***************************************************************************** +// Texturing +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Set Color Image +//! Sets information about color image +//----------------------------------------------------------------------------- +void RDP::RDP_SetCImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress) +{ + m_colorImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress ); + m_colorImageInfo.format = format; + m_colorImageInfo.size = size; + m_colorImageInfo.width = width + 1; //Note: add plus one + m_colorImageInfo.bpl = m_colorImageInfo.width << m_colorImageInfo.size >> 1; + + if (m_screenUpdatePending) + { + OpenGLManager::getSingleton().endRendering(); + m_screenUpdatePending = false; + } +} + +//----------------------------------------------------------------------------- +//* Set Z Image +//! Sets information about depth image +//----------------------------------------------------------------------------- +void RDP::RDP_SetZImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress) +{ + m_depthImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress ); + m_depthImageInfo.format = format; + m_depthImageInfo.size = size; + m_depthImageInfo.width = width + 1; //Note: add plus one + m_depthImageInfo.bpl = m_colorImageInfo.width << m_colorImageInfo.size >> 1; +} + +//----------------------------------------------------------------------------- +//* Set Texture Image +//! Sets information about texture image +//----------------------------------------------------------------------------- +void RDP::RDP_SetTImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress) +{ + m_textureLoader->setTextureImage(format, size, width, segmentAddress); +} + +//----------------------------------------------------------------------------- +// Set Tile +//----------------------------------------------------------------------------- +void RDP::RDP_SetTile(int format, int size, int line, int tmem, int tile, + int palette, int clampS, int clampT, int mirrorS, + int mirrorT, int maskS, int maskT, int shiftS, int shiftT ) +{ + //Set Tile + m_textureLoader->setTile( format, size, line, tmem, tile, palette, + clampS, clampT, mirrorS, mirrorT, maskS, maskT, + shiftS, shiftT ); + + //m_changedTiles = true; ??? Not needed? +} + +//----------------------------------------------------------------------------- +//* Load Tile +//----------------------------------------------------------------------------- +void RDP::RDP_LoadTile(int tile, int s0, int t0, int s1, int t1) +{ + //Load Tile + m_textureLoader->loadTile(tile, s0, t0, s1, t1); + + m_textureMode = TM_NORMAL; + m_loadType = LOADTYPE_TILE; + m_tmemChanged = true; +} + +//----------------------------------------------------------------------------- +// Load Block +//----------------------------------------------------------------------------- +void RDP::RDP_LoadBlock(int tile, int s0, int t0, int s1, int t1) +{ + //Load Block + m_textureLoader->loadBlock(tile, s0, t0, s1, t1); + + m_textureMode = TM_NORMAL; + m_loadType = LOADTYPE_BLOCK; + m_tmemChanged = true; +} + +//----------------------------------------------------------------------------- +//! Sets the size of tile +//! @Param tile Index of the tile to set size on +//! @param s0 Texture Coordinats for first vertex coordinate +//! @param t0 Texture Coordinats for first vertex coordinate +//! @param s1 Texture Coordinats for second vertex coordinate +//! @param t1 Texture Coordinats for second vertex coordinate +//----------------------------------------------------------------------------- +void RDP::RDP_SetTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1) +{ + m_textureLoader->setTileSize( tile, s0, t0, s1, t1); + + m_changedTiles = true; +} + +//----------------------------------------------------------------------------- +// Load Texture Look Up Table +//----------------------------------------------------------------------------- +void RDP::RDP_LoadTLUT(int tile, int s0, int t0, int s1, int t1) +{ + m_textureLoader->loadTLUT(tile, s0, t0, s1, t1); + + m_tmemChanged = true; +} + +//***************************************************************************** +// Private Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Texture Rectangle +//----------------------------------------------------------------------------- +void RDP::_textureRectangle(float ulx, float uly, float lrx, float lry, int tile, float s, float t, float dsdx, float dtdy,bool flip) +{ + bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled(); + OpenGLManager::getSingleton().setZBufferEnabled(false); + + //Copy Mode + if ( m_otherMode.cycleType == G_CYC_COPY ) + { + dsdx = 1.0; + lrx += 1.0f; + lry += 1.0f; + } + else if (m_otherMode.cycleType == G_CYC_FILL ) + { + lrx++; + lry++; + } + + //Set Current Texture tiles + m_rsp->setTile( m_textureLoader->getTile(tile), 0); + m_rsp->setTile( m_textureLoader->getTile(tile < 7 ? tile + 1 : tile), 1); + + + float lrs = s + (lrx - ulx - 1) * dsdx; + float lrt = t + (lry - uly - 1) * dtdy; + + //Change mode to texture rectangle + if ( m_textureMode == TM_NORMAL ) + m_textureMode = TM_TEXRECT; + + m_texRectWidth = (unsigned int)(max( lrs, s ) + dsdx); + m_texRectHeight = (unsigned int)(max( lrt, t ) + dtdy); + + //Update States + this->updateStates(); + + //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() ); + + glDisable(GL_SCISSOR_TEST); + + if (lrs > s) + { + if (lrt > t) + OpenGLRenderer::getSingleton().renderTexRect( ulx, uly, lrx, lry, s, t, lrs, lrt, flip ); + else + OpenGLRenderer::getSingleton().renderTexRect( ulx, lry, lrx, uly, s, lrt, lrs, t, flip ); + } + else + { + if (lrt > t) + OpenGLRenderer::getSingleton().renderTexRect( lrx, uly, ulx, lry, lrs, t, s, lrt, flip ); + else + OpenGLRenderer::getSingleton().renderTexRect( lrx, lry, ulx, uly, lrs, lrt, s, t, flip ); + } + + //Restore RSP Tile + int rspTile = m_rsp->getTexture().tile; + m_rsp->setTile( m_textureLoader->getTile( rspTile ), 0); + m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1); + + //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() ); + + glEnable(GL_SCISSOR_TEST); + OpenGLManager::getSingleton().setZBufferEnabled(zEnabled); +} + +//----------------------------------------------------------------------------- +//* Texture Rectangle Flip +//! @todo: Clamp Tile +//----------------------------------------------------------------------------- +void RDP::_textureRectangleFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1, int tile) +{ + //Disable z buffer + bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled(); + OpenGLManager::getSingleton().setZBufferEnabled(false); + + float widthDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getWidth(); + float heightDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getHeight(); + + float t0u0 = fS0 / widthDiv; + float t0v0 = fT0 / heightDiv; + float t0u1 = (fS1 - fS0)/ widthDiv + t0u0; + float t0v1 = (fT1 - fT0)/ heightDiv + t0v0; + + float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0; //TODO: Use RSP viewport nearz? + + static bool warned = false; + if( t0u0 >= 0 && t0u1 <= 1 && t0u1 >= t0u0 ) + { + //TODO: Clamp Tile + if (!warned) + { + warned = true; + Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING); + } + } + if( t0v0 >= 0 && t0v1 <= 1 && t0v1 >= t0v0 ) + { + //TODO: Clamp tile + if (!warned) + { + warned = true; + Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING); + } + } + + //HACK + if ( ROMDetector::getSingleton().getRomID() == SUPER_MARIO_64 ) + { + t0u0 *= 0.5f; + t0v0 *= 0.5f; + t0u1 *= 0.5f; + t0v1 *= 0.5f; + } + + //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() ); + + //Get Color + float color[4] = { 1,1,1,0 }; + this->getCombinerMgr()->getCombinerColor( &color[0] ); + float secondaryColor[4] = { 1,1,1,1 }; + + if ( m_otherMode.cycleType == G_CYC_COPY ) + { + glActiveTextureARB( GL_TEXTURE0_ARB ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + } + + //Disable Scissor + glDisable( GL_SCISSOR_TEST ); + + //Render Quad + m_openGL2DRenderer->renderFlippedTexturedQuad( color, secondaryColor, + (float)nX0, (float)nY0, + (float)nX1, (float)nY1, + depth, + t0u0, t0v0, + t0u1, t0v1, + t0u0, t0v0, + t0u1, t0v1 ); + + //Restore states + glEnable(GL_SCISSOR_TEST); + OpenGLManager::getSingleton().setZBufferEnabled(zEnabled); +} diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDP.h b/source/mupen64plus-video-arachnoid/src/RDP/RDP.h new file mode 100755 index 0000000..c203eea --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RDP/RDP.h @@ -0,0 +1,290 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef REALITY_DRAWING_PROCESSOR_H_ +#define REALITY_DRAWING_PROCESSOR_H_ + +//Includes +#define M64P_PLUGIN_PROTOTYPES 1 +#include "m64p_plugin.h" +#include "UCodeDefs.h" +#include "GBI.h" +#include "GBIDefs.h" +#include "TextureLoader.h" + +//Forward declaration +class RSP; +class VI; +class Memory; +class DisplayListParser; +class TextureCache; +class AdvancedCombinerManager; +class FogManager; +class TextureLoader; +class OpenGL2DRenderer; + +//***************************************************************************** +//! RDPSetImgInfo +//! Used by RDP to set color- and depth- image info +//***************************************************************************** +struct RDPSetImgInfo +{ + unsigned int format; + unsigned int size; + unsigned int width; + unsigned int rdramAddress; + unsigned int bpl; +}; + +//***************************************************************************** +//* OtherMode +//! Struct used to get input to combiner +//***************************************************************************** +union OtherMode +{ + struct + { + //Low 32: + unsigned int alphaCompare : 2; + unsigned int depthSource : 1; + + //RenderMode + unsigned int AAEnable : 1; + unsigned int depthCompare : 1; + unsigned int depthUpdate : 1; + unsigned int imageRead : 1; + unsigned int clearOnCvg : 1; + unsigned int cvgDest : 2; + unsigned int depthMode : 2; + unsigned int cvgXAlpha : 1; + unsigned int alphaCvgSel : 1; + unsigned int forceBlender : 1; + unsigned int textureEdge : 1; + + //Blender + unsigned int c2_m2b : 2; + unsigned int c1_m2b : 2; + unsigned int c2_m2a : 2; + unsigned int c1_m2a : 2; + unsigned int c2_m1b : 2; + unsigned int c1_m1b : 2; + unsigned int c2_m1a : 2; + unsigned int c1_m1a : 2; + + // High 32: + unsigned int blendMask : 4; + unsigned int alphaDither : 2; + unsigned int colorDither : 2; + unsigned int combineKey : 1; + unsigned int textureConvert : 3; + unsigned int textureFilter : 2; + unsigned int textureLUT : 2; + unsigned int textureLOD : 1; + unsigned int textureDetail : 2; + unsigned int texturePersp : 1; + unsigned int cycleType : 2; + unsigned int unusedColorDither : 1; // unsupported + unsigned int pipelineMode : 1; + unsigned int pad : 8; + }; + + struct + { + unsigned int l, h; //!< Low and high values + }; +}; + +//***************************************************************************** +//* RDP +//! Class for emulating the Reality Drawing Processor +//***************************************************************************** +class RDP +{ +public: + + //Constructor / Destructor + RDP(); + ~RDP(); + + //initialize + bool initialize(GFX_INFO* graphicsInfo, RSP* rsp, Memory* memory, GBI* gbi, TextureCache* textureCache, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr); + void updateStates(); + void dispose(); + void reset(); + void triggerInterrupt(); + +public: + void signalUpdate() { m_screenUpdatePending = true; } + + //Get Combiner Manager + AdvancedCombinerManager* getCombinerMgr() { return m_combinerMgr; } + + //Set/Get Cycle Type + void setCycleType(unsigned int cycleType) { m_otherMode.cycleType = cycleType; m_updateCombiner = true; } + unsigned int getCycleType() { return m_otherMode.cycleType; } + + //Set Texture LUT + void setTextureLUT(unsigned int lut) { m_textureLUT = lut; } + unsigned int getTextureLUT() { return m_textureLUT; } + + //Set/Get Texture Filtering + void setTextureFiltering(unsigned int filterMode) { m_otherMode.textureFilter = filterMode; } + unsigned int getTextureFiltering() { return m_otherMode.textureFilter; } + + // Set / Get Alpha Compare + void setAlphaCompareMode(unsigned int mode); + unsigned int getAlphaCompareMode() { return m_otherMode.alphaCompare; } + + // Set Rendermode + void setRenderMode(unsigned int w1); + + //Get Textures, Tiles + TextureImage* getTextureImage() { return m_textureLoader->getTextureImage(); } + RDPTile* getCurrentTile() { return m_textureLoader->getCurrentTile(); } + RDPTile* getTile(unsigned int tile) { return m_textureLoader->getTile(tile); } + + //Get texture modes + TextureMode getTextureMode() { return m_textureMode; } + LoadType getLoadType() { return m_loadType; } + bool getChangedTiles() { return m_changedTiles; } + bool getChangedTMEM() { return m_tmemChanged; } + + //Texture rectangle Size + unsigned int getTexRectWidth() { return m_texRectWidth; } + unsigned int getTexRectHeight() { return m_texRectHeight; } + + //Half + void setHalf1(unsigned int half1) { m_half1 = half1; } + void setHalf2(unsigned int half2) { m_half2 = half2; } + unsigned int getHalf1() { return m_half1; } + unsigned int getHalf2() { return m_half2; } + + //Get Primitive Depth + float getPrimitiveZ() { return m_primitiveZ; } + + //Depth Source (get z value from prim depth?) + void setDepthSource(unsigned int source) { m_otherMode.depthSource = source; } + unsigned int getDepthSource() { return m_otherMode.depthSource; } + + void setUpdateCombiner(bool update) { m_updateCombiner = update; } + +public: + + //Texture Rectangle + void _textureRectangle(float ulx, float uly, float lrx, float lry, int tile, float s, float t, float dsdx, float dtdy,bool flip); + void _textureRectangleFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1, int tile); + +public: + + //Texturing + void RDP_SetCImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress); + void RDP_SetZImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress); + void RDP_SetTImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress); + void RDP_SetTile(int format, int size, int line, int tmem, int tile, int palette, + int clampS, int clampT, int mirrorS, int mirrorT, int maskS, + int maskT, int shiftS, int shiftT); + void RDP_SetTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1); + void RDP_LoadTile(int tile, int s0, int t0, int s1, int t1); + void RDP_LoadBlock(int tile, int s0, int t0, int s1, int t1); + void RDP_LoadTLUT(int tile, int s0, int t0, int s1, int t1); + + //Colors + void RDP_SetEnvColor(float r, float g, float b, float a); + void RDP_SetFogColor(float r, float g, float b, float a); + void RDP_SetBlendColor(float r, float g, float b, float a); + void RDP_SetPrimColor(float r, float g, float b, float a, unsigned int primLodMin, unsigned int primLevel); + void RDP_SetFillColor(float r, float g, float b, float a); + + //Combiner + void RDP_SetCombine(MicrocodeArgument* ucode); + + //Misc + void RDP_SetOtherMode(MicrocodeArgument* ucode); + void RDP_SetPrimDepth(unsigned int dwZ, unsigned int dwDZ); + void RDP_SetScissor(int x0, int y0, int x1, int y1, int mode); + + //Rendering + void RDP_FillRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1); + void RDP_TexRectFlip(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, + unsigned int tileno, unsigned int dwS, unsigned int dwT, int nDSDX, int nDTDY); + void RDP_TexRect(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL, + unsigned int tileno, unsigned short dwS, unsigned short dwT, unsigned short nDSDX, unsigned short nDTDY); + + //Other + void RDP_FullSync(); + +public: + + static Memory* m_memory; //!< Pointer to memory manager + +public: + + //Other Mode + OtherMode m_otherMode; //!< Lots of states for graphics and combiner + + //Hash values for paletts + unsigned int m_paletteCRC16[16]; //!< Hash values used to select correct texture + unsigned int m_paletteCRC256; //!< Hash values used to select correct texture + +protected: + + //Pointers to other objects and managers + GFX_INFO* m_graphicsInfo; //!< Access to emulator data (like RDRAM ...) + RSP* m_rsp; //!< Pointer to Reality Signal Processor + VI* m_vi; //!< Pointer to video interface + DisplayListParser* m_displayListParser; //!< Pointer to display list parser + TextureCache* m_textureCache; //!< Pointer to texture cache + FogManager* m_fogMgr; //!< Pointer to fog manager + AdvancedCombinerManager* m_combinerMgr; //!< Pointer to combiner manager + TextureLoader* m_textureLoader; //!< Pointer to texture loader + OpenGL2DRenderer* m_openGL2DRenderer; //!< Pointer to OpenGL 2D Renderer + + //Prim Depth + float m_primitiveZ; //!< Z value assigned to vertices z value if depth source says so + float m_primitiveDeltaZ; //!< ??? Unused by this plugin + + //Update? + bool m_updateCombiner; //!< Update combiner? + bool m_updateCombineColors; //!< Update colors combiner uses? + bool m_tmemChanged; //!< True when texture memory has been altered + bool m_changedTiles; //!< True if tiles have been changed + + //Textures + LoadType m_loadType; //!< What kind of texture was previusly loaded + TextureMode m_textureMode; //!< Texture mode (NORMAL, TEXRECT, BACKGROUND, FRAMEBUFFER) + unsigned int m_textureLUT; //!< Texture Look Up Table + unsigned int m_texRectWidth; //!< Width of the texture rectangle to be rendered + unsigned int m_texRectHeight; //!< Height of the texture rectangle to be rendered + + //Images + RDPSetImgInfo m_colorImageInfo; //!< Information about color image + RDPSetImgInfo m_depthImageInfo; //!< Information about depth image + + //Half + unsigned int m_half1; //!< First half value + unsigned int m_half2; //!< Second half value + + //Update on first CI + bool m_screenUpdatePending; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp new file mode 100755 index 0000000..fc4766a --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp @@ -0,0 +1,481 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RDPInstructions.h" +#include "RDPUCodeStructs.h" +#include "RDP.h" +#include "DisplayListParser.h" +#include "Logger.h" + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- + +RDP* RDPInstructions::m_rdp = 0; +DisplayListParser* RDPInstructions::m_displayListParser = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +RDPInstructions::RDPInstructions() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +RDPInstructions::~RDPInstructions() +{ +} + +//----------------------------------------------------------------------------- +//* Initialize +//----------------------------------------------------------------------------- +bool RDPInstructions::initialize(RDP* rdp, DisplayListParser* displayListParser) +{ + m_rdp = rdp; + m_displayListParser = displayListParser; + return true; +} + +//----------------------------------------------------------------------------- +//! Set Color Image +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetCImg(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetCImg"); + RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode; + + //Set Color Image + m_rdp->RDP_SetCImg(temp->format, temp->size, temp->width, temp->segmentAddress); +} + +//----------------------------------------------------------------------------- +//! Set Z Image +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetZImg(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetZImg"); + RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode; + + //Set Depth Image + m_rdp->RDP_SetZImg(temp->format, temp->size, temp->width, temp->segmentAddress); +} + +//----------------------------------------------------------------------------- +//! Set Texture Image +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetTImg(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetTImg"); + RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode; + + //Set Texture Image + m_rdp->RDP_SetTImg(temp->format, temp->size, temp->width, temp->segmentAddress); +} + +//----------------------------------------------------------------------------- +//! Set Tile +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetTile(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetTile"); + RDPUCodeSetTile* temp = (RDPUCodeSetTile*)ucode; + + //Set Tile + m_rdp->RDP_SetTile( temp->format, temp->size, temp->line, temp->tmem, temp->tile, + temp->palette, temp->clampS, temp->clampT, temp->mirrorS, temp->mirrorT, + temp->maskS, temp->maskT, temp->shiftS, temp->shiftT + ); +} + +//----------------------------------------------------------------------------- +//! Load Tile +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_LoadTile(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_LoadTile"); + RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode; + + //Load Tile + m_rdp->RDP_LoadTile(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1); +} + +//----------------------------------------------------------------------------- +//! Load Block +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_LoadBlock(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_LoadBlock"); + RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode; + + //Load Block + m_rdp->RDP_LoadBlock(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1); +} + +//----------------------------------------------------------------------------- +//! Sets the size of tile +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetTileSize(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetTileSize"); + RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode; + + //Set Tile Size + m_rdp->RDP_SetTileSize(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1); +} + +//----------------------------------------------------------------------------- +//! Set Texture Look Up Table +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_LoadTLUT(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_LoadTLUT"); + RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode; + + //Load Texture Look Up Table + m_rdp->RDP_LoadTLUT(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1); +} + +//----------------------------------------------------------------------------- +//* Fill Rect +//! Renders a rectangle +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_FillRect(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_FillRect"); + RDPUCodeRectangle* temp = (RDPUCodeRectangle*)ucode; + + //Render a Rectangle + m_rdp->RDP_FillRect(temp->x0, temp->y0, temp->x1, temp->y1); +} + +//----------------------------------------------------------------------------- +//* Texture Rectangle Flipped +//! Renders a textured rectangle +//! @todo Better extraction of data +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_TexRectFlip(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_TexRectFlip"); + RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode; + + //Get Extra Words + unsigned int w2 = m_displayListParser->getNextWord(); + unsigned int w3 = m_displayListParser->getNextWord(); + + //Extract Data + unsigned int dwS = ( w2>>16)&0xFFFF; + unsigned int dwT = ( w2 )&0xFFFF; + int nDSDX = (int)(short)(( w3>>16)&0xFFFF); + int nDTDY = (int)(short)(( w3 )&0xFFFF); + + //Render Texture Rectangle Flipped + m_rdp->RDP_TexRectFlip(temp->x1 / 4, temp->y1 / 4, + temp->x0 / 4, temp->y0 / 4, + temp->tile, + dwS, dwT, + nDSDX, nDTDY); +} + +//----------------------------------------------------------------------------- +//* Texture Rect +//! Not this command use 128bits and not 64 bits wich could cause some +//! problems with the program counter. +//! @todo Better extraction of data +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_TexRect(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_TexRect"); + RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode; + + unsigned int w2 = m_displayListParser->getNextWord(); + unsigned int w3 = m_displayListParser->getNextWord(); + + //Extract Data + unsigned short uS = (unsigned short)( w2>>16)&0xFFFF; + unsigned short uT = (unsigned short)( w2 )&0xFFFF; + unsigned short uDSDX = (unsigned short)(( w3>>16)&0xFFFF); + unsigned short uDTDY = (unsigned short)(( w3 )&0xFFFF); + + //Render Texture Rectangle + m_rdp->RDP_TexRect( temp->x0 / 4, temp->y0 / 4, + temp->x1 / 4, temp->y1 / 4, + temp->tile, + uS, uT, + uDSDX, uDTDY); +} + +//----------------------------------------------------------------------------- +//! Set Enviroment Color +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetEnvColor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetEnvColor"); + RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode; + + //Set enviorment color + m_rdp->RDP_SetEnvColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f); +} + +//----------------------------------------------------------------------------- +//! Set Blend Color +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetBlendColor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetBlendColor"); + RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode; + + //Set blend color + m_rdp->RDP_SetBlendColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f); +} + +//----------------------------------------------------------------------------- +//! Set Prim Color +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetPrimColor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetPrimColor"); + RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode; + + //Set primitive color + m_rdp->RDP_SetPrimColor( temp->r / 255.0f, //red + temp->g / 255.0f, //green + temp->b / 255.0f, //blue + temp->a / 255.0f, //alpha + temp->prim_min_level, + temp->prim_level ); +} + +//----------------------------------------------------------------------------- +//! Set Fog Color +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetFogColor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDPInstructions_SetFogColor"); + RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode; + + //Set fog color + m_rdp->RDP_SetFogColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f); +} + +//----------------------------------------------------------------------------- +//! Set Fill Color +//! Note: Fill color is stored diffrently from the other types of colors +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetFillColor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetFillColor"); + RDPUCodeSetFillColor* temp = (RDPUCodeSetFillColor*)ucode; + + //Set fill color (Note: alpha is 0.0 or 1.0) FIXME: 32 or 31? 31 seems to work better with Super Mario 64 + m_rdp->RDP_SetFillColor(temp->r / 31.0f, temp->g / 31.0f, temp->b / 31.0f, (float)temp->a); +} + +//----------------------------------------------------------------------------- +//! Set Combine +//! @todo Extract data +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetCombine(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetCombine"); + m_rdp->RDP_SetCombine(ucode); +} + +//----------------------------------------------------------------------------- +//! Set Other Mode +//! @todo Extract data +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetOtherMode(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetOtherMode"); + m_rdp->RDP_SetOtherMode(ucode); +} + +//----------------------------------------------------------------------------- +//! Set Prim Depth +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetPrimDepth(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetPrimDepth"); + RDPUCodeSetPrimDepth* temp = (RDPUCodeSetPrimDepth*)ucode; + + //Set Prim Depth + m_rdp->RDP_SetPrimDepth(temp->z, temp->dz); +} + +//----------------------------------------------------------------------------- +//! Set Scissor +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetScissor(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetScissor"); + RDPUCodeScissor* temp = (RDPUCodeScissor*)ucode; + + //Set Scissor + m_rdp->RDP_SetScissor(temp->x0 / 4, temp->y0 / 4, temp->x1 / 4, temp->y1 / 4, temp->mode); +} + +//----------------------------------------------------------------------------- +//* Full Sync +//! Function that signals end of a frame. +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_FullSync(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_FullSync"); + m_rdp->RDP_FullSync(); +} + +//----------------------------------------------------------------------------- +//* Tile Sync +//! Ignored (Function that signals synchronize of texture tile change) +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_TileSync(MicrocodeArgument* ucode) +{ + //Ignore + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_TileSync - Ignored", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Pipe Sync +//! Ignored (Function that signals synchronize of RDP attribute change) +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_PipeSync(MicrocodeArgument* ucode) +{ + //Ignore + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_PipeSync - Ignored", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Load Sync +//! Ignored (Function that signals synchronize of textureloading Ignored) +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_LoadSync(MicrocodeArgument* ucode) +{ + //Ignored + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_LoadSync - Ignored", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Set Convert +//! Unimplemented +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetConvert(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_SetConvert - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Set Key Red +//! Unimplemented +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetKeyR(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("RDP_SetKeyR"); + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_SetKeyR - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Set Key Green Blue +//! Unimplemented +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_SetKeyGB(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_SetKeyGB - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* Unknown +//! This function gets called when the GBI recives an unknown instruction. +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_Unknown(MicrocodeArgument* ucode) +{ + //Ignore + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_Unknown - Ignored", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//* No Operation +//! Do nothing +//----------------------------------------------------------------------------- +void RDPInstructions::RDP_NoOp(MicrocodeArgument* ucode) +{ + //Ignore + + static bool warned = false; + if ( warned ) { + Logger::getSingleton().printMsg("RDP_NoOp - Ignored", M64MSG_WARNING); + warned = true; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h new file mode 100755 index 0000000..708edab --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef RDP_INSTRUCTIONS_H_ +#define RDP_INSTRUCTIONS_H_ + +#include "UCodeDefs.h" + +//Forward declarations +class RDP; +class DisplayListParser; + +//***************************************************************************** +//* RDP Instructions +//! Class for reciveing RDP instructions, and forward them to the RDP +//***************************************************************************** +class RDPInstructions +{ +public: + + //Constructor / Destructor + RDPInstructions(); + ~RDPInstructions(); + + //Initialize + bool initialize(RDP* rdp, DisplayListParser* displayListParser); + + //Texturing + static void RDP_SetCImg(MicrocodeArgument* ucode); + static void RDP_SetZImg(MicrocodeArgument* ucode); + static void RDP_SetTImg(MicrocodeArgument* ucode); + static void RDP_SetTile(MicrocodeArgument* ucode); + static void RDP_SetTileSize(MicrocodeArgument* ucode); + static void RDP_LoadTile(MicrocodeArgument* ucode); + static void RDP_LoadBlock(MicrocodeArgument* ucode); + static void RDP_LoadTLUT(MicrocodeArgument* ucode); + + //Rendering + static void RDP_TexRectFlip(MicrocodeArgument* ucode); + static void RDP_TexRect(MicrocodeArgument* ucode); + static void RDP_FillRect(MicrocodeArgument* ucode); + + //Colors + static void RDP_SetEnvColor(MicrocodeArgument* ucode); + static void RDP_SetPrimColor(MicrocodeArgument* ucode); + static void RDP_SetBlendColor(MicrocodeArgument* ucode); + static void RDP_SetFogColor(MicrocodeArgument* ucode); + static void RDP_SetFillColor(MicrocodeArgument* ucode); + + //Combiner + static void RDP_SetCombine(MicrocodeArgument* ucode); + + //Misc + static void RDP_SetOtherMode(MicrocodeArgument* ucode); + static void RDP_SetPrimDepth(MicrocodeArgument* ucode); + static void RDP_SetScissor(MicrocodeArgument* ucode); + + //Sync + static void RDP_FullSync(MicrocodeArgument* ucode); + + //Unimportant + static void RDP_TileSync(MicrocodeArgument* ucode); + static void RDP_PipeSync(MicrocodeArgument* ucode); + static void RDP_LoadSync(MicrocodeArgument* ucode); + static void RDP_SetConvert(MicrocodeArgument* ucode); + static void RDP_SetKeyR(MicrocodeArgument* ucode); + static void RDP_SetKeyGB(MicrocodeArgument* ucode); + static void RDP_Unknown(MicrocodeArgument* ucode); + static void RDP_NoOp(MicrocodeArgument* ucode); + +private: + + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static DisplayListParser* m_displayListParser; //!< Pointer to displaylist parser + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h b/source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h new file mode 100755 index 0000000..d67f71c --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h @@ -0,0 +1,147 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef RDP_UCODE_DEFS_H_ +#define RDP_UCODE_DEFS_H_ + +//! Struct for setting color-, depth- and texture- image +struct RDPUCodeSetImage +{ + unsigned int width:12; //!< Width + unsigned int :7; //!< Padding + unsigned int size:2; //!< Size (0=4, 1=8, 2=16, or 3=32) + unsigned int format:3; //!< Image format (0=RGBA, 1=YUV, 2=CI, 3=IA, 4=I, 5=?, 6=?, 7=?) + unsigned int cmd:8; //!< Command + unsigned int segmentAddress; //!< Address to register where there is an RDRAM address +}; + +//! Struct used by RDP to load textures +struct RDPUCodeTileSize +{ + unsigned int t0:12; //!< t texture coordinat for first vertex + unsigned int s0:12; //!< s texture coordinat for first vertex + unsigned int cmd:8; //!< Command, usualy LoadBlock, LoadTLUT, LoadTile, or SetTileSize + unsigned int t1:12; //!< t texture coordinat for second vertex + unsigned int s1:12; //!< s texture coordinat for second vertex + unsigned int tile:3; //!< Tile + unsigned int padding:5; //!< Unused Padding +}; + +//! Struct used by RDP to set tiles +struct RDPUCodeSetTile +{ + unsigned int tmem:9; //!< Address in Texture Memory + unsigned int line:9; + unsigned int pad0:1; //!< Padding + unsigned int size:2; + unsigned int format:3; //!< Image format of tile + unsigned int cmd:8; //!< Command, usualy SetTileSize + unsigned int shiftS:4; + unsigned int maskS:4; + unsigned int mirrorS:1; //!< + unsigned int clampS:1; + unsigned int shiftT:4; + unsigned int maskT:4; + unsigned int mirrorT:1; + unsigned int clampT:1; + unsigned int palette:4; + unsigned int tile:3; + unsigned int pad1:5; //!< Padding +}; + +//! Struct used by RDP to set fog-, blend-, enviroment-, and prim- color (fillcolor is diffrent) +struct RDPUCodeSetColor +{ + unsigned int prim_level:8; //!< Only used by setPrimColor + unsigned int prim_min_level:8; //!< Only used by setPrimColor + unsigned int pad0:8; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int a:8; //!< Alpha (0-255) + unsigned int b:8; //!< Blue (0-255) + unsigned int g:8; //!< Green (0-255) + unsigned int r:8; //!< Red (0-255) +}; + +//! Struct used by RDP to set fill color +struct RDPUCodeSetFillColor +{ + unsigned int pad0:24; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int a:1; //!< Alpha (0-1) + unsigned int b:5; //!< Blue (0-255) + unsigned int g:5; //!< Green (0-255) + unsigned int r:5; //!< Red (0-255) + unsigned int pad1:16; //!< Padding +}; + +//! Struct used by RDP to render rectangles +struct RDPUCodeRectangle +{ + unsigned int pad0 : 2; //!< Padding + unsigned int y1 : 10; //!< Y coordinate of second vertex corner + unsigned int pad1 : 2; //!< Padding + unsigned int x1 : 10; //!< X coordinate of second vertex corner + unsigned int cmd : 8; //!< Command + unsigned int pad3 : 2; //!< Padding + unsigned int y0 : 10; //!< Y coordinate of first vertex corner + unsigned int pad4 : 2; //!< Padding + unsigned int x0 : 10; //!< X coordinate of first vertex corner + unsigned int pad5 : 8; //!< Padding +}; + +//! Struct used by RDP to set scissor +struct RDPUCodeScissor +{ + unsigned int y0:12; //!< Y coordinate of second vertex + unsigned int x0:12; //!< X coordinate of second vertex + unsigned int cmd:8; //!< Command usualy + unsigned int y1:12; //!< Y coordinate of first vertex + unsigned int x1:12; //!< X coordinate of first vertex + unsigned int mode:2; //!< + unsigned int pad0:6; //!< Padding TexRect or TexRectFlip +}; + +//! Struct used by RDP to render textured rectangles +struct RDPUCodeTextureRectangle +{ + unsigned int y1:12; //!< Y coordinate of second vertex + unsigned int x1:12; //!< X coordinate of second vertex + unsigned int cmd:8; //!< Command usualy + unsigned int y0:12; //!< Y coordinate of first vertex + unsigned int x0:12; //!< X coordinate of first vertex + unsigned int tile:3; //!< Tile descriptor index + unsigned int pad0:5; //!< Padding TexRect or TexRectFlip + unsigned int t:16; //!< T texture coord at first vertex + unsigned int s:16; //!< S texture coord at first vertex + unsigned int dtdy:16; //!< Change in T per change in Y + unsigned int dsdx:16; //!< Change in S per change in X +}; + +//! Struct used by RDP to set prim depth +struct RDPUCodeSetPrimDepth +{ + unsigned int pad0:24; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int dz:16; + unsigned int z:16; //!< Depth value +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp new file mode 100755 index 0000000..0d86e22 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSP.cpp @@ -0,0 +1,635 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RSP.h" +#include "../UCodeDefs.h" +#include "../RDP/RDP.h" +#include +#include "GBIDefs.h" +#include "VI.h" +#include "Memory.h" +#include "Logger.h" +#include "OpenGLRenderer.h" +#include "OpenGLManager.h" +#include "RSPLightManager.h" +#include "FogManager.h" +#include "DisplayListParser.h" +#include "MathLib.h" +#include "MathLib.h" + +#define MI_INTR_SP 0x00000001 //!< RSP Interrupt signal + +//Geometry Mode Definitions +#define G_ZBUFFER 0x00000001 +#define G_SHADE 0x00000004 +#define G_FOG 0x00010000 +#define G_LIGHTING 0x00020000 +#define G_TEXTURE_GEN 0x00040000 +#define G_TEXTURE_GEN_LINEAR 0x00080000 +#define G_LOD 0x00100000 + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +RSP::RSP() +{ + m_texturesChanged = false; + m_matrixMgr = 0; + m_vertexMgr = 0; + m_lightMgr = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +RSP::~RSP() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//* Initialize +//----------------------------------------------------------------------------- +bool RSP::initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* dlp, FogManager* fogMgr) +{ + //Save pointers + m_graphicsInfo = graphicsInfo; + m_rdp = rdp; + m_vi = vi; + m_memory = memory; + m_displayListParser = dlp; + m_fogMgr = fogMgr; + + //Initialize Matrix Manager + m_matrixMgr = new RSPMatrixManager(); + if ( !m_matrixMgr->initialize(m_memory) ) { + return false; + } + + //Initialzie Light Manager + m_lightMgr = new RSPLightManager(); + if ( !m_lightMgr->initialize(m_memory) ) { + return false; + } + + //Initialzie Vertex Manager + m_vertexMgr = new RSPVertexManager(); + if ( !m_vertexMgr->initialize(&OpenGLManager::getSingleton(), m_memory, m_matrixMgr, m_lightMgr) ) { + return false; + } + + m_textureTiles[0] = m_rdp->getTile(0); + m_textureTiles[1] = m_rdp->getTile(1); + + return true; +} + +//----------------------------------------------------------------------------- +//* Dispose +//----------------------------------------------------------------------------- +void RSP::dispose() +{ + if ( m_matrixMgr ) { delete m_matrixMgr; m_matrixMgr = 0; } + if ( m_vertexMgr ) { delete m_vertexMgr; m_vertexMgr = 0; } + if ( m_lightMgr ) { delete m_lightMgr ; m_lightMgr = 0; } +} + +//----------------------------------------------------------------------------- +//* Update Geometry States +//----------------------------------------------------------------------------- +void RSP::updateGeometryStates() +{ + bool cullFront = (m_geometryMode & GBI::G_CULL_FRONT ) != 0; + bool cullBack = (m_geometryMode & GBI::G_CULL_BACK ) != 0; + bool fog = (m_geometryMode & G_FOG ) != 0; + bool textureGen = (m_geometryMode & G_TEXTURE_GEN ) != 0; + bool lighting = (m_geometryMode & G_LIGHTING ) != 0; + bool zBuffer = (m_geometryMode & G_ZBUFFER ) != 0; + + //Update states + m_lightMgr->setLightEnabled(lighting); + m_vertexMgr->setTexCoordGenType( textureGen ? TCGT_LINEAR : TCGT_NONE); + OpenGLManager::getSingleton().setZBufferEnabled(zBuffer); + OpenGLManager::getSingleton().setCullMode(cullFront, cullBack); + OpenGLManager::getSingleton().setFogEnabled(fog); +} + +//----------------------------------------------------------------------------- +// Reset +//----------------------------------------------------------------------------- +void RSP::reset() +{ + m_matrixMgr->resetMatrices(); +} + +//----------------------------------------------------------------------------- +//* Trigger Interupt +//----------------------------------------------------------------------------- +void RSP::triggerInterrupt() +{ + *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_SP; + m_graphicsInfo->CheckInterrupts(); +} + +//----------------------------------------------------------------------------- +//* Move Segment +//----------------------------------------------------------------------------- +void RSP::moveSegment(int segmentID, int value) +{ + m_memory->setSegment(segmentID, value); +} + +//----------------------------------------------------------------------------- +// Set Viewport +// FIXME +//----------------------------------------------------------------------------- +void RSP::moveMemViewport(unsigned int segmentAddress) +{ + //Get Adress + unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress); + + //Error controll + if ( rdramAddress + 16 > m_memory->getRDRAMSize() ) + { + Logger::getSingleton().printMsg("MoveMem Viewport, accessed invalid memory", M64MSG_ERROR); + return; + } + + m_viewport.vscale[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 2), 2 ); + m_viewport.vscale[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress ), 2 ); + m_viewport.vscale[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 6), 10 );// * 0.00097847357f; + m_viewport.vscale[3] = *(short*)m_memory->getRDRAM(rdramAddress + 4); + m_viewport.vtrans[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 10), 2 ); + m_viewport.vtrans[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 8), 2 ); + m_viewport.vtrans[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 14), 10 );// * 0.00097847357f; + m_viewport.vtrans[3] = *(short*)m_memory->getRDRAM(rdramAddress + 12); + + m_viewport.x = m_viewport.vtrans[0] - m_viewport.vscale[0]; + m_viewport.y = m_viewport.vtrans[1] - m_viewport.vscale[1]; + m_viewport.width = m_viewport.vscale[0] * 2; + m_viewport.height = m_viewport.vscale[1] * 2; + m_viewport.nearz = m_viewport.vtrans[2] - m_viewport.vscale[2]; + m_viewport.farz = (m_viewport.vtrans[2] + m_viewport.vscale[2]) ; + + /* + //Set Viewport + OpenGLManager::getSingleton().setViewport( + m_viewport.x, // * OGL.scaleX, + m_viewport.y, //(VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset, + //(m_vi->getHeight() - (m_viewport.y + m_viewport.height)), + m_viewport.width, // * OGL.scaleX, + m_viewport.height, // * OGL.scaleY, + 0.0f, //m_viewport.nearz, + 1.0f ); //m_viewport.farz ); + */ +} + +//----------------------------------------------------------------------------- +//* Load UCode Ex +//! @todo Change ucode while running +//----------------------------------------------------------------------------- +void RSP::RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize ) +{ + Logger::getSingleton().printMsg("RSP_LoadUcodeEx - Unimplemented", M64MSG_WARNING); + //TODO or skip + + /* + + RSP.PCi = 0; + gSP.matrix.modelViewi = 0; + gSP.changed |= CHANGED_MATRIX; + gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0; + + if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize)) + { + return; + } + + MicrocodeInfo *ucode = GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize ); + + if (ucode->type != NONE) + GBI_MakeCurrent( ucode ); + else + SetEvent( RSP.threadMsg[RSPMSG_CLOSE] ); + */ +} + +//***************************************************************************** +// Matrix Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +// RSP Matrix +//----------------------------------------------------------------------------- +void RSP::RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace ) +{ + Logger::getSingleton().printMsg("RSP_Matrix"); + m_matrixMgr->addMatrix( segmentAddress, //Segment adress + projectionMatrix, //Projection or view matrix? + push, //Save Current Matrix? + replace ); //Replace aka Load or Mult +} + +//----------------------------------------------------------------------------- +// RSP DMA Matrix +//----------------------------------------------------------------------------- +void RSP::RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply ) +{ + m_matrixMgr->DMAMatrix(m_memory->getRDRAMAddress(matrix), index, multiply); +} + +//----------------------------------------------------------------------------- +// RSP Force Matrix +//----------------------------------------------------------------------------- +void RSP::RSP_ForceMatrix( unsigned int segmentAddress ) +{ + // Logger::getSingleton().printMsg("RSP_ForceMatrix", M64MSG_WARNING); + m_matrixMgr->ForceMatrix( m_memory->getRDRAMAddress(segmentAddress)); +} + +//----------------------------------------------------------------------------- +// Pop Matrix +//----------------------------------------------------------------------------- +void RSP::RSP_PopMatrix( ) +{ + m_matrixMgr->popMatrix(); +} + +//----------------------------------------------------------------------------- +//* Pop Matrix N +//! Pop Matrix from stack N number of times +//! @param num The number of matrices to pop from matrix-stack +//----------------------------------------------------------------------------- +void RSP::RSP_PopMatrixN( unsigned int num ) +{ + m_matrixMgr->popMatrixN(num); +} + +//----------------------------------------------------------------------------- +// Insert Matrix +//----------------------------------------------------------------------------- +void RSP::RSP_InsertMatrix(unsigned int where, unsigned int num) +{ + m_matrixMgr->insertMatrix(where, num); +} + +//***************************************************************************** +// Misc +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Fog Factor +//----------------------------------------------------------------------------- +void RSP::RSP_FogFactor(short fogMultiplier, short fogOffset) +{ + m_fogMgr->setFogSettings((float)fogMultiplier, (float)fogOffset); +} + +//----------------------------------------------------------------------------- +// Texture +//----------------------------------------------------------------------------- +void RSP::RSP_Texture( float scaleS, float scaleT, int level, int tile, int on ) +{ + //Set Texture + m_texture.scaleS = (scaleS != 0.0f) ? scaleS : 1.0f; + m_texture.scaleT = (scaleT != 0.0f) ? scaleT : 1.0f; + m_texture.level = level; + m_texture.on = on; + m_texture.tile = tile; + + //Set Tiles (note: There are max 8 tiles) + if ( tile < 7 ) + { + m_textureTiles[0] = m_rdp->getTile(tile); + m_textureTiles[1] = m_rdp->getTile(tile+1); + } + else + { + m_textureTiles[0] = m_rdp->getTile(tile); + m_textureTiles[1] = m_rdp->getTile(tile); + } + + m_texturesChanged = true; +} + +//----------------------------------------------------------------------------- +// Set DMA Offsets +//----------------------------------------------------------------------------- +void RSP::RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset ) +{ + m_matrixMgr->setRDRAMOffset(mtxoffset); + m_vertexMgr->setRDRAMOffset(vtxoffset); +} + +//***************************************************************************** +// Light +//***************************************************************************** + +//----------------------------------------------------------------------------- +// RSP Light +//----------------------------------------------------------------------------- +void RSP::RSP_Light( unsigned int lightIndex, unsigned int segmentAddress ) +{ + m_lightMgr->setLight(lightIndex, m_memory->getRDRAMAddress(segmentAddress) ); +} + +//----------------------------------------------------------------------------- +// Num Lights +//----------------------------------------------------------------------------- +void RSP::RSP_NumLights( int numLights ) +{ + m_lightMgr->setNumLights(numLights); +} + +//----------------------------------------------------------------------------- +// Light Color +//----------------------------------------------------------------------------- +void RSP::RSP_LightColor( unsigned int lightIndex, unsigned int packedColor ) +{ + m_lightMgr->setLightColor(lightIndex, packedColor); +} + +//***************************************************************************** +// Vertex +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Vertex +//----------------------------------------------------------------------------- +void RSP::RSP_Vertex( unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex ) +{ + m_vertexMgr->setVertices(m_memory->getRDRAMAddress(segmentAddress), numVertices, firstVertexIndex); +} + +//----------------------------------------------------------------------------- +// Modify Vertex +//----------------------------------------------------------------------------- +void RSP::RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val ) +{ + m_vertexMgr->modifyVertex(vtx, where, val); +} + +void RSP::RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a) +{ + m_vertexMgr->setVertexColor(vtx, r,g,b,a); +} + +void RSP::RSP_SetVertexTexCoord( unsigned int vtx, float s, float t) +{ + m_vertexMgr->setVertexTextureCoord(vtx, s,t); +} + +//----------------------------------------------------------------------------- +//! Color Index Vertex +//! param segmentAddress Address to register where there is an RDRAM address +//! used to retrieve vertices from RDRAM. +//! param numVertices Number of vertices to retrive from RDRAM. +//! param firstVertexIndex Index of first vertex +//----------------------------------------------------------------------------- +void RSP::RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex ) +{ + m_vertexMgr->ciVertex(segmentAddress, numVertices, firstVertexIndex); +} + +//----------------------------------------------------------------------------- +// DMA Vertex +//----------------------------------------------------------------------------- +void RSP::RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 ) +{ + m_vertexMgr->DMAVertex(v, n, v0); +} + +//----------------------------------------------------------------------------- +// Set Vertex Color Base +//----------------------------------------------------------------------------- +void RSP::RSP_SetVertexColorBase(unsigned int segmentAddress) +{ + m_vertexMgr->setVertexColorBase( m_memory->getRDRAMAddress(segmentAddress) ); +} + +//***************************************************************************** +// Display List +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Display List +//----------------------------------------------------------------------------- +void RSP::RSP_DisplayList(unsigned int segmentAddress) +{ + m_displayListParser->displayList(segmentAddress); +} + +//----------------------------------------------------------------------------- +// DMA Display List +//----------------------------------------------------------------------------- +void RSP::RSP_DMADisplayList( unsigned int w0, unsigned int w1 ) +{ + m_displayListParser->DMADisplayList(w0, w1); +} + +//----------------------------------------------------------------------------- +// Branch Display List +//----------------------------------------------------------------------------- +void RSP::RSP_BranchList( unsigned int dl ) +{ + m_displayListParser->branchDisplayList(dl); +} + +//----------------------------------------------------------------------------- +// Branch Display List Z +//----------------------------------------------------------------------------- +void RSP::RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval ) +{ + if ( m_vertexMgr->getVertex(vtx)->z <= zval ) { + m_displayListParser->branchDisplayList(branchdl); + } +} + +//----------------------------------------------------------------------------- +// End Display List +//----------------------------------------------------------------------------- +void RSP::RSP_EndDisplayList() +{ + m_displayListParser->endDisplayList(); +} + +//----------------------------------------------------------------------------- +//* Cull Display List +//! @todo Cull Display List +//----------------------------------------------------------------------------- +void RSP::RSP_CullDisplayList( unsigned int v0, unsigned int vn ) +{ + //Logger::getSingleton().printMsg("RSP_CullDisplayList - Unimplemented", M64MSG_WARNING); + //TODO +} + +//***************************************************************************** +// Indices +//***************************************************************************** + +//----------------------------------------------------------------------------- +// 1 Triangle +//----------------------------------------------------------------------------- +void RSP::RSP_1Triangle( int v0, int v1, int v2) +{ + m_vertexMgr->add1Triangle(v0, v1, v2); +} + +//----------------------------------------------------------------------------- +// 2 Trangles +//----------------------------------------------------------------------------- +void RSP::RSP_2Triangles( int v00, int v01, int v02, int flag0, + int v10, int v11, int v12, int flag1 ) +{ + m_vertexMgr->add1Triangle(v00, v01, v02); + m_vertexMgr->add1Triangle(v10, v11, v12); +} + +//----------------------------------------------------------------------------- +// 4 Triangles +//----------------------------------------------------------------------------- +void RSP::RSP_4Triangles( int v00, int v01, int v02, + int v10, int v11, int v12, + int v20, int v21, int v22, + int v30, int v31, int v32 ) +{ + m_vertexMgr->add1Triangle(v00, v01, v02); + m_vertexMgr->add1Triangle(v10, v11, v12); + m_vertexMgr->add1Triangle(v20, v21, v22); + m_vertexMgr->add1Triangle(v30, v31, v32); +} + +//----------------------------------------------------------------------------- +// DMA Triangel +//----------------------------------------------------------------------------- +void RSP::RSP_DMATriangles( unsigned int tris, unsigned int n ) +{ + m_vertexMgr->addDMATriangles(tris, n); +} + +//----------------------------------------------------------------------------- +// Quadrangle +//----------------------------------------------------------------------------- +void RSP::RSP_1Quadrangle( int v0, int v1, int v2, int v3 ) +{ + m_vertexMgr->add1Triangle(v0, v1, v2); + m_vertexMgr->add1Triangle(v0, v2, v3); +} + +//***************************************************************************** +// Geometry Mode +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Geometry Mode +//----------------------------------------------------------------------------- +void RSP::RSP_GeometryMode(unsigned int clear, unsigned int set) +{ + RSP_ClearGeometryMode(clear); + RSP_SetGeometryMode(set); +} + +//----------------------------------------------------------------------------- +// Set Geometry Mode +//----------------------------------------------------------------------------- +void RSP::RSP_SetGeometryMode( unsigned int mode ) +{ + m_geometryMode |= mode; + updateGeometryStates(); +} + +//----------------------------------------------------------------------------- +// Clear Geometry Mode +//----------------------------------------------------------------------------- +void RSP::RSP_ClearGeometryMode( unsigned int mode ) +{ + m_geometryMode &= ~mode; + updateGeometryStates(); +} + +//***************************************************************************** +// Other +//***************************************************************************** + +void RSP::RSP_Line3D( int v0, int v1, int flag ) +{ + Logger::getSingleton().printMsg("RSP_Line3D - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_LineW3D( int v0, int v1, int wd, int flag ) +{ + Logger::getSingleton().printMsg("RSP_LineW3D - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjRectangle( unsigned int sp ) +{ + Logger::getSingleton().printMsg("RSP_ObjRectangle - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjSprite( unsigned int sp ) +{ + Logger::getSingleton().printMsg("RSP_ObjSprite - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjLoadTxtr( unsigned int tx ) +{ + Logger::getSingleton().printMsg("RSP_ObjLoadTxtr - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjLoadTxSprite( unsigned int txsp ) +{ + Logger::getSingleton().printMsg("RSP_ObjLoadTxSprite - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjLoadTxRectR( unsigned int txsp ) +{ + Logger::getSingleton().printMsg("RSP_ObjLoadTxRectR - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_BgRect1Cyc( unsigned int bg ) +{ + Logger::getSingleton().printMsg("RSP_BgRect1Cyc - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_BgRectCopy( unsigned int bg ) +{ + Logger::getSingleton().printMsg("RSP_BgRectCopy - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjMatrix( unsigned int mtx ) +{ + Logger::getSingleton().printMsg("RSP_ObjMatrix - Unimplemented", M64MSG_WARNING); +} +void RSP::RSP_ObjSubMatrix( unsigned int mtx ) +{ + Logger::getSingleton().printMsg("RSP_ObjSubMatrix - Unimplemented", M64MSG_WARNING); +} + +//***************************************************************************** +// Non important functions +//***************************************************************************** + +void RSP::RSP_Sprite2DBase( unsigned int base ) { + Logger::getSingleton().printMsg("RSP_Sprite2DBase - Unimplemented", M64MSG_WARNING); +} + +void RSP::RSP_LookAt( unsigned int l ) { + Logger::getSingleton().printMsg("RSP_LookAt - Unimplemented", M64MSG_WARNING); +} + +void RSP::RSP_ClipRatio( unsigned int r ) { + Logger::getSingleton().printMsg("RSP_ClipRatio - Unimplemented", M64MSG_WARNING); +} + +void RSP::RSP_PerspNormalize( unsigned short scale ) { + Logger::getSingleton().printMsg("RSP_PerspNormalize - Unimplemented", M64MSG_WARNING); +} diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSP.h b/source/mupen64plus-video-arachnoid/src/RSP/RSP.h new file mode 100755 index 0000000..26692f6 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSP.h @@ -0,0 +1,256 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef REALITY_SIGNAL_PROCESSOR_H_ +#define REALITY_SIGNAL_PROCESSOR_H_ + +#define M64P_PLUGIN_PROTOTYPES 1 +#include "m64p_plugin.h" +#include "UCodeDefs.h" +#include "RSPMatrixManager.h" +#include "RSPVertexManager.h" +#include "Matrix4.h" + +//Forward declarations +class VI; +struct RDPTile; +class RDP; +class Memory; +class DisplayListParser; +class RSPLightManager; +class FogManager; + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define RSP_1ST 0xBF +#define RSP_TRI1 (RSP_1ST-0) +#define RSP_CULLDL (RSP_1ST-1) +#define RSP_POPMTX (RSP_1ST-2) +#define RSP_MOVEWORD (RSP_1ST-3) +#define RSP_TEXTURE (RSP_1ST-4) +#define RSP_SETOTHERMODE_H (RSP_1ST-5) +#define RSP_SETOTHERMODE_L (RSP_1ST-6) +#define RSP_ENDDL (RSP_1ST-7) +#define RSP_SETGEOMETRYMODE (RSP_1ST-8) +#define RSP_CLEARGEOMETRYMODE (RSP_1ST-9) +#define RSP_LINE3D (RSP_1ST-10) +#define RSP_RDPHALF_1 (RSP_1ST-11) +#define RSP_RDPHALF_2 (RSP_1ST-12) +#define RSP_RDPHALF_CONT (RSP_1ST-13) + +#define RSP_MODIFYVTX (RSP_1ST-13) +#define RSP_TRI2 (RSP_1ST-14) +#define RSP_BRANCH_Z (RSP_1ST-15) +#define RSP_LOAD_UCODE (RSP_1ST-16) + +#define RSP_SPRITE2D_SCALEFLIP (RSP_1ST-1) +#define RSP_SPRITE2D_DRAW (RSP_1ST-2) + +// flags to inhibit pushing of the display list (on branch) +#define RSP_DLIST_PUSH 0x00 +#define RSP_DLIST_NOPUSH 0x01 + +//----------------------------------------------------------------------------- +//! Viewport +//----------------------------------------------------------------------------- +struct Viewport +{ + float vscale[4]; + float vtrans[4]; + float x, y, width, height; + float nearz, farz; +}; + + +//----------------------------------------------------------------------------- +//! Struct used to store Information about Background Image +//----------------------------------------------------------------------------- +struct BGImageInfo +{ + unsigned int address; //!< Where texture is stored (in RDRAM) + unsigned int width; //!< Width of texture + unsigned int height; //!< Height of texture + unsigned int format; //!< Format of texture + unsigned int size; //!< Size of texture + unsigned int palette; //!< What Texture Lookup Table to use +}; + +//----------------------------------------------------------------------------- +//* RSPTexture +//! Struct used to store information about current texture on rsp +//----------------------------------------------------------------------------- +struct RSPTexture +{ + float scaleS, scaleT; + int level, on, tile; +}; + +//----------------------------------------------------------------------------- +//! Singnal Processor Triangle +//----------------------------------------------------------------------------- +typedef SPVertex SPTriangle[3]; + +//***************************************************************************** +//* RSP +//! Class for emulating the Reality Signal Processor +//***************************************************************************** +class RSP +{ +public: + //Constructor + RSP(); + //Destructor + ~RSP(); + + //Initialize + bool initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr); + void dispose(); + void reset(); + + void updateGeometryStates(); + + //Trigger Interrupt + void triggerInterrupt(); + + void moveSegment(int segmentID, int value); + + void moveMemViewport(unsigned int segmentAddress); + + RDPTile* getTile(int tile) { return m_textureTiles[tile]; } + void setTile(RDPTile* tile, int index) { m_textureTiles[index] = tile; } + RSPTexture& getTexture() { return m_texture; } + bool getTexturesChanged() { return m_texturesChanged; } + void setTexturesChanged(bool changed) { m_texturesChanged = changed; } + + RSPMatrixManager* getMatrixMgr() { return m_matrixMgr; } + RSPVertexManager* getVertexMgr() { return m_vertexMgr; } + +public: + + //Matrix + void RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace ); + void RSP_PopMatrix(); + void RSP_PopMatrixN(unsigned int num); + void RSP_InsertMatrix(unsigned int where, unsigned int num); + void RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply ); + void RSP_ForceMatrix( unsigned int segmentAddress ); + void RSP_LookAt( unsigned int l ); + void RSP_PerspNormalize( unsigned short scale ); + + //Display List + void RSP_DisplayList(unsigned int segmentAddress); + void RSP_DMADisplayList( unsigned int w0, unsigned int w1 ); + void RSP_CullDisplayList( unsigned int v0, unsigned int vn ); + void RSP_BranchList( unsigned int dl ); + void RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval ); + void RSP_EndDisplayList(); + + //Light + void RSP_Light( unsigned int lightIndex, unsigned int segmentAddress ); + void RSP_NumLights( int n ); + void RSP_LightColor( unsigned int lightIndex, unsigned int packedColor ); + + //Vertices + void RSP_Vertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex); + void RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex); + void RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val ); + void RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a); + void RSP_SetVertexTexCoord( unsigned int vtx, float s, float t); + + void RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 ); + void RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset ); + void RSP_SetVertexColorBase(unsigned int segmentAddress); + + //Indices + void RSP_1Triangle( int v00, int v01, int v02 ); + void RSP_2Triangles( int v00, int v01, int v02, int flag0, + int v10, int v11, int v12, int flag1 ); + void RSP_4Triangles( int v00, int v01, int v02, + int v10, int v11, int v12, + int v20, int v21, int v22, + int v30, int v31, int v32 ); + void RSP_DMATriangles( unsigned int tris, unsigned int n ); + void RSP_1Quadrangle( int v0, int v1, int v2, int v4 ); + + //Object + void RSP_ObjRectangle( unsigned int sp ); + void RSP_ObjSprite( unsigned int sp ); + void RSP_ObjLoadTxtr( unsigned int tx ); + void RSP_ObjLoadTxSprite( unsigned int txsp ); + void RSP_ObjLoadTxRectR( unsigned int txsp ); + void RSP_ObjMatrix( unsigned int mtx ); + void RSP_ObjSubMatrix( unsigned int mtx ); + + //Rendering + void RSP_Line3D( int v0, int v1, int flag ); + void RSP_LineW3D( int v0, int v1, int wd, int flag ); + void RSP_BgRect1Cyc( unsigned int bg ); + void RSP_BgRectCopy( unsigned int bg ); + void RSP_Sprite2DBase( unsigned int base ); + + //States + void RSP_GeometryMode( unsigned int clear, unsigned int set ); + void RSP_SetGeometryMode( unsigned int mode ); + void RSP_ClearGeometryMode( unsigned int mode ); + + //Clipping + void RSP_ClipRatio( unsigned int r ); + + //Texturing + void RSP_Texture( float sc, float tc, int level, int tile, int on ); + + //Fog + void RSP_FogFactor( short fm, short fo ); + + //UCode + void RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize ); + +private: + + //Pointers to big objects and managers + GFX_INFO* m_graphicsInfo; //!< Access to emulator data (like RDRAM ...) + VI* m_vi; //!< Videointerface + Memory* m_memory; //!< Memory managers (handles RDRAM, Texture Memory...) + DisplayListParser* m_displayListParser; //!< Display list parser + FogManager* m_fogMgr; //!< Manager that handles fog + RDP* m_rdp; //!< Pointer to Reality Drawing Processor + + //Helper managers + RSPMatrixManager* m_matrixMgr; //!< Handles matrix stack + RSPVertexManager* m_vertexMgr; //!< Vertex Manager, processes and modifies vertices + RSPLightManager* m_lightMgr; //!< Light Manager, handles lights + + //Geometry Mode + unsigned int m_geometryMode; //!< Contains states (lighting, shading, culling...) + + //Textures + RSPTexture m_texture; + RDPTile* m_textureTiles[2]; + bool m_texturesChanged; + + //Viewport + Viewport m_viewport; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp new file mode 100755 index 0000000..3384fcb --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp @@ -0,0 +1,105 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RSPLightManager.h" +#include "Memory.h" +#include "MathLib.h" +#include "GBI.h" +#include "Logger.h" + +#define RGBA_GETALPHA(rgb) ((rgb) >> 24) +#define RGBA_GETRED(rgb) (((rgb) >> 16) & 0xff) +#define RGBA_GETGREEN(rgb) (((rgb) >> 8) & 0xff) +#define RGBA_GETBLUE(rgb) ((rgb) & 0xff) + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +RSPLightManager::RSPLightManager() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +RSPLightManager::~RSPLightManager() +{ +} + +bool RSPLightManager::initialize(Memory* memory) +{ + m_memory = memory; + m_numLights = 0; + m_lightEnabled = false; + + return true; +} + +//----------------------------------------------------------------------------- +// Set Light +//----------------------------------------------------------------------------- +void RSPLightManager::setLight( unsigned int lightIndex, unsigned int rdramAddress ) +{ + //Error control + if ((rdramAddress + sizeof(RDRAMLight)) > m_memory->getRDRAMSize() ) { + return; + } + + //Get Light from memory + RDRAMLight* light = (RDRAMLight*)m_memory->getRDRAM(rdramAddress); + + if ( lightIndex < 8 ) //Only supports 8 lights + { + m_lights[lightIndex].r = light->r * 0.0039215689f; //Convert from 0-255 to 0-1 + m_lights[lightIndex].g = light->g * 0.0039215689f; + m_lights[lightIndex].b = light->b * 0.0039215689f; + + m_lights[lightIndex].x = light->x; + m_lights[lightIndex].y = light->y; + m_lights[lightIndex].z = light->z; + + Vec3Normalize( &m_lights[lightIndex].x ); + } +} + +//----------------------------------------------------------------------------- +// Set Num Lights +//----------------------------------------------------------------------------- +void RSPLightManager::setNumLights(int numLights) +{ + if (numLights <= 8) + { + m_numLights = numLights; + } +} + +//----------------------------------------------------------------------------- +// Set Light Color +//----------------------------------------------------------------------------- +void RSPLightManager::setLightColor( unsigned int lightIndex, unsigned int packedColor ) +{ + if (lightIndex < 8) + { + m_lights[lightIndex].r = _SHIFTR( packedColor, 24, 8 ) * 0.0039215689f; + m_lights[lightIndex].g = _SHIFTR( packedColor, 16, 8 ) * 0.0039215689f; + m_lights[lightIndex].b = _SHIFTR( packedColor, 8, 8 ) * 0.0039215689f; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h new file mode 100755 index 0000000..7c99ebf --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef RSP_LIGHT_MANAGER_H_ +#define RSP_LIGHT_MANAGER_H_ + +//Forward declarations +class Memory; + +//----------------------------------------------------------------------------- +//* Light +//! Struct defining how lights are stored in RDRAM +//----------------------------------------------------------------------------- +struct RDRAMLight +{ + unsigned char pad0; //!< Padding + unsigned char b, g, r; //!< Color + unsigned char pad1; //!< Padding + unsigned char b2, g2, r2; //!< Color + char pad2; //!< Padding + char z, y, x; //!< Direction +}; + +//----------------------------------------------------------------------------- +//* RSP Light +//! Struct used to store information about lights +//----------------------------------------------------------------------------- +struct RSPLight +{ + float r, g, b; //Color + float x, y, z; //Direction +}; + +//***************************************************************************** +//! RSP Light Manager +//***************************************************************************** +class RSPLightManager +{ +public: + + //Constructor / Destructor + RSPLightManager(); + ~RSPLightManager(); + + bool initialize(Memory* memory); + + void setLight( unsigned int lightIndex, unsigned int rdramAddress ); + void setNumLights(int numLights); + void setLightColor( unsigned int lightIndex, unsigned int packedColor ); + const float* getAmbientLight() { return &m_lights[m_numLights].r; } + + //Get + int getNumLights() { return m_numLights; } + void setLightEnabled(bool enabled) { m_lightEnabled = enabled; } + bool getLightEnabled() { return m_lightEnabled; } + const float* getLightColor(int lightIndex) { return &m_lights[lightIndex].r; } + const float* getLightDirection(int lightIndex) { return &m_lights[lightIndex].x; } + +private: + + Memory* m_memory; + + //Light + bool m_lightEnabled; + RSPLight m_lights[8]; + int m_numLights; + +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp new file mode 100755 index 0000000..89a4923 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp @@ -0,0 +1,291 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RSPMatrixManager.h" +#include "Memory.h" +#include //modff +#include "GBI.h" //SHIFT +#include "GBIDefs.h" //_FIXED2FLOAT +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +RSPMatrixManager::RSPMatrixManager() +{ + +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +RSPMatrixManager::~RSPMatrixManager() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialize +//----------------------------------------------------------------------------- +bool RSPMatrixManager::initialize(Memory* memory) +{ + m_memory = memory; + m_rdramOffset = 0; + return true; +} + +//----------------------------------------------------------------------------- +//! Add Matrix +//! @param segmentAddress Later converted to RDRam address pointing to Matrix to load +//! @param projectionMatrix True if matrix is a projection matrix, +//! False if matrix is a modelview matrix +//! @param push True if adding a new matrix to stack(and saving the old one) +//! @param replace True if loading matrix (glLoadMatrix), false if multiplying with the previus matrix (glMultMatrix) +//----------------------------------------------------------------------------- +void RSPMatrixManager::addMatrix(unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace) +{ + unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress); + + if (rdramAddress + 64 > m_memory->getRDRAMSize() ) { + return; + } + + Matrix4 temp; + _loadMatrix(rdramAddress, temp); + + if ( projectionMatrix ) + { + _setProjection(temp, push, replace); + } + else + { + _setWorldView(temp, push, replace); + } + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! Insert Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::insertMatrix(unsigned int where, unsigned int num) +{ + float fraction, integer; + + _updateCombinedMatrix(); + + if ((where & 0x3) || (where > 0x3C)) + { + return; + } + + if (where < 0x20) + { + fraction = modff( m_worldProject[0][where >> 1], &integer ); + m_worldProject[0][where >> 1] = (short)_SHIFTR( num, 16, 16 ) + fabs( fraction ); + + fraction = modff( m_worldProject[0][(where >> 1) + 1], &integer ); + m_worldProject[0][(where >> 1) + 1] = (short)_SHIFTR( num, 0, 16 ) + fabs( fraction ); + } + else + { + float newValue; + + fraction = modff( m_worldProject[0][(where - 0x20) >> 1], &integer ); + newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 16, 16 ), 16); + + // Make sure the sign isn't lost + if ((integer == 0.0f) && (fraction != 0.0f)) + newValue = newValue * (fraction / fabs( fraction )); + + m_worldProject[0][(where - 0x20) >> 1] = newValue; + + fraction = modff( m_worldProject[0][((where - 0x20) >> 1) + 1], &integer ); + newValue = integer + _FIXED2FLOAT( _SHIFTR( num, 0, 16 ), 16 ); + + // Make sure the sign isn't lost + if ((integer == 0.0f) && (fraction != 0.0f)) + newValue = newValue * (fraction / fabs( fraction )); + + m_worldProject[0][((where - 0x20) >> 1) + 1] = newValue; + } +} +void RSPMatrixManager::ForceMatrix(unsigned int rdramAddress) +{ + _loadMatrix(rdramAddress, m_worldProject); +} + + + +//----------------------------------------------------------------------------- +// Pop Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::popMatrix() +{ + if ( m_modelViewMatrixTop > 0 ) + { + m_modelViewMatrixTop--; //Pop Matrix from stack + } + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +// Pop Matrix N +//----------------------------------------------------------------------------- +void RSPMatrixManager::popMatrixN(unsigned int num) +{ + if ( m_modelViewMatrixTop > num - 1) + { + m_modelViewMatrixTop -= num; + } + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! DMA Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::DMAMatrix( unsigned int rdramAddress, unsigned char index, unsigned char multiply ) +{ + //Get final address + unsigned int address = m_rdramOffset + rdramAddress; + + if (address + 64 > m_memory->getRDRAMSize()) + { + return; + } + + //Load Matrix from Memory + Matrix4 temp; + _loadMatrix(rdramAddress, temp); + + //Set Modelview index + m_modelViewMatrixTop = index; + + //FIXME: Other way around? + if (multiply) + { + m_modelViewMatrices[m_modelViewMatrixTop] = m_modelViewMatrices[0]; + m_modelViewMatrices[m_modelViewMatrixTop] = m_modelViewMatrices[m_modelViewMatrixTop] * temp; + } + else + { + m_modelViewMatrices[m_modelViewMatrixTop] = temp; + } + + //Set Projection Matrix to Identity + m_projectionMatrices[m_projectionMatrixTop] = Matrix4::IDENTITY; + + //Update Matrices + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! Reset Matrices +//----------------------------------------------------------------------------- +void RSPMatrixManager::resetMatrices() +{ + m_modelViewMatrices[0] = Matrix4::IDENTITY; + m_projectionMatrices[0] = Matrix4::IDENTITY; + + m_modelViewMatrixTop = 0; + m_projectionMatrixTop = 0; + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! Load Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::_loadMatrix(unsigned int addr, Matrix4& out) +{ + if ( addr + 64 > m_memory->getRDRAMSize() ) { + return; + } + + unsigned char* RDRAM = m_memory->getRDRAM(); + + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + int hi = *(short *)(RDRAM + ((addr+(i<<3)+(j<<1) )^0x2)); + unsigned short lo = *(unsigned short *)(RDRAM + ((addr+(i<<3)+(j<<1) + 32)^0x2)); + out[i][j] = (float)((hi<<16) | (lo))/ 65536.0f; + } + } +} + +//----------------------------------------------------------------------------- +//! Set Projection Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::_setProjection(const Matrix4& mat, bool push, bool replace) +{ + Matrix4& oldMatrix = m_projectionMatrices[m_projectionMatrixTop]; + + if (push) + { + m_projectionMatrixTop++; + } + + if ( replace ) + { + m_projectionMatrices[m_projectionMatrixTop] = mat; + } + else + { + m_projectionMatrices[m_projectionMatrixTop] = mat * oldMatrix; + } + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! Set World View Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::_setWorldView(const Matrix4 & mat, bool push, bool replace) +{ + Matrix4& oldMatrix = m_modelViewMatrices[m_modelViewMatrixTop]; + + if (push) + { + m_modelViewMatrixTop++; + } + + if ( replace ) + { + m_modelViewMatrices[m_modelViewMatrixTop] = mat; + } + else + { + m_modelViewMatrices[m_modelViewMatrixTop] = mat * oldMatrix; + } + + _updateCombinedMatrix(); +} + +//----------------------------------------------------------------------------- +//! Update Combined Matrix +//----------------------------------------------------------------------------- +void RSPMatrixManager::_updateCombinedMatrix() +{ + m_worldProject = m_modelViewMatrices[m_modelViewMatrixTop] * m_projectionMatrices[m_projectionMatrixTop]; +} diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h new file mode 100755 index 0000000..bdfe776 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef RSP_MATRIX_MANAGER_H_ +#define RSP_MATRIX_MANAGER_H_ + +#include "Matrix4.h" + +//Forward Declarations +class Memory; + +//***************************************************************************** +//! RSP Matrix Manager +//***************************************************************************** +class RSPMatrixManager +{ +public: + + //Constructor / Destructor + RSPMatrixManager(); + ~RSPMatrixManager(); + + bool initialize(Memory* memory); + + //Add Matrices + void addMatrix(unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace); + void insertMatrix(unsigned int where, unsigned int num); + + //Remove Matrices + void popMatrix(); + void popMatrixN(unsigned int num); + void ForceMatrix( unsigned int segmentAddress ); + void selectViewMatrix(unsigned int index) { m_modelViewMatrixTop = index; _updateCombinedMatrix(); } + void DMAMatrix(unsigned int segmentAddress, unsigned char index, unsigned char multiply ); + //void RSP_ForceMatrix( unsigned int mptr ); + //void RSP_LookAt( unsigned int l ); + //void RSP_PerspNormalize( unsigned short scale ); + + void setRDRAMOffset(unsigned int offset) { m_rdramOffset = offset; } + + void resetMatrices(); + +public: + + float* getModelViewMatrix() { return m_modelViewMatrices[m_modelViewMatrixTop]._m; } + float* getProjectionMatrix() { return m_projectionMatrices[m_projectionMatrixTop]._m; } + float* getViewProjectionMatrix() { return m_worldProject._m; } + +private: + + void _loadMatrix(unsigned int addr, Matrix4& out); + void _setProjection(const Matrix4& mat, bool push, bool replace); + void _setWorldView(const Matrix4 & mat, bool push, bool replace); + void _updateCombinedMatrix(); + +private: + + Memory* m_memory; //!< Pointer to memory + + static const int NUM_STACK_MATRICES = 60; + + unsigned int m_rdramOffset; + + //Stack indices + unsigned int m_modelViewMatrixTop; + unsigned int m_projectionMatrixTop; + + //Matrices + Matrix4 m_modelViewMatrices[NUM_STACK_MATRICES]; //!< Stack with projection matrices + Matrix4 m_projectionMatrices[NUM_STACK_MATRICES]; //!< Stack with projection matrices + Matrix4 m_worldProject; //!< Combined modelviewprojection matrix +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp new file mode 100755 index 0000000..d87b11e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp @@ -0,0 +1,578 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RSPVertexManager.h" +#include "OpenGLManager.h" +#include "Memory.h" +#include "RSPMatrixManager.h" +#include "RSPLightManager.h" +#include "OpenGLRenderer.h" +#include "GBIDefs.h" //hmm +#include "MathLib.h" //Transform, Vec3Normalize +#include //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 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 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; igetNumLights(); ++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 x; + m_vertices[i].y = vertex->y; + m_vertices[i].z = vertex->z; + m_vertices[i].flag = vertex->flag; + m_vertices[i].s = _FIXED2FLOAT( vertex->s, 5 ); + m_vertices[i].t = _FIXED2FLOAT( vertex->t, 5 ); + + if ( m_lightMgr->getLightEnabled() ) + { + m_vertices[i].nx = vertex->normal.x; + m_vertices[i].ny = vertex->normal.y; + m_vertices[i].nz = vertex->normal.z; + m_vertices[i].a = vertex->color.a * 0.0039215689f; + } + else + { + m_vertices[i].r = vertex->color.r * 0.0039215689f; + m_vertices[i].g = vertex->color.g * 0.0039215689f; + m_vertices[i].b = vertex->color.b * 0.0039215689f; + m_vertices[i].a = vertex->color.a * 0.0039215689f; + } + + _processVertex(i); + vertex++; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h new file mode 100755 index 0000000..6939878 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef RSP_VERTEX_MANAGER_H_ +#define RSP_VERTEX_MANAGER_H_ + +//Forward declarations +class Memory; +class RSPMatrixManager; +class RSPLightManager; +class OpenGLManager; + +enum TexCoordGenType +{ + TCGT_NONE = 0, + TCGT_LINEAR = 1, + TCGT_GEN = 2, +}; + +//----------------------------------------------------------------------------- +//! Signal Processor Vertex +//----------------------------------------------------------------------------- +struct SPVertex +{ + float x, y, z, w; + float nx, ny, nz; + float r, g, b, a; + float s, t; + float xClip, yClip, zClip; + float flag; +}; + +//***************************************************************************** +//! RSP Vertex Manager +//***************************************************************************** +class RSPVertexManager +{ +public: + + //Constructor / Destructor + RSPVertexManager(); + ~RSPVertexManager(); + + bool initialize(OpenGLManager* openGLMgr, Memory* memory, RSPMatrixManager* matrixMgr, RSPLightManager* lightMgr); + + //Vertices + void setVertices( unsigned int address, unsigned int numVertices, unsigned int firstVertexIndex); + void modifyVertex( unsigned int vtx, unsigned int where, unsigned int val ); + void setVertexColor(unsigned int vertexIndex, float r, float g, float b, float a); + void setVertexTextureCoord(unsigned int vertexIndex, float s, float t); + + void ciVertex(unsigned int segmentAddress, unsigned int n, unsigned int v0 ); + + void addConkerVertices(unsigned int segmentAddress, unsigned int n, unsigned int v0 ); + + void DMAVertex( unsigned int v, unsigned int n, unsigned int v0 ); + void DMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset ); + void setVertexColorBase( unsigned int rdramAddress ) { m_colorBaseRDRAMAddress = rdramAddress; } + + bool add1Triangle( unsigned int v0, unsigned int v1, unsigned int v2); + void add2Triangles( int v00, int v01, int v02, int flag0, + int v10, int v11, int v12, int flag1 ); + void add4Triangles( int v00, int v01, int v02, + int v10, int v11, int v12, + int v20, int v21, int v22, + int v30, int v31, int v32 ); + void addDMATriangles( unsigned int tris, unsigned int n ); + void add1Quadrangle( int v0, int v1, int v2, int v4 ); + void setTexCoordGenType(TexCoordGenType texCoordGenType) { m_texCoordGenType = texCoordGenType; } + + void setRDRAMOffset(unsigned int offset) { m_rdramOffset = offset; } + void setBillboard(unsigned int billboard) { m_billboard = billboard; } + unsigned int getBillboard() { return m_billboard; } + + void setConkerAddress(unsigned int segmentAddress); + +public: + + SPVertex* getVertex(unsigned int index) { return &m_vertices[index]; } + +private: + + void _processVertex( unsigned int v ); + +private: + + OpenGLManager* m_openGLMgr; + Memory* m_memory; + RSPMatrixManager* m_matrixMgr; + RSPLightManager* m_lightMgr; + + //Vertex Buffer + static const unsigned int MAX_VERTICES = 300; + SPVertex m_vertices[MAX_VERTICES]; + + unsigned int m_colorBaseRDRAMAddress; //!< Address in RDRAM where colors for vertices are located (used by Perfect Dark) + + unsigned int m_rdramOffset; + + unsigned int m_billboard; + TexCoordGenType m_texCoordGenType; //!< Texture Coordinate Generation Technique + + unsigned int m_conkerRDRAMAddress; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/RomDetector.cpp b/source/mupen64plus-video-arachnoid/src/RomDetector.cpp new file mode 100755 index 0000000..b1336f4 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RomDetector.cpp @@ -0,0 +1,140 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "RomDetector.h" +#include "assembler.h" //swapRomHeaderBytes +#include //memcpy +#include "StringFunctions.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +ROMDetector::ROMDetector() +{ + +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +ROMDetector::~ROMDetector() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialzie +//! Saves rom header, detects which rom it is, and sets states after +//! which rom it is. +//! @param romHeader Header with information about rom. +//----------------------------------------------------------------------------- +void ROMDetector::initialize(unsigned char* romHeader) +{ + + //Copy Header + memcpy(&m_romHeader, romHeader, sizeof(ROMHeader)); + + //Header are stored really strange, swap bytes around to make sense of it + swapRomHeaderBytes((void*)&m_romHeader, sizeof(ROMHeader)); + + //Trim rom name (remove unnecessary whitespaces) + StringFunctions::trim(m_romHeader.romName); + + //What game is it? + m_currentRomID = this->_getRomID(m_romHeader.romName); +} + +//----------------------------------------------------------------------------- +//* Get ROM ID +//! Detects and returns which rom it is, and sets states after +//! which rom it is. +//! @param romName Name of rom from rom-header. +//! @return ID of the rom that was identified by rom name. +//----------------------------------------------------------------------------- +N64_ROM_ID ROMDetector::_getRomID(char romName[20]) +{ + m_combinerType = CT_ADVANCED; //Use advanced combiner + m_clearType = CT_NEVER; //Never Clear Screen + m_ignoreFillRects = false; + m_forceDisableFaceCulling = false; + m_useMultiTexture = true; + m_useSecondaryColor = true; + + //Return ROM-ID and set ROM options + if ( !strncmp(romName, "Banjo-Kazooie", 13) ) + { + m_combinerType = CT_SIMPLE; + return BANJO_KAZOOIE; + } + else if ( !strncmp(romName, "BANJO TOOIE", 11) ) + { + m_combinerType = CT_SIMPLE; + return BANJO_TOOIE; + } + else if ( !strncmp(romName, "F-ZERO X", 8) ) + { + m_clearType = CT_AFTER_ONE_DISPLAY_LIST; + return F_ZERO_X; + } + else if ( !strncmp(romName, "STARFOX64", 9) ) + { + m_clearType = CT_AFTER_ONE_DISPLAY_LIST; + return STAR_FOX_64; + } + else if ( !strncmp(romName, "SMASH BROTHERS", 14) ) + { + m_clearType = CT_AFTER_ONE_DISPLAY_LIST; + return SUPER_SMASH_BROS; + } + else if ( !strncmp(romName, "SUPER MARIO 64", 14) ) + { + return SUPER_MARIO_64; + } + else if ( !strncmp(romName, "BOMBERMAN64E", 11) ) + { + m_clearType = CT_AFTER_ONE_DISPLAY_LIST; + m_ignoreFillRects = true; + return BOMBERMAN_64; + } + else if ( !strncmp(romName, "DONKEY KONG 64", 14) ) + { + return DONKEY_KONG_64; + } + else if ( !strncmp(romName, "WAVE RACE 64", 12) ) + { + m_clearType = CT_AFTER_ONE_DISPLAY_LIST; + m_ignoreFillRects = true; + return WAVE_RACE_64; + } + else if ( !strncmp(romName, "GOLDENEYE", 9) ) + { + return GOLDEN_EYE; + } + else if ( !strncmp(romName, "PAPER MARIO", 11) ) + { + m_clearType = CT_NEVER; + return PAPER_MARIO; + } + else + { + return UNKNOWN_ROM; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/RomDetector.h b/source/mupen64plus-video-arachnoid/src/RomDetector.h new file mode 100755 index 0000000..8c57c89 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/RomDetector.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef ROM_DETECTOR_H_ +#define ROM_DETECTOR_H_ + +#include "N64Games.h" + +//***************************************************************************** +//* ROM Header +//! Stored in each rom, gives us information about rom. +//***************************************************************************** +//#pragma pack(push, 1) +struct ROMHeader +{ + unsigned char x1, x2, x3, x4; + unsigned int clockRate; + unsigned int bootAddressOffset; + unsigned int release; + unsigned int CRC1; //!< Hash value + unsigned int CRC2; //!< Hash value + unsigned long long unknown0; + char romName[20]; //!< Name of rom, used to identify what rom it is. + unsigned int unknown1; + unsigned short unknown2; + unsigned char unknown3; + unsigned char nManufacturer; + unsigned short cartID; + signed char countryID; + unsigned char unknown4; +}; +//#pragma pack(pop) +//***************************************************************************** +//* COMBINER TYPE +//! What kind of combiner to use +//***************************************************************************** +enum COMBINER_TYPE +{ + CT_ADVANCED, + CT_SIMPLE, + CT_DUMMY, +}; + +//***************************************************************************** +//* CLEAR TYPE +//! When to clear screen +//***************************************************************************** +enum CLEAR_TYPE +{ + CT_NEVER, + CT_AFTER_ONE_DISPLAY_LIST, + CT_AFTER_TWO_DISPLAY_LIST, + CT_AFTER_THREE_DISPLAY_LIST, +}; + +//***************************************************************************** +//* ROM Detector +//! Class for detecting which rom it is and settings states after that. +//***************************************************************************** +class ROMDetector +{ +public: + + //Destructor + ~ROMDetector(); + + //Singleton Instance + static ROMDetector& getSingleton() + { + static ROMDetector instance; + return instance; + } + + //Initialize + void initialize(unsigned char* romHeader); + + const char* getRomName() { return m_romHeader.romName; } + +public: + + //! Get Rom ID + //! @return ID of the current running rom (game). + N64_ROM_ID getRomID() { return m_currentRomID; } + + //! Get Combiner Type + //! @return ID of the combiner to use. + COMBINER_TYPE getCombinerType() { return m_combinerType; } + + //! Get Clear Type + //! @return when to clear screen. + CLEAR_TYPE getClearType() { return m_clearType; } + + //! Get Ignore Fill Rects + //! @return True if we should ignore fill rect instructions. + bool getIgnoreFillRects() { return m_ignoreFillRects; } + + //! Get Disable Face Culling + //! @return True if we never should enable Face Culling. + bool getDisableFaceCulling() { return m_forceDisableFaceCulling; } + + //! Get Use Multi Texturing + //! @return True if we should use multiple textures when rendering + bool getUseMultiTexture() { return m_useMultiTexture; } + + //! Get Use Secondary Color + //! @return True if we should secondary color when rendering + bool getUseSecondaryColor() { return m_useSecondaryColor; } + +private: + + //Construtor + ROMDetector(); + + //Get rom ID + N64_ROM_ID _getRomID(char romName[20]); + +private: + + ROMHeader m_romHeader; //!< Rom header with information about rom + + N64_ROM_ID m_currentRomID; //!< What rom is running + COMBINER_TYPE m_combinerType; //!< What combiner to use + CLEAR_TYPE m_clearType; //!< When to clear screen + bool m_ignoreFillRects; //!< Ignore fill rectangles? + bool m_forceDisableFaceCulling; //!< Disable face culling? + bool m_useMultiTexture; //!< Use multitextureing? + bool m_useSecondaryColor; //!< Use secondary color? + +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp new file mode 100755 index 0000000..9d125da --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp @@ -0,0 +1,76 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "SecondaryColorExt.h" +#include "ExtensionChecker.h" + +// EXT_secondary_color functions +#ifndef HAVE_GLES +#ifndef GL_GLEXT_VERSION +PFNGLSECONDARYCOLOR3BEXTPROC glSecondaryColor3bEXT; +PFNGLSECONDARYCOLOR3BVEXTPROC glSecondaryColor3bvEXT; +PFNGLSECONDARYCOLOR3DEXTPROC glSecondaryColor3dEXT; +PFNGLSECONDARYCOLOR3DVEXTPROC glSecondaryColor3dvEXT; +PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT; +PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT; +PFNGLSECONDARYCOLOR3IEXTPROC glSecondaryColor3iEXT; +PFNGLSECONDARYCOLOR3IVEXTPROC glSecondaryColor3ivEXT; +PFNGLSECONDARYCOLOR3SEXTPROC glSecondaryColor3sEXT; +PFNGLSECONDARYCOLOR3SVEXTPROC glSecondaryColor3svEXT; +PFNGLSECONDARYCOLOR3UBEXTPROC glSecondaryColor3ubEXT; +PFNGLSECONDARYCOLOR3UBVEXTPROC glSecondaryColor3ubvEXT; +PFNGLSECONDARYCOLOR3UIEXTPROC glSecondaryColor3uiEXT; +PFNGLSECONDARYCOLOR3UIVEXTPROC glSecondaryColor3uivEXT; +PFNGLSECONDARYCOLOR3USEXTPROC glSecondaryColor3usEXT; +PFNGLSECONDARYCOLOR3USVEXTPROC glSecondaryColor3usvEXT; +#endif +#endif +PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT; + +bool initializeSecondaryColorExtension() +{ +#ifndef HAVE_GLES + if ( isExtensionSupported( "GL_EXT_secondary_color" )) + { +#ifndef GL_GLEXT_VERSION + glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)wglGetProcAddress( "glSecondaryColor3bEXT" ); + glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)wglGetProcAddress( "glSecondaryColor3bvEXT" ); + glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)wglGetProcAddress( "glSecondaryColor3dEXT" ); + glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)wglGetProcAddress( "glSecondaryColor3dvEXT" ); + glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)wglGetProcAddress( "glSecondaryColor3fEXT" ); + glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)wglGetProcAddress( "glSecondaryColor3fvEXT" ); + glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)wglGetProcAddress( "glSecondaryColor3iEXT" ); + glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)wglGetProcAddress( "glSecondaryColor3ivEXT" ); + glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)wglGetProcAddress( "glSecondaryColor3sEXT" ); + glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)wglGetProcAddress( "glSecondaryColor3svEXT" ); + glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)wglGetProcAddress( "glSecondaryColor3ubEXT" ); + glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)wglGetProcAddress( "glSecondaryColor3ubvEXT" ); + glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)wglGetProcAddress( "glSecondaryColor3uiEXT" ); + glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)wglGetProcAddress( "glSecondaryColor3uivEXT" ); + glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)wglGetProcAddress( "glSecondaryColor3usEXT" ); + glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)wglGetProcAddress( "glSecondaryColor3usvEXT" ); + glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)wglGetProcAddress( "glSecondaryColorPointerEXT" ); +#endif + return true; + } +#endif + return false; +} diff --git a/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h new file mode 100755 index 0000000..6fd20e1 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/SecondaryColorExt.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef SECONDARY_COLOR_EXTENSION_H_ +#define SECONDARY_COLOR_EXTENSION_H_ + +#include "m64p.h" +#include "OpenGL.h" + +#ifndef GL_GLEXT_VERSION + #ifndef GL_EXT_secondary_color + #define GL_EXT_secondary_color 1 + + //Definitions + #define GL_COLOR_SUM_EXT 0x8458 + #define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 + #define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A + #define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B + #define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C + #define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D + #define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + + //Functions + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat r, GLfloat g, GLfloat b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble r, GLdouble g, GLdouble b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte r, GLbyte g, GLbyte b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort r, GLshort g, GLshort b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint r, GLint g, GLint b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC)(GLubyte r, GLubyte g, GLubyte b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC)(GLushort r, GLushort g, GLushort b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC)(GLuint r, GLuint g, GLuint b); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC)(const GLubyte *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC)(const GLushort *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC)(const GLuint *v); + typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC)(GLint size, GLenum type, GLsizei stride, void *pointer); + + #endif //GL_EXT_secondary_color + + // EXT_secondary_color functions + extern PFNGLSECONDARYCOLOR3BEXTPROC glSecondaryColor3bEXT; + extern PFNGLSECONDARYCOLOR3BVEXTPROC glSecondaryColor3bvEXT; + extern PFNGLSECONDARYCOLOR3DEXTPROC glSecondaryColor3dEXT; + extern PFNGLSECONDARYCOLOR3DVEXTPROC glSecondaryColor3dvEXT; + extern PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT; + extern PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT; + extern PFNGLSECONDARYCOLOR3IEXTPROC glSecondaryColor3iEXT; + extern PFNGLSECONDARYCOLOR3IVEXTPROC glSecondaryColor3ivEXT; + extern PFNGLSECONDARYCOLOR3SEXTPROC glSecondaryColor3sEXT; + extern PFNGLSECONDARYCOLOR3SVEXTPROC glSecondaryColor3svEXT; + extern PFNGLSECONDARYCOLOR3UBEXTPROC glSecondaryColor3ubEXT; + extern PFNGLSECONDARYCOLOR3UBVEXTPROC glSecondaryColor3ubvEXT; + extern PFNGLSECONDARYCOLOR3UIEXTPROC glSecondaryColor3uiEXT; + extern PFNGLSECONDARYCOLOR3UIVEXTPROC glSecondaryColor3uivEXT; + extern PFNGLSECONDARYCOLOR3USEXTPROC glSecondaryColor3usEXT; + extern PFNGLSECONDARYCOLOR3USVEXTPROC glSecondaryColor3usvEXT; + extern PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT; +#endif + +bool initializeSecondaryColorExtension(); + +#endif //SECONDARY_COLOR_EXTENSION_H_ diff --git a/source/mupen64plus-video-arachnoid/src/UCodeDefs.h b/source/mupen64plus-video-arachnoid/src/UCodeDefs.h new file mode 100755 index 0000000..c1d13d5 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/UCodeDefs.h @@ -0,0 +1,443 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef _UCODE_DEFS_H_ +#define _UCODE_DEFS_H_ + +//***************************************************************************** +// Matrices +//***************************************************************************** + +//! Add matrix struct used for example ucode F3D +struct RSPUCodeAddMatrix0 +{ + unsigned int length:16; //!< Length + unsigned int projection:1; //!< Is this a projection or view matrix? + unsigned int load:1; //!< Replace current matrix or multiply with it? + unsigned int push:1; //!< Save current matrix in stack? + unsigned int :5; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int segmentAddress; //!< Address to register where there is an RDRAM address used to retrieve matrix +}; + +//! Add matrix struct used for example ucode F3DEX2 +#pragma pack(push, 1) +struct RSPUCodeAddMatrixF3DEX2 +{ + union + { + struct + { + unsigned int param:8; //!< Push?, Load?, Projection? + unsigned int len:16; //!< Length + }; + struct + { + unsigned int nopush:1; //!< Save current matrix in stack? + unsigned int load:1; //!< Replace current matrix or multiply with it? + unsigned int projection:1; //!< Is this a projection or view matrix? + unsigned int :5; //!< Padding + unsigned int lenght:16; //!< Length + }; + }; + unsigned int cmd:8; //!< Command + unsigned int segmentAddress:32; //!< Address to register where there is an RDRAM address used to retrieve matrix +}; +#pragma pack(pop) +//***************************************************************************** +// Vertices +//***************************************************************************** + +//! Add vertices struct used for ucode F3D +struct RSPUCodeAddVertices0 +{ + unsigned int length:16; //!< Length + unsigned int firstVertex:4; //!< Index of first vertex + unsigned int numVertices:4; //!< Number of vertices minus one + unsigned int cmd:8; //!< Command + unsigned int segmentAddress; //!< Address to register where there is an RDRAM address used to retrieve vertices +}; +//! Add vertices struct used for ucode F3DEX +struct RSPUCodeAddVertices1 +{ + unsigned int length:10; //!< Length + unsigned int numVertices:6; //!< Number of vertices + unsigned int :1; //!< Padding + unsigned int firstVertex:7; //!< Index of first vertex + unsigned int cmd:8; //!< Command + unsigned int segmentAddress; //!< Address to register where there is an RDRAM address used to retrieve vertices +}; + +//! Add vertices struct used for ucode F3DEX2 +struct RSPUCodeAddVerticesF3DEX2 +{ + unsigned int pad0:1; //!< Padding + unsigned int vertexEnd:7; //!< Index of last vertex + unsigned int pad1:4; //!< Padding + unsigned int numVertices:8; //!< Number of vertices + unsigned int pad2:4; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int segmentAddress:32; //!< Address to register where there is an RDRAM address used to retrieve vertices +}; + +//! Add vertices struct used for ucode 9 (Perfect Dark) +struct RSPUCode9AddColorIndexVertices +{ + unsigned int pad0:16; //!< Padding + unsigned int firstVertexIndex:4; //!< Index of first vertex (where to place vertices in vertexbuffer) + unsigned int numVertices:4; //!< Add one + unsigned int cmd:8; //!< Command + unsigned int segmentAddress:32; //!< Address to register where there is an RDRAM address used to retrieve vertices +}; + +//! Add vertices struct used for ucode 4 (Wave Rave 64) +struct RSPUCodeAddVerticesWaveRace64 +{ + unsigned int pad0:8; //!< Padding + unsigned int pad1:1; //!< Padding + unsigned int numVertices:7; //!< Number of vertices + unsigned int firstVertexIndex:8; //!< Index of first vertex (where to place vertices in vertexbuffer)(divide by 5) + unsigned int cmd:8; //!< Command + unsigned int segmentAddress:32; //!< Address to register where there is an RDRAM address used to retrieve vertices +}; + +//***************************************************************************** +// One triangle +//***************************************************************************** + +//! Add triangle struct used for ucode F3D (and F3DEX) +struct RSPUCodeAddOneTriangleF3D +{ + unsigned int padding:24; //!< padding + unsigned int cmd:8; //!< Command + unsigned int index2:8; //!< Third vertex index (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race) + unsigned int index1:8; //!< Second vertex index (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race) + unsigned int index0:8; //!< First vertex index (divide by 10 in ucode F3D and 2 in F3DEX, 5 for wave race) + unsigned int flag:8; //!< ??? +}; + +//! Add triangle struct used for example ucode F3DEX +struct RSPUCodeAddOneTriangleF3DEX +{ + unsigned int padding:24; //!< padding + unsigned int cmd:8; //!< Command + unsigned int pad0:1; //!< Padding + unsigned int index2:7; //!< Third vertex index + unsigned int pad1:1; //!< Padding + unsigned int index1:7; //!< Second vertex index + unsigned int pad2:1; //!< Padding + unsigned int index0:7; //!< First vertex index + unsigned int pad3:8; //!< Padding +}; + +//! Add triangle struct used for ucode F3DEX2 +struct RSPUCodeAddOneTriangleF3DEX2 +{ + unsigned int index2:8; //!< Third vertex index + unsigned int index1:8; //!< Second vertex index + unsigned int index0:8; //!< First vertex index + unsigned int cmd:8; //!< Command + unsigned int pad:32; //!< padding +}; + +//***************************************************************************** +// Two triangles +//***************************************************************************** + +//! Add triangle struct used for adding two triangles +struct RSPUCodeAddTwoTrianglesWaveRace64 +{ + unsigned int v2:8; //!< Third vertex index for first triangle (divide by 5 for wave race) + unsigned int v1:8; //!< Second vertex index for first triangle (divide by 5 for wave race) + unsigned int v0:8; //!< First vertex index for first triangle (divide by 5 for wave race) + unsigned int cmd:8; //!< Command + unsigned int v5:8; //!< Third vertex index for second triangle (divide by 5 for wave race) + unsigned int v4:8; //!< Second vertex index for second triangle (divide by 5 for wave race) + unsigned int v3:8; //!< First vertex index for second triangle (divide by 5 for wave race) + unsigned int flag:8; //!< ??? +}; + +//! Add triangle struct used for adding two triangles +struct RSPUCodeAddTwoTrianglesF3DEX +{ + unsigned int pad0:1; //!< Padding + unsigned int v2:7; //!< Third vertex index for first triangle + unsigned int pad1:1; //!< Padding + unsigned int v1:7; //!< Second vertex index for first triangle + unsigned int pad2:1; //!< Padding + unsigned int v0:7; //!< First vertex index for first triangle + unsigned int cmd:8; //!< Command + unsigned int pad3:1; //!< Padding + unsigned int v5:7; //!< Third vertex index for second triangle + unsigned int pad4:1; //!< Padding + unsigned int v4:7; //!< Second vertex index for second triangle + unsigned int pad8:1; //!< Padding + unsigned int v3:7; //!< First vertex index for second triangle + unsigned int flag:8; //!< ??? +}; + +//***************************************************************************** +// Four triangles +//***************************************************************************** + +//! Add triangle struct used for adding four triangles, used by ucode F3D +struct RSPUCodeAddFourTrianglesF3D +{ + unsigned int v0:4; + unsigned int v3:4; + unsigned int v6:4; + unsigned int v9:4; + unsigned int pad:8; + unsigned int cmd:8; + unsigned int v1:4; + unsigned int v2:4; + unsigned int v4:4; + unsigned int v5:4; + unsigned int v7:4; + unsigned int v8:4; + unsigned int v10:4; + unsigned int v11:4; +}; + +//***************************************************************************** +// One Quad +//***************************************************************************** + +//! Add quad struct used for adding a rectangel, used by ucode F3D +struct RSPUCodeAddOneQuadF3D +{ + unsigned int pad0:24; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int index3:8; //!< (divide by 10, 5 for Wave Race) + unsigned int index2:8; //!< (divide by 10, 5 for Wave Race) + unsigned int index1:8; //!< (divide by 10, 5 for Wave Race) + unsigned int index0:8; //!< (divide by 10, 5 for Wave Race) +}; + +//! Add quad struct used for adding a rectangel, used by ucode F3DEX +struct RSPUCodeAddOneQuadF3DEX +{ + unsigned int pad0:24; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int pad1:1; //!< Padding + unsigned int index3:7; //!< Index of fourth vertex + unsigned int pad2:1; //!< Padding + unsigned int index2:7; //!< Index of third vertex + unsigned int pad3:1; //!< Padding + unsigned int index1:7; //!< Index of second vertex + unsigned int pad4:1; //!< Padding + unsigned int index0:7; //!< Index of first vertex +}; + +//! Add quad struct used for adding a rectangel, used by ucode F3DEX2 +struct RSPUCodeAddOneQuadF3DEX2 //aka TwoTriangles +{ + unsigned int v2:8; + unsigned int v1:8; + unsigned int v0:8; + unsigned int cmd:8; + unsigned int v5:8; + unsigned int v4:8; + unsigned int v3:8; + unsigned int pad0:8; +}; + +//***************************************************************************** +// Misc +//***************************************************************************** + +//! Struct used to set DMA Offsets (Mainly used by Diddy Kong Racing UCode6) +struct RSPUCodeSetDMAOffsets +{ + unsigned int addressOffsetMatrix:24; + unsigned int cmd:8; + unsigned int addressOffsetVertex:24; + unsigned int padding:8; +}; + +//! Struct used to set Vertex Color Base +struct RSPUCodeSetVertexColorBase +{ + unsigned int padding:24; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int rdramAddress:32; //!< Address to RDRAM where vertex colors are located. +}; + +//! Struct used to change display list +struct RSPUCodeDisplayList +{ + unsigned int padding:16; //!< Padding + unsigned int param:8; //!< Push display list or not? + unsigned int cmd:8; //!< Command + unsigned int segmentAddress:32; //!< +}; + +//! Struct used when modifying vertex data +struct RSPUCodeModifyVertex +{ + unsigned int pad0:1; //!< Padding + unsigned int vertexIndex:15; //!< Vertex Index (witch vertex to modify + unsigned int modifyType:8; //!< How to modify vertex (set color or texcoords?) + unsigned int cmd:8; //!< Command + union + { + unsigned int value:16; //!< Input values for vertex + struct + { + unsigned int a:8; //!< Alpha component of color + unsigned int b:8; //!< Blue component of color + unsigned int g:8; //!< Green component of color + unsigned int r:8; //!< Red component of color + }; + struct + { + unsigned int t:16; //!< Second value of texturecoord + unsigned int s:16; //!< First value of texturecoord + }; + }; +}; + +//***************************************************************************** +// Move Word +//***************************************************************************** + +//! Struct used to extract information in MoveWord instruction for ucode F3D +struct RSPUCodeMoveWordF3D +{ + unsigned int type:8; //!< Type of MoveWord + unsigned int offset:16; //!< Offset + unsigned int cmd:8; //!< Command + + union + { + unsigned int value:32; //!< Value + struct + { + unsigned int fo:16; //!< Fog + unsigned int fm:16; //!< Fog + }; + }; +}; + +//! Struct used to extract information in MoveWord instruction for ucode F3DEX2 +struct RSPUCodeMoveWordF3DEX2 +{ + unsigned int offset:16; //!< Offset + unsigned int type:8; //!< Type of MoveWord + unsigned int cmd:8; //!< Command + union + { + unsigned int value:32; //!< Value + struct + { + unsigned int fo:16; //!< Fog + unsigned int fm:16; //!< Fog + }; + }; +}; + +//***************************************************************************** +//* Texture +//! Struct used when retriving texture information on RSP +//***************************************************************************** +struct RSPUCodeTexture +{ + unsigned int enable_gbi0:1; + unsigned int enable_gbi2:1; + unsigned int :6; + unsigned int tile:3; + unsigned int level:3; + unsigned int :10; + unsigned int cmd:8; + unsigned int scaleT:16; + unsigned int scaleS:16; +}; + +//***************************************************************************** +//* RSPUCodeLoadUCode +//! Struct used when changing ucode on RSP +//***************************************************************************** +struct RSPUCodeLoadUCode +{ + unsigned int ucodeSize:16; //!< UCode size, note: Add one + unsigned int padding:8; //!< Padding? + unsigned int cmd:8; //!< Command + unsigned int ucodeStart:32; //!< UCode Start +}; + + +//***************************************************************************** +// Display List +//***************************************************************************** + +//! Struct used to cull displaylist +struct RSPUCodeCullDisplayList +{ + unsigned int pad0:1; //!< Padding + unsigned int vertexIndex:15; //!< First vertex index to vertices to cull + unsigned int pad2:8; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int pad3:1; //!< Padding + unsigned int numVerticies:15; //!< Number of vertices to cull + unsigned int pad4:8; //!< Padding +}; + +//! Used by instruction branch display list by ucode F3DEX +struct RSPUCodeBranchZF3DEX +{ + unsigned int pad0:1; //!< Padding + unsigned int vertex:11; //!< Vertex to retrive z value from + unsigned int pad1:12; //!< Padding + unsigned int cmd:8; //!< Command + unsigned int zvalue:32; //!< z value used to compare with +}; + +//***************************************************************************** +// Others +//***************************************************************************** + +//typedef struct { +// union { +// unsigned int w0; +// struct { +// unsigned int arg0:24; +// unsigned int cmd:8; +// }; +// }; +// unsigned int w1; +//} Gwords; + +//! Stuct used to give GBI instructions input data as function argument. +typedef union { + struct { + union { + unsigned int w0; + struct { + unsigned int arg0:24; + unsigned int cmd:8; + }; + }; + unsigned int w1; + }; + long long int force_structure_alignment; +} MicrocodeArgument; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/VI.cpp b/source/mupen64plus-video-arachnoid/src/VI.cpp new file mode 100755 index 0000000..08c43a6 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/VI.cpp @@ -0,0 +1,82 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "VI.h" +#include "GBIDefs.h" //_FIXED2FLOAT, _SHIFTR +#include "m64p.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +VI::VI() +{ + m_width = 320; + m_height = 240; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +VI::~VI() +{ + +} + +//----------------------------------------------------------------------------- +//* Calculate Size +//! Calculates width and height of video interface +//----------------------------------------------------------------------------- +void VI::calcSize(GFX_INFO* graphicsInfo) +{ + //Get video interface values + //unsigned int viScaleX = *graphicsInfo->VI_X_SCALE_REG; + //unsigned int viScaleY = *graphicsInfo->VI_X_SCALE_REG; + unsigned int viStartHorizontal = *graphicsInfo->VI_H_START_REG; + unsigned int viStartVertical = *graphicsInfo->VI_V_START_REG; + + //Get Scale + float xScale = _FIXED2FLOAT(_SHIFTR(*graphicsInfo->VI_X_SCALE_REG, 0, 12), 10); + float yScale = _FIXED2FLOAT(_SHIFTR(*graphicsInfo->VI_Y_SCALE_REG, 0, 12), 10); + + //Get Offsets (no need for these?) + //float xOffset = _FIXED2FLOAT(_SHIFTR(viScaleX, 16, 12), 10); + //float yOffset = _FIXED2FLOAT(_SHIFTR(viScaleY, 16, 12), 10); + + //Get horizontal coordinats + unsigned int hEnd = _SHIFTR( viStartHorizontal, 0, 10 ); + unsigned int hStart = _SHIFTR( viStartHorizontal, 16, 10 ); + + //Get vertical coordinats + // These are in half-lines, so shift an extra bit + unsigned int vEnd = _SHIFTR( viStartVertical, 1, 9 ); + unsigned int vStart = _SHIFTR( viStartVertical, 17, 9 ); + + //Calculate size + m_width = (int)((hEnd - hStart) * xScale); + m_height = (int)((vEnd - vStart) * yScale * 1.0126582f); + + //If Zero: Set to defaults + if ( m_width == 0.0f ) m_width = 320; + if ( m_height == 0.0f ) m_height = 240; + + //m_width = 320; + //m_height = 240; +} diff --git a/source/mupen64plus-video-arachnoid/src/VI.h b/source/mupen64plus-video-arachnoid/src/VI.h new file mode 100755 index 0000000..6df4782 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/VI.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef VIDEO_INTERFACE_H_ +#define VIDEO_INTERFACE_H_ + +//Forward declarations +#define M64P_PLUGIN_PROTOTYPES 1 +#include "UCodeDefs.h" +#include "m64p_plugin.h" + +//***************************************************************************** +//! Video Interface +//***************************************************************************** +class VI +{ +public: + + //Constructor + VI(); + ~VI(); + + //Calculate height and width + void calcSize(GFX_INFO* graphicsInfo); + + //Get Height and Width + unsigned int getWidth() { return m_width; } + unsigned int getHeight() { return m_height; } + +private: + + unsigned int m_width; //!< Width of video interface viewport + unsigned int m_height; //!< Height of video interface viewport + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/config/Config.cpp b/source/mupen64plus-video-arachnoid/src/config/Config.cpp new file mode 100755 index 0000000..69f9a0a --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/Config.cpp @@ -0,0 +1,87 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "Config.h" +#include +#include "GraphicsPlugin.h" +#include "Logger.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +Config::Config(GraphicsPlugin* graphicsPlugin) +{ + m_graphicsPlugin = graphicsPlugin; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +Config::~Config() +{ +} + +bool Config::initialize() +{ + if (ConfigOpenSection("Video-General", &m_videoGeneralSection) != M64ERR_SUCCESS || + ConfigOpenSection("Video-Arachnoid", &m_videoArachnoidSection) != M64ERR_SUCCESS) + { + Logger::getSingleton().printMsg("Could not open configuration", M64MSG_ERROR); + return false; + } + + ConfigSetDefaultBool(m_videoGeneralSection, "Fullscreen", false, "Use fullscreen mode if True, or windowed mode if False"); + ConfigSetDefaultInt(m_videoGeneralSection, "ScreenWidth", 640, "Width of output window or fullscreen width"); + ConfigSetDefaultInt(m_videoGeneralSection, "ScreenHeight", 480, "Height of output window or fullscreen height"); + ConfigSetDefaultInt(m_videoArachnoidSection, "ColorDepth", 32, "Color bit-depth in fullscreen mode"); + ConfigSetDefaultInt(m_videoArachnoidSection, "RefreshRate", 60, "Screen refresh-rate in fullscreen mode"); + ConfigSetDefaultInt(m_videoArachnoidSection, "TextureCacheSize", 15 * (1024 * 1024), "Size of texture cache used to store textures"); + ConfigSetDefaultBool(m_videoArachnoidSection, "Wireframe", false, "Render in wireframe?"); + ConfigSetDefaultBool(m_videoArachnoidSection, "Fog", false, "Render fog?"); + ConfigSetDefaultInt(m_videoArachnoidSection, "MultiSampling", 0, "Use MultiSampling? 0=no 2,4,8,16=quality"); + ConfigSetDefaultInt(m_videoArachnoidSection, "Mipmapping", 0, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear"); +#ifdef WIN32 + ConfigSetDefaultInt(m_videoArachnoidSection, "ScreenUpdateSetting", SCREEN_UPDATE_CI, "When to update the screen: 1 - on VI, 2 - on first CI"); +#else + ConfigSetDefaultInt(m_videoArachnoidSection, "ScreenUpdateSetting", SCREEN_UPDATE_VI, "When to update the screen: 1 - on VI, 2 - on first CI"); +#endif + ConfigSetDefaultBool(m_videoArachnoidSection, "FrameSkip", false, "Use FrameSkipping?"); + return true; +} + +void Config::load() +{ + m_cfg.fullscreenWidth = ConfigGetParamInt(m_videoGeneralSection, "ScreenWidth"); + m_cfg.fullscreenHeight = ConfigGetParamInt(m_videoGeneralSection, "ScreenHeight"); + m_cfg.fullscreenBitDepth = ConfigGetParamInt(m_videoArachnoidSection, "ColorDepth"); + m_cfg.fullscreenRefreshRate = ConfigGetParamInt(m_videoArachnoidSection, "RefreshRate"); + m_cfg.windowWidth = ConfigGetParamInt(m_videoGeneralSection, "ScreenWidth"); + m_cfg.windowHeight = ConfigGetParamInt(m_videoGeneralSection, "ScreenHeight"); + m_cfg.startFullscreen = ConfigGetParamBool(m_videoGeneralSection, "Fullscreen"); + m_cfg.textureCacheSize = ConfigGetParamInt(m_videoArachnoidSection, "TextureCacheSize"); + m_cfg.wireframe = ConfigGetParamBool(m_videoArachnoidSection, "Wireframe"); + m_cfg.fog = ConfigGetParamBool(m_videoArachnoidSection, "Fog"); + m_cfg.multiSampling = ConfigGetParamBool(m_videoArachnoidSection, "MultiSampling"); + m_cfg.mipmapping = ConfigGetParamInt(m_videoArachnoidSection, "Mipmapping"); + m_cfg.screenUpdateSetting = ConfigGetParamInt(m_videoArachnoidSection, "ScreenUpdateSetting"); + m_cfg.frameSkip = ConfigGetParamBool(m_videoArachnoidSection, "FrameSkip"); +} diff --git a/source/mupen64plus-video-arachnoid/src/config/Config.h b/source/mupen64plus-video-arachnoid/src/config/Config.h new file mode 100755 index 0000000..0dffe32 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/Config.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef CONFIG_H_ +#define CONFIG_H_ + +#include "m64p.h" +#include "ConfigMap.h" + +//Forward declaration +class GraphicsPlugin; + +//***************************************************************************** +//* Config +//! Manages configuration of graphics plugin +//! +//! Responability: +//! * Loads config data from core +//! * Sets default config values +//! +//! @see ConfigMap +//***************************************************************************** +class Config +{ +public: + + //Constructor / Destructor + Config(GraphicsPlugin* graphicsPlugin); + ~Config(); + + bool initialize(); + + //Loads settings from core + void load(); + + //Tell Graphics plugin that config has changed + void updateGraphics(); + +public: + + //Get configuration + ConfigMap* getConfig() { return &m_cfg; } + +private: + + ConfigMap m_cfg; //!< Config map with all settings + GraphicsPlugin* m_graphicsPlugin; //!< Pointer to graphics plugin + + m64p_handle m_videoGeneralSection; + m64p_handle m_videoArachnoidSection; +}; + +enum +{ + SCREEN_UPDATE_VI = 1, + SCREEN_UPDATE_CI = 2 +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/config/ConfigMap.h b/source/mupen64plus-video-arachnoid/src/config/ConfigMap.h new file mode 100755 index 0000000..b0d75bf --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/ConfigMap.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef CONFIG_MAP_H_ +#define CONFIG_MAP_H_ + +//***************************************************************************** +//! Struct with all configuration settings are stored +//***************************************************************************** +struct ConfigMap +{ + //Configuration Settings + int fullscreenWidth; //!< Display width in fullscreen mode, default = 800 + int fullscreenHeight; //!< Display height in fullscreen mode, default = 600 + int fullscreenRefreshRate; //!< Screen refresh-rate in fullscreen mode, default = 60 + int fullscreenBitDepth; //!< Bitdepth in fullscreen mode, default = 32 + bool startFullscreen; //!< Whether to start in fullscreen mode, default = false + int windowWidth; //!< Width of render window in window mode, default = 800 + int windowHeight; //!< Height of render window in window mode, default = 600 + int textureCacheSize; //!< Size of texture cache used to store textures, default = 15 MB + bool wireframe; //!< Render in wireframe? defualt = false + bool fog; //!< Render fog? default = true + int multiSampling; //!< Use MultiSampling? 0=no 2,4,8,16=quality default = 0 + int mipmapping; //!< Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear default = 0 + int screenUpdateSetting; //!< When to redraw the screen default = SCREEN_UPDATE_VI + bool frameSkip; //!< Use frameskipping? +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp new file mode 100755 index 0000000..eddb9fa --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.cpp @@ -0,0 +1,155 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "StringFunctions.h" +#include +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 split(const string& str, const string& delims, size_t maxSplits) +{ + size_t pos; + size_t start = 0; + vector 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 split(const char* str, const std::string& delims) +{ + return split(string(str), delims); +} + + +} //namespace StringFunctions diff --git a/source/mupen64plus-video-arachnoid/src/config/StringFunctions.h b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.h new file mode 100755 index 0000000..beef848 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/StringFunctions.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +/* +What is the difference between '\n' and '\r\n'? +----------------------------------------------- + +There are a few characters which can indicate a new line. The usual ones are these two: + + * '\n' or '0x0A' (10 in decimal) -> This character is called "Line Feed" (LF). + * '\r' or '0x0D' (13 in decimal) -> This one is called "Carriage return" (CR). + +Different Operating Systems handle newlines in a different way. Here is a short list of the most common ones: + + * DOS and Windows + They expect a newline to be the combination of two characters, namely '\r\n' (or 13 followed by 10). + + * Unix (and hence Linux as well) + Unix uses a single '\n' to indicate a new line. + + * Mac + Macs use a single '\r'. + +To unify things a bit, so that writing portable C/C++ programs is possible, file streams have both a +"translated" and an "untranslated" mode. If you open a file in translated mode, the runtime library +will convert a '\n' to the appropriate newline character(s). If the following program is compiled under +Unix, the file will contain a single LF to indicate the newline. If it's compiled under windows, it will +contain a CRLF. + +#include +#include +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 +#include +#include +#include //std::transform + +namespace StringFunctions +{ + //Split + std::vector split(const std::string& str, const std::string& delims="\n\t ", size_t maxSplits=std::string::npos); + std::vector split(const char* str, const std::string& delims="\n\t "); + + //Trim + void trim(std::string& str, bool left=true, bool right=true, const std::string delims=" \t\r\n"); + + //Trim + char* trim(char* str, bool left=true, bool right=true); +} + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/config/StringValue.h b/source/mupen64plus-video-arachnoid/src/config/StringValue.h new file mode 100755 index 0000000..1462585 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/config/StringValue.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef STRING_VALUE_H_ +#define STRING_VALUE_H_ +#include +#include +#include + +//! 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 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 bool operator==(T x) const { return (x == T(*this)); } + // conversion operators + operator bool() const { + if (data=="false" || data=="0") return false; + return true; + } + operator float() const { + return (float) atof(data.c_str()); + } + operator double() const { + return atof(data.c_str()); + } + operator char() const { + char x; + std::stringstream ss; ss << data; ss >> x; + return x; + } + operator unsigned char() const { + unsigned char x; + std::stringstream ss; ss << data; ss >> x; + return x; + } + operator int() const { + return atoi(data.c_str()); + } + operator short() const { + return (short) atoi(data.c_str()); + } + operator long() const { + return atol(data.c_str()); + } + operator unsigned short() const { + unsigned short x; + std::stringstream ss; ss << data; ss >> x; + return x; + } + operator unsigned int() const { + unsigned int x; + std::stringstream ss; ss << data; ss >> x; + return x; + } + operator unsigned long() const { + unsigned int x; + std::stringstream ss; ss << data; ss >> x; + return x; + } + operator const char *() const { + return data.c_str(); + } + + std::string str() const { return data; } +private: + std::string data; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp new file mode 100755 index 0000000..31255da --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp @@ -0,0 +1,371 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "FrameBuffer.h" +#include "m64p.h" +#include "OpenGL.h" + +#ifndef GL_GLEXT_VERSION +#ifndef HAVE_GLES + //----------------------------------------------------------------------------- + //OpenGL Texture Definitions + //----------------------------------------------------------------------------- + typedef GLvoid (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum texture); + PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; +#endif +#endif + +#ifndef GL_TEXTURE0 + #define GL_TEXTURE0 0x84C0 +#endif +#ifndef GL_CLAMP_TO_EDGE + #define GL_CLAMP_TO_EDGE 0x812F +#endif + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +FrameBuffer::FrameBuffer() +{ + m_id = ~0U; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +FrameBuffer::~FrameBuffer() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialize +//! @param width Width of framebuffer, usually equal to window-client-width +//! @param height Height of framebuffer, usually equal to window-client-height +//----------------------------------------------------------------------------- +void FrameBuffer::initialize(int width, int height) +{ + //Save parameters + m_width = width; + m_height = height; + int channels = 3; //!< RGB=3 or RGBA=4 + + //Allocate memory + unsigned char* data = new unsigned char[width * height * channels]; + memset(data, 0, width * height * channels * sizeof(unsigned char)); + + //Register the texture with OpenGL and bind it to the texture ID + glGenTextures(1, &m_id); + glBindTexture(GL_TEXTURE_2D, m_id); + + //Create the texture and store it on the video card +#ifdef HAVE_GLES + if (channels == 3) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); +#else + glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +#endif + + //No texure filtering + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1 ); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + //Clamp texture to edges + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + //Delete data (no need for it when it is stored in video card) + delete[] data; + data = 0; +} + +//----------------------------------------------------------------------------- +// Dispose +//----------------------------------------------------------------------------- +void FrameBuffer::dispose() +{ + if ( m_id != ~0U ) + { + glDeleteTextures(1, &m_id); + m_id = -1; + } +} + +//----------------------------------------------------------------------------- +// Resize +//----------------------------------------------------------------------------- +void FrameBuffer::resize(int width, int height) +{ + dispose(); + initialize(width, height); +} + +//----------------------------------------------------------------------------- +//* Begin Rendering +//! +//----------------------------------------------------------------------------- +void FrameBuffer::beginRendering() +{ + //Get viewport + glGetIntegerv(GL_VIEWPORT, m_oldViewport); + + //Set new viewport for texture + //glViewport(0, 20, m_width, m_height); + + //glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + //glClear(GL_COLOR_BUFFER_BIT); + //glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + + //Clear Buffers + // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +//----------------------------------------------------------------------------- +//* End Rendering +//! Will save all rendering to a texture +//----------------------------------------------------------------------------- +void FrameBuffer::endRendering() +{ + //Activate texture + _activate(); + + //Render to Texture + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 20, m_width, m_height ); + + //TODO Deactivate texture? + //_deactivate(); + + //Reset Viewport + //glViewport(m_oldViewport[0], m_oldViewport[1], m_oldViewport[2], m_oldViewport[3]); + + //Clear Buffers + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +//----------------------------------------------------------------------------- +//* Render +//! Will render frame buffer to screen. +//----------------------------------------------------------------------------- +void FrameBuffer::render() +{ + //Push states + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f ); + //glViewport( 0, 0, m_width, m_height ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + //glPushAttrib(GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + + //Render QUAD (using framebuffer texture) + _activate(); + { +#ifdef HAVE_GLES + GLfloat tex[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + GLfloat vtx[] = { + -1, -1, 0, + 0, -1, 0, + 0, 0, 0, + -1, 0, 0 + }; + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + + GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY); + if (glcol) glDisableClientState(GL_COLOR_ARRAY); + GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY); + if (!glvtx) + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT, 0,&vtx); + glActiveTexture( GL_TEXTURE1 ); + GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D); + if (gltex1) glDisable(GL_TEXTURE_2D); + glActiveTexture( GL_TEXTURE0 ); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex); + // draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // restaure + if (glcol) glEnableClientState(GL_COLOR_ARRAY); + glActiveTexture( GL_TEXTURE1 ); + if (gltex1) glEnable(GL_TEXTURE_2D); + if (!glvtx) + glDisableClientState(GL_VERTEX_ARRAY); + else + glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array ); + glActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array ); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +#else + glBegin(GL_QUADS); + { + glColor3f(0.0f, 0.0f, 1.0f); + glTexCoord2f(0,0); + glVertex3f(-1,-1,0); + glTexCoord2f(1,0); + glVertex3f( 0,-1,0); + glTexCoord2f(1,1); + glVertex3f( 0, 0,0); + glTexCoord2f(0,1); + glVertex3f(-1, 0,0); + glColor3f(1.0f, 1.0f, 1.0f); + } + glEnd(); +#endif + } + _deactivate(); + + //Pop states + //glPopAttrib(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); +} + +//----------------------------------------------------------------------------- +//* Render +//! Will render frame buffer to screen. +//----------------------------------------------------------------------------- +void FrameBuffer::render2() +{ + //Push states + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f ); + //glViewport( 0, 0, m_width, m_height ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + //glPushAttrib(GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + + //Render QUAD (using framebuffer texture) + _activate(); + { +#ifdef HAVE_GLES + GLfloat tex[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + GLfloat vtx[] = { + -1, -1, 0, + 0, -1, 0, + 0, 0, 0, + -1, 0, 0 + }; + + GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY); + if (glcol) glDisableClientState(GL_COLOR_ARRAY); + GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY); + if (!glvtx) + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT, 0,&vtx); + glActiveTexture( GL_TEXTURE1 ); + GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D); + if (gltex1) glDisable(GL_TEXTURE_2D); + glActiveTexture( GL_TEXTURE0 ); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex); + // draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // restaure + if (glcol) glEnableClientState(GL_COLOR_ARRAY); + glActiveTexture( GL_TEXTURE1 ); + if (gltex1) glEnable(GL_TEXTURE_2D); + if (!glvtx) + glDisableClientState(GL_VERTEX_ARRAY); + else + glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array ); + glActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array ); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); +#else + glBegin(GL_QUADS); + { + glTexCoord2f(0,0); + glVertex3f(-1,-1,0); + glTexCoord2f(1,0); + glVertex3f( 1,-1,0); + glTexCoord2f(1,1); + glVertex3f( 1, 1,0); + glTexCoord2f(0,1); + glVertex3f(-1, 1,0); + glColor3f(1.0f, 1.0f, 1.0f); + } + glEnd(); +#endif + } + _deactivate(); + + //Pop states + //glPopAttrib(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); +} + +//----------------------------------------------------------------------------- +// Activate +//----------------------------------------------------------------------------- +void FrameBuffer::_activate() +{ + //Activate Texture (so we can copy to it) +#ifndef GL_GLEXT_VERSION +#ifndef HAVE_GLES + if ( glActiveTexture == 0 ) { + glActiveTexture = (PFNGLACTIVETEXTUREPROC) CoreVideo_GL_GetProcAddress("glActiveTexture"); + } +#endif +#endif + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_id); +} + +//----------------------------------------------------------------------------- +// Deactivate +//----------------------------------------------------------------------------- +void FrameBuffer::_deactivate() +{ + glActiveTexture((GLuint)GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h new file mode 100755 index 0000000..2285ce3 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef FRAME_BUFFER_H_ +#define FRAME_BUFFER_H_ + + +//***************************************************************************** +//* FrameBuffer +//! A Texture that we can render to. +//***************************************************************************** +class FrameBuffer +{ +public: + + //Get Singleton + //static FrameBuffer& getSingleton() { + // static FrameBuffer instance; + // return instance; + //} + + //Constructor + FrameBuffer(); + + //Destructor + ~FrameBuffer(); + + void initialize(int width, int height); + void dispose(); + void resize(int width, int height); + void beginRendering(); + void endRendering(); + void render(); + void render2(); + +protected: + + void _activate(); + void _deactivate(); + +private: + + + +protected: + + unsigned int m_id; //!< TextureID, Used mainly for OpenGL (so it can keep track of textures) + int m_width; //!< Width of framebuffer + int m_height; //!< Height of framebuffer + + int m_oldViewport[4]; + + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp new file mode 100755 index 0000000..57a1806 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp @@ -0,0 +1,161 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "CRCCalculator.h" + +#define CRC32_POLYNOMIAL 0xedb88320L //0x04C11DB7 +typedef unsigned char byte; + +//----------------------------------------------------------------------------- +// Static Variabels +//----------------------------------------------------------------------------- +unsigned int CRCCalculator::m_crcTable[256] = {0}; + +static unsigned int crc_table[256]; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +CRCCalculator::CRCCalculator() +{ + static bool hashTableInitialized = false; + + //Build hash table + //http://www.gamedev.net/reference/articles/article1941.asp + if ( !hashTableInitialized ) + { + // unsigned int crc; + + // //For each value + // for (int i=0; i<256; i++) + //{ + // crc = _reflect( i, 8 ) << 24; + + // for (int j = 0; j < 8; j++) + // { + // crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); + // } + // + // m_crcTable[i] = _reflect( crc, 32 ); + // } + + unsigned int crc; + unsigned int poly; // polynomial exclusive-or pattern + // terms of polynomial defining this crc (except x^32): + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (unsigned int n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + { + poly |= 1L << (31 - p[n]); + } + + for (int n=0; n<256; ++n) + { + crc = (unsigned int)n; + + for (int k = 0; k < 8; k++) + { + crc = (crc & 1) ? (poly ^ (crc >> 1)) : crc >> 1; + } + crc_table[n] = crc; + } + + hashTableInitialized = true; + } +} + +//----------------------------------------------------------------------------- +// CalculateCRC +//----------------------------------------------------------------------------- +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO1b(buf) crc = (crc >> 8) ^ crc_table[(crc & 0xFF) ^ *buf++] +unsigned int CRCCalculator::calcCRC(unsigned int crc, void *buffer, unsigned int count) +{ + byte* p = (byte*) buffer; + //unsigned int orig = crc; + + // p = (byte*) buffer; + // while (count--) + // { + // crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + // } + + // return crc ^ orig; + + if (buffer == 0) return 0L; + + crc = crc ^ 0xffffffffL; + while (count--) + { + crc = crc_table[((int)crc ^ (*p++)) & 0xff] ^ (crc >> 8); + } + // if (len) do { + // DO1(buf); + // } while (--len); + return crc ^ 0xffffffffL; +} + +//----------------------------------------------------------------------------- +// CalculatePaletteCRC +//----------------------------------------------------------------------------- +unsigned int CRCCalculator::calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count) +{ + byte *p; + unsigned int orig = crc; + + p = (byte*) buffer; + while (count--) + { + crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + + p += 6; + } + + return crc ^ orig; +} + +//***************************************************************************** +// Private Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Reflect +//! Help function when creating the CRC Table +//! Swaps bit 0 for bit 7 +//! bit 1 for bit 6 +//! bit 2 for bit 5 ... +//----------------------------------------------------------------------------- +unsigned int CRCCalculator::_reflect(unsigned int ref, char ch) +{ + unsigned int value = 0; + for (int i=1; i<(ch + 1); ++i) + { + if(ref & 1) + { + value |= 1 << (ch - i); + } + ref >>= 1; + } + return value; +} diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h new file mode 100755 index 0000000..06629eb --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef CYCLIC_REDUNDANCY_CHECK_CALCULATOR_H_ +#define CYCLIC_REDUNDANCY_CHECK_CALCULATOR_H_ + +//***************************************************************************** +//! Cyclic Redundancy Check Calculator +//! CRC is a type of hash function which is used to produce a small, +//! fixed-size checksum of a larger block of data. +//! +//! Often used in networks for reducing errors caused by noise. +//! +//! http://en.wikipedia.org/wiki/CRC32 +//! http://en.wikipedia.org/wiki/Hash_function +//! http://en.wikipedia.org/wiki/Hash_table +//! http://www.gamedev.net/reference/articles/article1941.asp +//! http://www.codeproject.com/cpp/crc32_large.asp +//***************************************************************************** +class CRCCalculator +{ +public: + + //Constructor + CRCCalculator(); + + //Functions for calculating crc values + unsigned int calcCRC(unsigned int crc, void *buffer, unsigned int count); + unsigned int calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count); + +private: + + //Help function used to build hash table + unsigned int _reflect(unsigned int ref, char ch); + +private: + + static unsigned int m_crcTable[256]; //!< Hash table that associates keys with values +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp new file mode 100755 index 0000000..f0950da --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp @@ -0,0 +1,122 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "CRCCalculator2.h" + +#define CRC32_POLYNOMIAL 0xedb88320 //0x04C11DB7 +typedef unsigned char byte; + +//----------------------------------------------------------------------------- +// Static Variabels +//----------------------------------------------------------------------------- +unsigned int CRCCalculator2::m_crcTable[256] = {0}; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +CRCCalculator2::CRCCalculator2() +{ + static bool hashTableInitialized = false; + + //Build hash table + //http://www.gamedev.net/reference/articles/article1941.asp + if ( !hashTableInitialized ) + { + unsigned int crc; + + //For each value + for (int i=0; i<256; i++) + { + crc = _reflect( i, 8 ) << 24; + + for (int j = 0; j < 8; j++) + { + crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); + } + + m_crcTable[i] = _reflect( crc, 32 ); + } + + hashTableInitialized = true; + } +} + +//----------------------------------------------------------------------------- +// CalculateCRC +//----------------------------------------------------------------------------- +unsigned int CRCCalculator2::calcCRC(unsigned int crc, void *buffer, unsigned int count) +{ + byte* p = (byte*) buffer; + unsigned int orig = crc; + + p = (byte*) buffer; + while (count--) + { + crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + } + + return crc ^ orig; +} + +//----------------------------------------------------------------------------- +// CalculatePaletteCRC +//----------------------------------------------------------------------------- +unsigned int CRCCalculator2::calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count) +{ + byte *p; + unsigned int orig = crc; + + p = (byte*) buffer; + while (count--) + { + crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + crc = (crc >> 8) ^ m_crcTable[(crc & 0xFF) ^ *p++]; + + p += 6; + } + + return crc ^ orig; +} + +//***************************************************************************** +// Private Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Reflect +//! Help function when creating the CRC Table +//! Swaps bit 0 for bit 7 +//! bit 1 for bit 6 +//! bit 2 for bit 5 ... +//----------------------------------------------------------------------------- +unsigned int CRCCalculator2::_reflect(unsigned int ref, char ch) +{ + unsigned int value = 0; + for (int i=1; i<(ch + 1); ++i) + { + if(ref & 1) + { + value |= 1 << (ch - i); + } + ref >>= 1; + } + return value; +} diff --git a/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h new file mode 100755 index 0000000..7082bc8 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef CYCLIC_REDUNDANCY_CHECK_CALCULATOR_2_H_ +#define CYCLIC_REDUNDANCY_CHECK_CALCULATOR_2_H_ + +//***************************************************************************** +//! Cyclic Redundancy Check Calculator +//! CRC is a type of hash function which is used to produce a small, +//! fixed-size checksum of a larger block of data. +//! +//! Often used in networks for reducing errors caused by noise. +//! +//! http://en.wikipedia.org/wiki/CRC32 +//! http://en.wikipedia.org/wiki/Hash_function +//! http://en.wikipedia.org/wiki/Hash_table +//! http://www.gamedev.net/reference/articles/article1941.asp +//! http://www.codeproject.com/cpp/crc32_large.asp +//***************************************************************************** +class CRCCalculator2 +{ +public: + + //Constructor + CRCCalculator2(); + + //Functions for calculating crc values + unsigned int calcCRC(unsigned int crc, void *buffer, unsigned int count); + unsigned int calcPaletteCRC(unsigned int crc, void *buffer, unsigned int count); + +private: + + //Help function used to build hash table + unsigned int _reflect(unsigned int ref, char ch); + +private: + + static unsigned int m_crcTable[256]; //!< Hash table that associates keys with values +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/log/Logger.cpp b/source/mupen64plus-video-arachnoid/src/log/Logger.cpp new file mode 100755 index 0000000..193a8eb --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/log/Logger.cpp @@ -0,0 +1,67 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "Logger.h" + +//----------------------------------------------------------------------------- +//* Initialize +//! Initializes log with debug callback +//----------------------------------------------------------------------------- +bool Logger::initialize(void (*debugCallback)(void*, int, const char*), void *context) +{ + m_debugCallback = debugCallback; + m_debugCallContext = context; + + return true; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +Logger::~Logger() +{ + dispose(); +} + +//----------------------------------------------------------------------------- +//* Dispose +//! Closes log file +//----------------------------------------------------------------------------- +void Logger::dispose() +{ + m_debugCallback = NULL; + m_debugCallContext = NULL; +} + +//----------------------------------------------------------------------------- +//* Print Message +//! Writes a message to log-file and/or console. +//! @param msg The text message to write to log-file. +//! @param lml How important the message is. Error message are more important then warnings for example. +//----------------------------------------------------------------------------- +void Logger::printMsg(const char* msg, m64p_msg_level lml) +{ + if (m_debugCallback != NULL) + { + (*m_debugCallback)(m_debugCallContext, lml, msg); + } +} diff --git a/source/mupen64plus-video-arachnoid/src/log/Logger.h b/source/mupen64plus-video-arachnoid/src/log/Logger.h new file mode 100755 index 0000000..168b44b --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/log/Logger.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include "m64p_types.h" + +//***************************************************************************** +//***************************************************************************** +//* Log +//! Class for sending log messages to M64P +//***************************************************************************** +class Logger +{ +public: + //Destructor + ~Logger(); + + //Singleton Instance + static Logger& getSingleton() + { + static Logger pInstance; + return pInstance; + } + + //Initialize / Dispose + bool initialize(void (*debugCallback)(void*, int, const char*), void *context); + void dispose(); + + //Message + void printMsg(const char* msg, m64p_msg_level lml=M64MSG_VERBOSE); + +protected: + //! Constructor + Logger() { m_debugCallback = NULL; m_debugCallContext = NULL; } + +protected: + void (*m_debugCallback)(void *, int, const char *); + void *m_debugCallContext; +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/m64p.h b/source/mupen64plus-video-arachnoid/src/m64p.h new file mode 100755 index 0000000..e0ce6c0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/m64p.h @@ -0,0 +1,71 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef M64P_H +#define M64P_H + +#ifdef WIN32 + #include +#else + #include + #include + + #define BOOL int +#endif + +#define M64P_PLUGIN_PROTOTYPES 1 +#include "m64p_types.h" +#include "m64p_plugin.h" +#include "m64p_config.h" +#include "m64p_vidext.h" + +/* definitions of pointers to Core config functions */ +extern ptr_ConfigOpenSection ConfigOpenSection; +extern ptr_ConfigSetParameter ConfigSetParameter; +extern ptr_ConfigGetParameter ConfigGetParameter; +extern ptr_ConfigGetParameterHelp ConfigGetParameterHelp; +extern ptr_ConfigSetDefaultInt ConfigSetDefaultInt; +extern ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat; +extern ptr_ConfigSetDefaultBool ConfigSetDefaultBool; +extern ptr_ConfigSetDefaultString ConfigSetDefaultString; +extern ptr_ConfigGetParamInt ConfigGetParamInt; +extern ptr_ConfigGetParamFloat ConfigGetParamFloat; +extern ptr_ConfigGetParamBool ConfigGetParamBool; +extern ptr_ConfigGetParamString ConfigGetParamString; + +extern ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath; +extern ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath; +extern ptr_ConfigGetUserDataPath ConfigGetUserDataPath; +extern ptr_ConfigGetUserCachePath ConfigGetUserCachePath; + +/* definitions of pointers to Core video extension functions */ +extern ptr_VidExt_Init CoreVideo_Init; +extern ptr_VidExt_Quit CoreVideo_Quit; +extern ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes; +extern ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode; +extern ptr_VidExt_SetCaption CoreVideo_SetCaption; +extern ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen; +extern ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow; +extern ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress; +extern ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute; +extern ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/main.cpp b/source/mupen64plus-video-arachnoid/src/main.cpp new file mode 100755 index 0000000..bc8360e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/main.cpp @@ -0,0 +1,453 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +//Includes +#define M64P_PLUGIN_PROTOTYPES 1 +#include "m64p.h" +#include "GraphicsPlugin.h" //Main class +#include "config/Config.h" //Configuration +#include "Logger.h" //Debug logger +#include "MemoryLeakDetector.h" //For detecting memory leaks + +#include "m64p_types.h" +#include "m64p_common.h" +#include "m64p_plugin.h" +#include "m64p_config.h" +#include "m64p_vidext.h" + +#include "osal_dynamiclib.h" + +//Definitions +#define PLUGIN_NAME "Arachnoid Video Plugin" +#define PLUGIN_VERSION 0x020000 +#define VIDEO_PLUGIN_API_VERSION 0x020200 +#define CONFIG_API_VERSION 0x020000 +#define VIDEXT_API_VERSION 0x030000 + +#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) + +#define MI_INTR_DP 0x00000020 //!< RDP Interrupt signal +#define MI_INTR_SP 0x00000001 //!< RSP Interrupt signal + +//----------------------------------------------------------------------------- +// Global variables +//----------------------------------------------------------------------------- + +char g_cfgFilename[] = "ConfigGraphicsPlugin.cfg"; //!< Name configuration file +GFX_INFO g_graphicsInfo; //!< Information about window, memory... +GraphicsPlugin g_graphicsPlugin; //!< Main class for application +Config g_config(&g_graphicsPlugin); //!< Handles configuration + +void (*renderCallback)(int) = NULL; + + +/* definitions of pointers to Core config functions */ +ptr_ConfigOpenSection ConfigOpenSection = NULL; +ptr_ConfigSetParameter ConfigSetParameter = NULL; +ptr_ConfigGetParameter ConfigGetParameter = NULL; +ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL; +ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL; +ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL; +ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL; +ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL; +ptr_ConfigGetParamInt ConfigGetParamInt = NULL; +ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL; +ptr_ConfigGetParamBool ConfigGetParamBool = NULL; +ptr_ConfigGetParamString ConfigGetParamString = NULL; + +ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL; +ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL; +ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL; +ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL; + +/* definitions of pointers to Core video extension functions */ +ptr_VidExt_Init CoreVideo_Init = NULL; +ptr_VidExt_Quit CoreVideo_Quit = NULL; +ptr_VidExt_ListFullscreenModes CoreVideo_ListFullscreenModes = NULL; +ptr_VidExt_SetVideoMode CoreVideo_SetVideoMode = NULL; +ptr_VidExt_SetCaption CoreVideo_SetCaption = NULL; +ptr_VidExt_ToggleFullScreen CoreVideo_ToggleFullScreen = NULL; +ptr_VidExt_ResizeWindow CoreVideo_ResizeWindow = NULL; +ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress = NULL; +ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute = NULL; +ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers = NULL; + +//----------------------------------------------------------------------------- +// Mupen64plus 2.0 Common Plugin API Functions +//----------------------------------------------------------------------------- +#ifdef __cplusplus +extern "C" { +#endif +EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, + void (*DebugCallback)(void *, int, const char *)) +{ + char logMsg[530]; + Logger::getSingleton().initialize(DebugCallback, Context); + Logger::getSingleton().printMsg("PluginStartup"); + + /* attach and call the CoreGetAPIVersions function, check Config and Video Extension API versions for compatibility */ + ptr_CoreGetAPIVersions CoreAPIVersionFunc; + CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); + if (CoreAPIVersionFunc == NULL) + { + sprintf(logMsg, "Core emulator broken; no CoreAPIVersionFunc() function found."); + Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); + return M64ERR_INCOMPATIBLE; + } + int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; + (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); + if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) + { + sprintf(logMsg, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", + VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); + Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); + return M64ERR_INCOMPATIBLE; + } + if ((VidextAPIVersion & 0xffff0000) != (VIDEXT_API_VERSION & 0xffff0000)) + { + sprintf(logMsg, "Emulator core Video Extension API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", + VERSION_PRINTF_SPLIT(VidextAPIVersion), VERSION_PRINTF_SPLIT(VIDEXT_API_VERSION)); + Logger::getSingleton().printMsg(logMsg, M64MSG_ERROR); + return M64ERR_INCOMPATIBLE; + } + + /* Get the core config function pointers from the library handle */ + ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); + ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); + ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); + ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); + ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); + ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); + ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); + ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); + ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); + ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); + ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); + + ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath"); + ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath"); + ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath"); + ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath"); + + if (!ConfigOpenSection || !ConfigSetParameter || !ConfigGetParameter || + !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || + !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString || + !ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath) + { + Logger::getSingleton().printMsg("Couldn't connect to Core configuration functions", M64MSG_ERROR); + return M64ERR_INCOMPATIBLE; + } + + /* Get the core Video Extension function pointers from the library handle */ + CoreVideo_Init = (ptr_VidExt_Init) osal_dynlib_getproc(CoreLibHandle, "VidExt_Init"); + CoreVideo_Quit = (ptr_VidExt_Quit) osal_dynlib_getproc(CoreLibHandle, "VidExt_Quit"); + CoreVideo_ListFullscreenModes = (ptr_VidExt_ListFullscreenModes) osal_dynlib_getproc(CoreLibHandle, "VidExt_ListFullscreenModes"); + CoreVideo_SetVideoMode = (ptr_VidExt_SetVideoMode) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetVideoMode"); + CoreVideo_SetCaption = (ptr_VidExt_SetCaption) osal_dynlib_getproc(CoreLibHandle, "VidExt_SetCaption"); + CoreVideo_ToggleFullScreen = (ptr_VidExt_ToggleFullScreen) osal_dynlib_getproc(CoreLibHandle, "VidExt_ToggleFullScreen"); + CoreVideo_ResizeWindow = (ptr_VidExt_ResizeWindow) osal_dynlib_getproc(CoreLibHandle, "VidExt_ResizeWindow"); + CoreVideo_GL_GetProcAddress = (ptr_VidExt_GL_GetProcAddress) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_GetProcAddress"); + CoreVideo_GL_SetAttribute = (ptr_VidExt_GL_SetAttribute) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SetAttribute"); + CoreVideo_GL_SwapBuffers = (ptr_VidExt_GL_SwapBuffers) osal_dynlib_getproc(CoreLibHandle, "VidExt_GL_SwapBuffers"); + + if (!CoreVideo_Init || !CoreVideo_Quit || !CoreVideo_ListFullscreenModes || !CoreVideo_SetVideoMode || + !CoreVideo_SetCaption || !CoreVideo_ToggleFullScreen || !CoreVideo_GL_GetProcAddress || + !CoreVideo_GL_SetAttribute || !CoreVideo_GL_SwapBuffers || !CoreVideo_ResizeWindow) + { + Logger::getSingleton().printMsg("Couldn't connect to Core video functions", M64MSG_ERROR); + return M64ERR_INCOMPATIBLE; + } + + //Read configuration + if (g_config.initialize()) + { + g_config.load(); + g_graphicsPlugin.setConfig(g_config.getConfig()); + } + + return M64ERR_SUCCESS; +} + +EXPORT m64p_error CALL PluginShutdown(void) +{ + //Close Logger + Logger::getSingleton().printMsg("CloseDLL\n"); + Logger::getSingleton().dispose(); + + //g_graphicsPlugin.dispose(); + return M64ERR_SUCCESS; +} + +EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities) +{ + /* set version info */ + if (PluginType != NULL) + *PluginType = M64PLUGIN_GFX; + + if (PluginVersion != NULL) + *PluginVersion = PLUGIN_VERSION; + + if (APIVersion != NULL) + *APIVersion = VIDEO_PLUGIN_API_VERSION; + + if (PluginNamePtr != NULL) + *PluginNamePtr = PLUGIN_NAME; + + if (Capabilities != NULL) + { + *Capabilities = 0; + } + + return M64ERR_SUCCESS; +} + + + +//----------------------------------------------------------------------------- +// Mupen64plus 2.0 Video Plugin API Functions +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +//* InitiateGFX +//! This function is called when the DLL is started to give +//! information from the emulator that the n64 graphics +//! uses. This is not called from the emulation thread. +//! @param[in] Gfx_Info Information about rom and emulator +//! @return true on success, FALSE on failure to initialise +//! +//! @note on interrupts : +//! To generate an interrupt set the appropriate bit in MI_INTR_REG +//! and then the function CheckInterrupts to tell the emulator +//! that there is a waiting interrupt. +//----------------------------------------------------------------------------- +EXPORT BOOL CALL InitiateGFX(GFX_INFO Gfx_Info) +{ + Logger::getSingleton().printMsg("InitiateGFX"); + + //Save Graphics Info + memcpy(&g_graphicsInfo, &Gfx_Info, sizeof(GFX_INFO)); + return true; +} + +//----------------------------------------------------------------------------- +//* Rom Open +//! This function is called when a rom is open. (from the emulation thread) +//----------------------------------------------------------------------------- +EXPORT int CALL RomOpen() +{ + Logger::getSingleton().printMsg("RomOpen\n"); + return g_graphicsPlugin.initialize(&g_graphicsInfo); +} + +//----------------------------------------------------------------------------- +//* Resize Video Output +//! This function is called to force us to resize our output OpenGL window. +//! This is currently unsupported, and should never be called because we do +//! not pass the RESIZABLE flag to VidExt_SetVideoMode when initializing. +//----------------------------------------------------------------------------- +EXPORT void CALL ResizeVideoOutput(int Width, int Height) +{ +} + +//----------------------------------------------------------------------------- +//* Rom Closed +//! This function is called when a rom is closed. +//----------------------------------------------------------------------------- +EXPORT void CALL RomClosed() +{ + //Logger::getSingleton().printMsg("RomClosed\n"); + //Destroy + g_graphicsPlugin.dispose(); +} + +//----------------------------------------------------------------------------- +//* Update Screen +//! This function is called in response to a vsync of the +//! screen where the VI bit in MI_INTR_REG has already been set +//----------------------------------------------------------------------------- +EXPORT void CALL UpdateScreen() +{ + if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_VI) + g_graphicsPlugin.drawScreen(); + else if (g_config.getConfig()->screenUpdateSetting == SCREEN_UPDATE_CI) + g_graphicsPlugin.setDrawScreenSignal(); + else + { + Logger::getSingleton().printMsg("Invalid screen update setting!", M64MSG_WARNING); + g_graphicsPlugin.drawScreen(); + } +} + + +//----------------------------------------------------------------------------- +//* ProcessDList +//! This function is called when there is a Dlist to be processed. (High level GFX list) +//----------------------------------------------------------------------------- +EXPORT void CALL ProcessDList() +{ + Logger::getSingleton().printMsg("ProcessDList\n"); + + try + { + g_graphicsPlugin.viStatusChanged(); + g_graphicsPlugin.processDisplayList(); + } + catch (...) + { + Logger::getSingleton().printMsg("Unknown Error processing DisplayList", M64MSG_WARNING); + //MessageBox(0, "Unknown Error processing DisplayList", "Arachnoid Graphics Plugin", MB_OK|MB_SETFOREGROUND); + + g_graphicsPlugin.dispose(); + g_graphicsPlugin.initialize(&g_graphicsInfo); + + //Trigger Interupts + *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_DP; + g_graphicsInfo.CheckInterrupts(); + *(g_graphicsInfo.MI_INTR_REG) |= MI_INTR_SP; + g_graphicsInfo.CheckInterrupts(); + } +} + + +//----------------------------------------------------------------------------- +//* ProcessRDPList +//! This function is called when there is a Dlist to be processed. (Low level GFX list) +//! @todo ProcessRDPList +//----------------------------------------------------------------------------- +EXPORT void CALL ProcessRDPList() +{ + Logger::getSingleton().printMsg("ProcessRDPList\n"); + //TODO +} + +//----------------------------------------------------------------------------- +//* Show CFB +//! Usally once Dlists are started being displayed, cfb is +//! ignored. This function tells the dll to start displaying +//! them again. +//----------------------------------------------------------------------------- +EXPORT void CALL ShowCFB() +{ + Logger::getSingleton().printMsg("ShowCFB\n"); +} + +//----------------------------------------------------------------------------- +//* ViStatusChanged +//! This function is called to notify the dll that the +//! ViStatus registers value has been changed. +//----------------------------------------------------------------------------- +EXPORT void CALL ViStatusChanged() +{ + Logger::getSingleton().printMsg("ViStatusChanged"); + + //g_graphicsPlugin.viStatusChanged(); +} + +//----------------------------------------------------------------------------- +//* ViWidthChanged +//! This function is called to notify the dll that the +//! ViWidth registers value has been changed. +//----------------------------------------------------------------------------- +EXPORT void CALL ViWidthChanged() +{ + Logger::getSingleton().printMsg("ViWidthChanged"); + //g_graphicsPlugin.viStatusChanged(); +} + +//----------------------------------------------------------------------------- +//* MoveScreen +//! This function is called in response to the emulator +//! receiving a WM_MOVE passing the xpos and ypos passed +//! from that message. +//! @param xpos The x-coordinate of the upper-left corner of the +//! client area of the window. +//! @param ypos The y-coordinate of the upper-left corner of the +//! client area of the window. +//! @todo MoveScreen +//----------------------------------------------------------------------------- +EXPORT void CALL MoveScreen(int xpos, int ypos) +{ + Logger::getSingleton().printMsg("MoveScreen\n"); + //TODO +} + +//----------------------------------------------------------------------------- +//* ChangeWindow +//! Toggle between fullscreen and window mode +//----------------------------------------------------------------------------- +EXPORT void CALL ChangeWindow() +{ + Logger::getSingleton().printMsg("ChangeWindow\n"); + //Toggle Fullscreen + g_graphicsPlugin.toggleFullscreen(); +} + +//----------------------------------------------------------------------------- +//* ReadScreen2 +//! This function reads the pixels of the currently displayed screen +//----------------------------------------------------------------------------- +EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front) +{ + g_graphicsPlugin.takeScreenshot(dest, width, height, front); +} + +//----------------------------------------------------------------------------- +//* SetRenderingCallback +//! Allows the core to register a callback function that will be called by the +//! graphics plugin just before the the frame buffers are swapped. +//----------------------------------------------------------------------------- +EXPORT void CALL SetRenderingCallback(void (*callback)(int)) +{ + OpenGLManager::getSingleton().setRenderingCallback(callback); +} + +//----------------------------------------------------------------------------- +//* FBRead +//! Read data from frame buffer into emulated RAM space +//----------------------------------------------------------------------------- +EXPORT void CALL FBRead(unsigned int addr) +{ + //TODO +} + +//----------------------------------------------------------------------------- +//* FBWrite +//! Write data from emulated RAM space into frame buffer +//----------------------------------------------------------------------------- +EXPORT void CALL FBWrite(unsigned int addr, unsigned int size) +{ + //TODO +} + +//----------------------------------------------------------------------------- +//* FBWrite +//! Get some information about the frame buffer +//----------------------------------------------------------------------------- +EXPORT void FBGetFrameBufferInfo(void *p) +{ + //TODO +} + +#ifdef __cplusplus +} +#endif diff --git a/source/mupen64plus-video-arachnoid/src/math/MathLib.h b/source/mupen64plus-video-arachnoid/src/math/MathLib.h new file mode 100755 index 0000000..cf9e393 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/math/MathLib.h @@ -0,0 +1,100 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef MATH_LIBRARY_H_ +#define MATH_LIBRARY_H_ + +#include //sqrtf +#include "m64p.h" + +// Formula: a.b = a0*b0 + a1*b1 + a2*b2 +#define Vec3Dot(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) + +#define Vec3Normalize(v) { \ + float lenght = (v)[0]*(v)[0]+(v)[1]*(v)[1]+(v)[2]*(v)[2]; \ + if ( lenght > 0.00001f ) { \ + lenght = 1.0f / sqrt(lenght); \ + (v)[0] *= lenght; \ + (v)[1] *= lenght; \ + (v)[2] *= lenght; \ + } \ +} + + +//----------------------------------------------------------------------------- +// Transform Vector +//----------------------------------------------------------------------------- + +inline void transformVertex( float* m, float* v, float* out ) +{ + float x = v[0]; + float y = v[1]; + float z = v[2]; + out[0] = m[0] * x + m[4] * y + m[8] * z + m[12]; + out[1] = m[1] * x + m[5] * y + m[9] * z + m[13]; + out[2] = m[2] * x + m[6] * y + m[10] * z + m[14]; + out[3] = m[3] * x + m[7] * y + m[11] * z + m[15]; +} + +inline void transformVector( float* m, float* v, float* out ) +{ + float x = v[0]; + float y = v[1]; + float z = v[2]; + out[0] = m[0] * x + m[4] * y + m[8] * z; + out[1] = m[1] * x + m[5] * y + m[9] * z; + out[2] = m[2] * x + m[6] * y + m[10] * z; +} + + + +//----------------------------------------------------------------------------- +// Random Float +//----------------------------------------------------------------------------- +inline float randomFloat(float min, float max) +{ + return (float)( min + double(max-min)*rand()/RAND_MAX ); +} + +inline unsigned int pow2( unsigned int dim ) +{ + unsigned int i = 1; + + while (i < dim) i <<= 1; + + return i; +} + +inline unsigned int powof( unsigned int dim ) +{ + unsigned int num = 1; + unsigned int i = 0; + + while (num < dim) + { + num <<= 1; + i++; + } + + return i; +} + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp b/source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp new file mode 100755 index 0000000..d3a73ba --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/math/Matrix4.cpp @@ -0,0 +1,111 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "Matrix4.h" + +const Matrix4 Matrix4::ZERO( 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 ); + +const Matrix4 Matrix4::IDENTITY( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 ); + +const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE( 0.5, 0, 0, 0.5, + 0, -0.5, 0, 0.5, + 0, 0, 1, 0, + 0, 0, 0, 1); + + +//----------------------------------------------------------------------- +//! Calclate and returns the deteminant of the matrix +//----------------------------------------------------------------------- +float Matrix4::determinant() const +{ + return (_m[0]*(_m[4]*_m[8] - _m[7]*_m[5])) - (_m[1]*(_m[3]*_m[8] - _m[6]*_m[5])) + (_m[2]*(_m[3]*_m[7] - _m[6]*_m[4])); +} + +//----------------------------------------------------------------------- +//! Inverse Matrix +//----------------------------------------------------------------------- +Matrix4 Matrix4::inverse() const +{ + float m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3]; + float m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3]; + float m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3]; + float m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3]; + + float v0 = m20 * m31 - m21 * m30; + float v1 = m20 * m32 - m22 * m30; + float v2 = m20 * m33 - m23 * m30; + float v3 = m21 * m32 - m22 * m31; + float v4 = m21 * m33 - m23 * m31; + float v5 = m22 * m33 - m23 * m32; + + float t00 = + (v5 * m11 - v4 * m12 + v3 * m13); + float t10 = - (v5 * m10 - v2 * m12 + v1 * m13); + float t20 = + (v4 * m10 - v2 * m11 + v0 * m13); + float t30 = - (v3 * m10 - v1 * m11 + v0 * m12); + + float invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03); + + float d00 = t00 * invDet; + float d10 = t10 * invDet; + float d20 = t20 * invDet; + float d30 = t30 * invDet; + + float d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet; + float d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet; + float d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet; + float d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet; + + v0 = m10 * m31 - m11 * m30; + v1 = m10 * m32 - m12 * m30; + v2 = m10 * m33 - m13 * m30; + v3 = m11 * m32 - m12 * m31; + v4 = m11 * m33 - m13 * m31; + v5 = m12 * m33 - m13 * m32; + + float d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet; + float d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet; + float d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet; + float d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet; + + v0 = m21 * m10 - m20 * m11; + v1 = m22 * m10 - m20 * m12; + v2 = m23 * m10 - m20 * m13; + v3 = m22 * m11 - m21 * m12; + v4 = m23 * m11 - m21 * m13; + v5 = m23 * m12 - m22 * m13; + + float d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet; + float d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet; + float d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet; + float d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet; + + return Matrix4( + d00, d01, d02, d03, + d10, d11, d12, d13, + d20, d21, d22, d23, + d30, d31, d32, d33); +} diff --git a/source/mupen64plus-video-arachnoid/src/math/Matrix4.h b/source/mupen64plus-video-arachnoid/src/math/Matrix4.h new file mode 100755 index 0000000..5595479 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/math/Matrix4.h @@ -0,0 +1,252 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef MATRIX_4_H_ +#define MATRIX_4_H_ + +#include +#include + +//***************************************************************************** +//* Matrix4 +//! Math class defining a 4x4 matrix or an array of 16 float. +//! @details Used for viewprojection matrix and vertex transformation. +//***************************************************************************** +class Matrix4 +{ +public: + + //! The matrix entries, indexed by [row][col]. + union { + float m[4][4]; + float _m[16]; + }; + +public: + + //! Default constructor. + inline Matrix4() { operator=(IDENTITY); } + inline Matrix4( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33 ) + { + m[0][0] = m00; + m[0][1] = m01; + m[0][2] = m02; + m[0][3] = m03; + m[1][0] = m10; + m[1][1] = m11; + m[1][2] = m12; + m[1][3] = m13; + m[2][0] = m20; + m[2][1] = m21; + m[2][2] = m22; + m[2][3] = m23; + m[3][0] = m30; + m[3][1] = m31; + m[3][2] = m32; + m[3][3] = m33; + } + + //! Matrix multiplication + inline Matrix4 operator * ( const Matrix4 &m2 ) const + { + Matrix4 r; + r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0]; + r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1]; + r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2]; + r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3]; + + r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0]; + r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1]; + r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2]; + r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3]; + + r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0]; + r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1]; + r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2]; + r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3]; + + r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0]; + r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1]; + r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2]; + r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3]; + + return r; + } + + //Access operators + inline float* operator [] ( size_t iRow ) { return m[iRow]; } + + inline const float* const operator [] ( size_t iRow ) const { return m[iRow]; } + + //! Matrix addition. + inline Matrix4 operator + ( const Matrix4 &m2 ) const + { + Matrix4 r; + + r.m[0][0] = m[0][0] + m2.m[0][0]; + r.m[0][1] = m[0][1] + m2.m[0][1]; + r.m[0][2] = m[0][2] + m2.m[0][2]; + r.m[0][3] = m[0][3] + m2.m[0][3]; + + r.m[1][0] = m[1][0] + m2.m[1][0]; + r.m[1][1] = m[1][1] + m2.m[1][1]; + r.m[1][2] = m[1][2] + m2.m[1][2]; + r.m[1][3] = m[1][3] + m2.m[1][3]; + + r.m[2][0] = m[2][0] + m2.m[2][0]; + r.m[2][1] = m[2][1] + m2.m[2][1]; + r.m[2][2] = m[2][2] + m2.m[2][2]; + r.m[2][3] = m[2][3] + m2.m[2][3]; + + r.m[3][0] = m[3][0] + m2.m[3][0]; + r.m[3][1] = m[3][1] + m2.m[3][1]; + r.m[3][2] = m[3][2] + m2.m[3][2]; + r.m[3][3] = m[3][3] + m2.m[3][3]; + + return r; + } + + //! Matrix subtraction. + inline Matrix4 operator - ( const Matrix4 &m2 ) const + { + Matrix4 r; + r.m[0][0] = m[0][0] - m2.m[0][0]; + r.m[0][1] = m[0][1] - m2.m[0][1]; + r.m[0][2] = m[0][2] - m2.m[0][2]; + r.m[0][3] = m[0][3] - m2.m[0][3]; + + r.m[1][0] = m[1][0] - m2.m[1][0]; + r.m[1][1] = m[1][1] - m2.m[1][1]; + r.m[1][2] = m[1][2] - m2.m[1][2]; + r.m[1][3] = m[1][3] - m2.m[1][3]; + + r.m[2][0] = m[2][0] - m2.m[2][0]; + r.m[2][1] = m[2][1] - m2.m[2][1]; + r.m[2][2] = m[2][2] - m2.m[2][2]; + r.m[2][3] = m[2][3] - m2.m[2][3]; + + r.m[3][0] = m[3][0] - m2.m[3][0]; + r.m[3][1] = m[3][1] - m2.m[3][1]; + r.m[3][2] = m[3][2] - m2.m[3][2]; + r.m[3][3] = m[3][3] - m2.m[3][3]; + + return r; + } + + //! Tests 2 matrices for equality. + inline bool operator == ( const Matrix4& m2 ) const + { + if( + m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] || + m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] || + m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] || + m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] ) + return false; + return true; + } + + //! Tests 2 matrices for inequality. + inline bool operator != ( const Matrix4& m2 ) const + { + if( + m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] || + m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] || + m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] || + m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] ) + return true; + return false; + } + + //!Transpose Matrix (Switch columns with rows) + inline Matrix4 transpose() const + { + return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3]); + } + + //! Set Translation Part of the matrix + inline void setTranslationPart(const float v[3] ) + { + m[0][3] = v[0]; + m[1][3] = v[1]; + m[2][3] = v[2]; + } + + //! Builds a translation matrix + inline void setTranslation(float tx, float ty, float tz) + { + m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx; + m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty; + m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz; + m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0; + } + + //! Set scale part of matrix + inline void setScalePart( const float v[3] ) + { + m[0][0] = v[0]; + m[1][1] = v[1]; + m[2][2] = v[2]; + } + + static const Matrix4 ZERO; + static const Matrix4 IDENTITY; + static const Matrix4 CLIPSPACE2DTOIMAGESPACE; //! Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} and inverts the Y. + + + inline Matrix4 operator*(float scalar) const + { + return Matrix4( + scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3], + scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3], + scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3], + scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]); + } + + //! Function for writing to a stream. + inline friend std::ostream& operator << ( std::ostream& o, const Matrix4& m ) + { + o << "Matrix4("; + for (size_t i = 0; i < 4; ++i) + { + o << " row" << (unsigned)i << "{"; + for(size_t j = 0; j < 4; ++j) + { + o << m[i][j] << " "; + } + o << "}"; + } + o << ")"; + return o; + } + + float determinant() const; + Matrix4 inverse() const; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h new file mode 100755 index 0000000..f94bcda --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib.h @@ -0,0 +1,41 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-core - osal/dynamiclib.h * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2009 Richard Goedeken * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#if !defined(OSAL_DYNAMICLIB_H) +#define OSAL_DYNAMICLIB_H + +#include "m64p_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath); + +void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName); + +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle); + +#ifdef __cplusplus +} +#endif + +#endif /* #define OSAL_DYNAMICLIB_H */ diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp new file mode 100755 index 0000000..39df6cb --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Mupen64plus-core - osal/dynamiclib_unix.c * + * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * + * Copyright (C) 2009 Richard Goedeken * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include +#include +#include + +#include "m64p_types.h" +#include "osal_dynamiclib.h" + +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) +{ + if (pLibHandle == NULL || pccLibraryPath == NULL) + return M64ERR_INPUT_ASSERT; + + *pLibHandle = dlopen(pccLibraryPath, RTLD_NOW); + + if (*pLibHandle == NULL) + { + fprintf(stderr, "dlopen('%s') error: %s\n", pccLibraryPath, dlerror()); + return M64ERR_INPUT_NOT_FOUND; + } + + return M64ERR_SUCCESS; +} + +void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) +{ + if (pccProcedureName == NULL) + return NULL; + + return dlsym(LibHandle, pccProcedureName); +} + +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) +{ + int rval = dlclose(LibHandle); + + if (rval != 0) + { + fprintf(stderr, "dlclose() error: %s\n", dlerror()); + return M64ERR_INTERNAL; + } + + return M64ERR_SUCCESS; +} + + diff --git a/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp new file mode 100755 index 0000000..d55b2ae --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp @@ -0,0 +1,74 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Arachnoid Graphics Plugin for Mupen64Plus * + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * + * Copyright (C) 2009 Richard Goedeken * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include +#include +#include + +#include "m64p_types.h" +#include "osal_dynamiclib.h" + +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) +{ + if (pLibHandle == NULL || pccLibraryPath == NULL) + return M64ERR_INPUT_ASSERT; + + *pLibHandle = LoadLibrary(pccLibraryPath); + + if (*pLibHandle == NULL) + { + char *pchErrMsg; + DWORD dwErr = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); + fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg); + LocalFree(pchErrMsg); + return M64ERR_INPUT_NOT_FOUND; + } + + return M64ERR_SUCCESS; +} + +void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) +{ + if (pccProcedureName == NULL) + return NULL; + + return (void *)GetProcAddress(LibHandle, pccProcedureName); +} + +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) +{ + int rval = FreeLibrary(LibHandle); + + if (rval == 0) + { + char *pchErrMsg; + DWORD dwErr = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); + fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg); + LocalFree(pchErrMsg); + return M64ERR_INTERNAL; + } + + return M64ERR_SUCCESS; +} diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp new file mode 100755 index 0000000..dc63652 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp @@ -0,0 +1,350 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "OpenGL2DRenderer.h" +#include "VI.h" +#include "m64p.h" +#include "OpenGL.h" + +//----------------------------------------------------------------------------- +//* Initialize +//! Saves pointer to video interface +//----------------------------------------------------------------------------- +bool OpenGL2DRenderer::initialize(VI* vi) +{ + m_vi = vi; + return true; +} + +//----------------------------------------------------------------------------- +//* Render Quad +//! Renders a 2D rectangle in HUD. +//! @todo Set Viewport +//! @todo Reset Viewport +//----------------------------------------------------------------------------- +void OpenGL2DRenderer::renderQuad( const float color[4], + float x0, float y0, + float x1, float y1, + float depth ) +{ + //Get States + GLboolean scissor = glIsEnabled(GL_SCISSOR_TEST); + GLboolean cull = glIsEnabled(GL_CULL_FACE); + + //Set States + glDisable( GL_SCISSOR_TEST ); + glDisable( GL_CULL_FACE ); + + //Set Othographic Projection Matrix + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f); + + //TODO Set Viewport + //glViewport(0, glheightOffset, glwidth, glheight); + //glDepthRange( 0.0f, 1.0f ); + + //Render Quad + glColor4fv(color); +#ifdef HAVE_GLES + GLfloat vtx[] = { + x0, y0, depth, + x1, y0, depth, + x1, y1, depth, + x0, y1, depth + }; + + GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY); + if (glcol) glDisableClientState(GL_COLOR_ARRAY); + GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY); + if (!glvtx) + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT, 0,&vtx); + glActiveTexture( GL_TEXTURE1 ); + GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D); + if (gltex1) glDisable(GL_TEXTURE_2D); + glActiveTexture( GL_TEXTURE0 ); + GLboolean gltex = glIsEnabled(GL_TEXTURE_2D); + if (gltex) glDisable(GL_TEXTURE_2D); + // draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // restaure + if (glcol) glEnableClientState(GL_COLOR_ARRAY); + glActiveTexture( GL_TEXTURE1 ); + if (gltex1) glEnable(GL_TEXTURE_2D); + glActiveTexture( GL_TEXTURE0 ); + if (gltex) glEnable(GL_TEXTURE_2D); + if (!glvtx) + glDisableClientState(GL_VERTEX_ARRAY); + else + glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array ); + +#else + glBegin(GL_QUADS); + glVertex3f(x0, y0, depth); + glVertex3f(x1, y0, depth); + glVertex3f(x1, y1, depth); + glVertex3f(x0, y1, depth); + glEnd(); +#endif + //Reset Projection Matrix + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + //Reset States + if ( scissor ) glEnable(GL_SCISSOR_TEST); + if ( cull ) glEnable(GL_CULL_FACE); + + //TODO Reset viewport? +} + + +//----------------------------------------------------------------------------- +//* Render Textured Quad +//! Renders a textured 2D rectangle in HUD. +//! @todo Set Viewport +//! @todo Reset Viewport +//----------------------------------------------------------------------------- +void OpenGL2DRenderer::renderTexturedQuad( const float color[4], + const float secondaryColor[4], + float x0, float y0, + float x1, float y1, + float depth, + float t0s0, float t0t0, + float t0s1, float t0t1, + float t1s0, float t1t0, + float t1s1, float t1t1 ) +{ + //Get States + GLboolean cull = glIsEnabled(GL_CULL_FACE); + GLboolean fog = glIsEnabled(GL_FOG); + + //Set States + glDisable(GL_CULL_FACE); + glDisable(GL_FOG); + + //Set Orthographic Projection + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f); + + //TODO Set Viewport + //glViewport(0, glheightOffset, glwidth, glheight); + //glDepthRange( 0.0f, 1.0f ); + + //Set Color + glColor4fv( color ); +#ifdef HAVE_GLES + GLfloat tex[] = { + t0s0, t0t0, + t0s1, t0t0, + t0s1, t0t1, + t0s0, t0t1 + }; + GLfloat tex1[] = { + t1s0, t1t0, + t1s1, t1t0, + t1s1, t1t1, + t1s0, t1t1 + }; + GLfloat vtx[] = { + x0, y0, depth, + x1, y0, depth, + x1, y1, depth, + x0, y1, depth + }; + + GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY); + if (glcol) glDisableClientState(GL_COLOR_ARRAY); + GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY); + if (!glvtx) + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT, 0,&vtx); +/* glActiveTexture( GL_TEXTURE1 ); + GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D); + if (gltex1) glDisable(GL_TEXTURE_2D);*/ + glClientActiveTexture( GL_TEXTURE1 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex1); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex); + // draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // restaure + if (glcol) glEnableClientState(GL_COLOR_ARRAY); +// if (gltex1) glEnable(GL_TEXTURE_2D); + if (!glvtx) + glDisableClientState(GL_VERTEX_ARRAY); + if (glsav_vtx_type==GL_FLOAT) glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array ); + glClientActiveTexture( GL_TEXTURE1 ); + if (glsav_tex1_type==GL_FLOAT) glTexCoordPointer( glsav_tex1_size, glsav_tex1_type, glsav_tex1_stride, glsav_tex1_array ); + glClientActiveTexture( GL_TEXTURE0 ); + if (glsav_tex_type==GL_FLOAT) glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array ); +#else + //Render Rectangle + glBegin(GL_QUADS); + { + //Vertex 00 + glTexCoord2f(t0s0, t0t0); + glVertex3f(x0, y0, depth); + + //Vertex 10 + glTexCoord2f(t0s1, t0t0); + glVertex3f(x1, y0, depth); + + //Vertex 11 + glTexCoord2f(t0s1, t0t1 ); + glVertex3f(x1, y1, depth); + + //Vertex 01 + glTexCoord2f(t0s0, t0t1 ); + glVertex3f(x0, y1, depth); + } + glEnd(); +#endif + //Reset Projection Matrix + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + //Reset States + if ( cull ) glEnable(GL_CULL_FACE); + if ( fog ) glEnable(GL_FOG); + + //TODO Reset viewport? +} + + +//----------------------------------------------------------------------------- +//Render Flipped Textured Quad +//! Renders a flipped textured 2D rectangle in HUD. +//! @todo Set Viewport +//! @todo Reset Viewport +//----------------------------------------------------------------------------- +void OpenGL2DRenderer::renderFlippedTexturedQuad( const float color[4], + const float secondaryColor[4], + float x0, float y0, + float x1, float y1, + float depth, + float t0s0, float t0t0, + float t0s1, float t0t1, + float t1s0, float t1t0, + float t1s1, float t1t1 ) +{ + //Get States + GLboolean cull = glIsEnabled(GL_CULL_FACE); + GLboolean fog = glIsEnabled(GL_FOG); + + //Set States + glDisable(GL_CULL_FACE); + glDisable(GL_FOG); + + //Set Orthographic Projection + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f); + + //TODO + //glViewport(0, glheightOffset, glwidth, glheight); + //glDepthRange( 0.0f, 1.0f ); + + //Set Color + glColor4fv( color ); + +#ifdef HAVE_GLES + GLfloat tex[] = { + t0s0, t0t0, + t0s0, t0t1, + t0s1, t0t1, + t0s1, t0t0 + }; + GLfloat tex1[] = { + t1s0, t1t0, + t1s0, t1t1, + t1s1, t1t1, + t1s1, t1t0 + }; + GLfloat vtx[] = { + x0, y0, depth, + x1, y0, depth, + x1, y1, depth, + x0, y1, depth + }; + + GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY); + if (glcol) glDisableClientState(GL_COLOR_ARRAY); + GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY); + if (!glvtx) + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT, 0,&vtx); +/* glActiveTexture( GL_TEXTURE1 ); + GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D); + if (gltex1) glDisable(GL_TEXTURE_2D);*/ + glClientActiveTexture( GL_TEXTURE1 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex1); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex); + // draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // restaure + if (glcol) glEnableClientState(GL_COLOR_ARRAY); +// if (gltex1) glEnable(GL_TEXTURE_2D); + glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array ); + glClientActiveTexture( GL_TEXTURE1 ); + glTexCoordPointer( glsav_tex1_size, glsav_tex1_type, glsav_tex1_stride, glsav_tex1_array ); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array ); +#else //Render Rectangle + glBegin(GL_QUADS); + { + //Vertex 00 + glTexCoord2f(t0s0, t0t0); //00 + glVertex3f(x0, y0, depth); + + //Vertex 10 + glTexCoord2f(t0s0, t0t1); //01 ! + glVertex3f(x1, y0, depth); + + //Vertex 11 + glTexCoord2f(t0s1, t0t1); //11 + glVertex3f(x1, y1, depth); + + //Vertex 01 + glTexCoord2f(t0s1, t0t0); //10 ! + glVertex3f(x0, y1, depth); + } + glEnd(); +#endif + //Reset Projection Matrix + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + //Reset States + if ( cull ) glEnable(GL_CULL_FACE); + if ( fog ) glEnable(GL_FOG); + + //TODO Reset viewport? +} + diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h new file mode 100755 index 0000000..6d37661 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef OPEN_GL_2D_RENDERER_H_ +#define OPEN_GL_2D_RENDERER_H_ + +//Forward declarations +class VI; + +//***************************************************************************** +//* OpenGL 2D Renderer +//! Class used to render HUD objects. +//! @details Renders 2D quads, textured 2D quads and flipped textures 2D quads. +//***************************************************************************** +class OpenGL2DRenderer +{ +public: + + //Initialize + bool initialize(VI* vi); + + //Render Quad + void renderQuad( const float color[4], + float x0, float y0, + float x1, float y1, + float depth ); + + + //Render Textured Quad + void renderTexturedQuad( const float color[4], + const float secondaryColor[4], + float x0, float y0, + float x1, float y1, + float depth, + float t0s0, float t0t0, + float t0s1, float t0t1, + float t1s0, float t1t0, + float t1s1, float t1t1 ); + + //Render Flipped Textured Quad + void renderFlippedTexturedQuad( const float color[4], + const float secondaryColor[4], + float x0, float y0, + float x1, float y1, + float depth, + float t0s0, float t0t0, + float t0s1, float t0t1, + float t1s0, float t1t0, + float t1s1, float t1t1 ); + + +private: + + VI* m_vi; //!< Video interface + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp new file mode 100755 index 0000000..9392d95 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp @@ -0,0 +1,531 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2009 Jon Ring + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "m64p.h" + +#include +#include +#include "OpenGLRenderer.h" +#include "OpenGLManager.h" +#include "RSP.h" +#include "RDP.h" +#include "TextureCache.h" +#include "VI.h" +#include "Logger.h" +//#include "CombinerManager.h" +#include "AdvancedCombinerManager.h" +#include "FogManager.h" +#include "ExtensionChecker.h" +#include "MultiTexturingExt.h" +#include "SecondaryColorExt.h" + +#ifdef HAVE_GLES +// save of arrays +GLint glsav_col_size; +GLenum glsav_col_type; +GLsizei glsav_col_stride; +GLvoid* glsav_col_array; + +GLint glsav_vtx_size; +GLenum glsav_vtx_type; +GLsizei glsav_vtx_stride; +GLvoid* glsav_vtx_array; + +GLint glsav_tex_size; +GLenum glsav_tex_type; +GLsizei glsav_tex_stride; +GLvoid* glsav_tex_array; + +GLint glsav_tex1_size; +GLenum glsav_tex1_type; +GLsizei glsav_tex1_stride; +GLvoid* glsav_tex1_array; +#endif + +using std::max; + +#ifndef GL_CLAMP_TO_EDGE + #define GL_CLAMP_TO_EDGE 0x812F +#endif + +bool ARB_multitexture = false; +bool EXT_secondary_color = false; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +OpenGLRenderer::OpenGLRenderer() +{ + m_numVertices = 0; +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +OpenGLRenderer::~OpenGLRenderer() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Saves pointers and setup render OpenGl pointers to vertex data. +//----------------------------------------------------------------------------- +bool OpenGLRenderer::initialize(RSP* rsp, RDP* rdp, TextureCache* textureCache, VI* vi, FogManager* fogMgr) +{ + m_rsp = rsp; + m_rdp = rdp; + m_textureCache = textureCache; + m_vi = vi; + m_fogMgr = fogMgr; + + m_numVertices = 0; + m_numTriangles = 0; + + //Init multitexturing + ARB_multitexture = initializeMultiTexturingExtensions(); + EXT_secondary_color = initializeSecondaryColorExtension(); + + //Vertices + glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x ); + glEnableClientState( GL_VERTEX_ARRAY ); + + //Colors + glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r); + glEnableClientState( GL_COLOR_ARRAY ); + + //Secondary Color + if ( EXT_secondary_color) + { + glSecondaryColorPointerEXT( 3, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].secondaryColor.r ); + glEnableClientState( GL_SECONDARY_COLOR_ARRAY_EXT ); + } + + //Textureing 0 + glClientActiveTextureARB( GL_TEXTURE0_ARB ); + glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 ); + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + //Textureing 1 + glClientActiveTextureARB( GL_TEXTURE1_ARB ); + glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 ); + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + //Fog + m_fogMgr->setFogCoordPointer(GL_FLOAT, sizeof(GLVertex), &m_vertices[0].fog); + m_fogMgr->enableFogCoordArray(); + m_fogMgr->setLinearFog(); + +#ifdef HAVE_GLES + // save of arrays + glsav_col_size = 4; + glsav_col_type = GL_FLOAT; + glsav_col_stride = sizeof(GLVertex); + glsav_col_array = &m_vertices[0].color.r; + + glsav_vtx_size = 4; + glsav_vtx_type = GL_FLOAT; + glsav_vtx_stride = sizeof(GLVertex); + glsav_vtx_array = &m_vertices[0].x; + + glsav_tex_size = 2; + glsav_tex_type = GL_FLOAT; + glsav_tex_stride = sizeof(GLVertex); + glsav_tex_array = &m_vertices[0].s0; + + glsav_tex1_size = 2; + glsav_tex1_type = GL_FLOAT; + glsav_tex1_stride = sizeof(GLVertex); + glsav_tex1_array = &m_vertices[0].s1; +#endif + + + return true; +} + + + +//----------------------------------------------------------------------------- +// Add triangle +//----------------------------------------------------------------------------- +void OpenGLRenderer::addTriangle( SPVertex *vertices, int v0, int v1, int v2 ) +{ + int v[] = { v0, v1, v2 }; + + //Update States + m_rdp->updateStates(); + + //For each vertex in triangle + for (int i=0; i<3; ++i) + { + //Set Vertex + m_vertices[m_numVertices].x = vertices[v[i]].x; + m_vertices[m_numVertices].y = vertices[v[i]].y; + m_vertices[m_numVertices].z = m_rdp->getDepthSource() == G_ZS_PRIM ? m_rdp->getPrimitiveZ() * vertices[v[i]].w : vertices[v[i]].z; + m_vertices[m_numVertices].w = vertices[v[i]].w; + + //Set Color + m_vertices[m_numVertices].color.r = vertices[v[i]].r; + m_vertices[m_numVertices].color.g = vertices[v[i]].g; + m_vertices[m_numVertices].color.b = vertices[v[i]].b; + m_vertices[m_numVertices].color.a = vertices[v[i]].a; + m_rdp->getCombinerMgr()->getCombinerColor( &m_vertices[m_numVertices].color.r ); + + if ( EXT_secondary_color ) + { + m_vertices[m_numVertices].secondaryColor.r = 0.0f;//lod_fraction; //vertices[v[i]].r; + m_vertices[m_numVertices].secondaryColor.g = 0.0f;//lod_fraction; //vertices[v[i]].g; + m_vertices[m_numVertices].secondaryColor.b = 0.0f;//lod_fraction; //vertices[v[i]].b; + m_vertices[m_numVertices].secondaryColor.a = 1.0f; + m_rdp->getCombinerMgr()->getSecondaryCombinerColor( &m_vertices[m_numVertices].secondaryColor.r ); + } + + //Set Fog + if ( OpenGLManager::getSingleton().getFogEnabled() ) + { + if (vertices[v[i]].z < -vertices[v[i]].w) + { + m_vertices[m_numVertices].fog = max(0.0f, -m_fogMgr->getMultiplier() + m_fogMgr->getOffset() ); + } + else + { + m_vertices[m_numVertices].fog = max(0.0f, vertices[v[i]].z / vertices[v[i]].w * m_fogMgr->getMultiplier() + m_fogMgr->getOffset()); + } + } + + //Set TexCoords + if ( m_rdp->getCombinerMgr()->getUsesTexture0() ) + { + RSPTexture& rspTexture = m_rsp->getTexture(); + CachedTexture* cacheTexture = m_textureCache->getCurrentTexture(0); + RDPTile* rspTile = m_rsp->getTile(0); + if ( cacheTexture ) + { + m_vertices[m_numVertices].s0 = (vertices[v[i]].s * cacheTexture->shiftScaleS * rspTexture.scaleS - rspTile->fuls + cacheTexture->offsetS) * cacheTexture->scaleS; + m_vertices[m_numVertices].t0 = (vertices[v[i]].t * cacheTexture->shiftScaleT * rspTexture.scaleT - rspTile->fult + cacheTexture->offsetT) * cacheTexture->scaleT; + } + else + { + m_vertices[m_numVertices].s0 = (vertices[v[i]].s * rspTexture.scaleS - rspTile->fuls ); + m_vertices[m_numVertices].t0 = (vertices[v[i]].t * rspTexture.scaleT - rspTile->fult ); + } + } + + if ( m_rdp->getCombinerMgr()->getUsesTexture1() ) + { + RSPTexture& rspTexture = m_rsp->getTexture(); + CachedTexture* cache = m_textureCache->getCurrentTexture(1); + RDPTile* rspTile = m_rsp->getTile(1); + if ( cache && rspTile ) + { + m_vertices[m_numVertices].s1 = (vertices[v[i]].s * cache->shiftScaleS * rspTexture.scaleS - rspTile->fuls + cache->offsetS) * cache->scaleS; + m_vertices[m_numVertices].t1 = (vertices[v[i]].t * cache->shiftScaleT * rspTexture.scaleT - rspTile->fult + cache->offsetT) * cache->scaleT; + } + } + + m_numVertices++; + } + m_numTriangles++; + + if ( m_numVertices >= 255 ) + { + + Logger::getSingleton().printMsg("RENDER VERTICES!!! :)", M64MSG_ERROR); + OpenGLRenderer::getSingleton().render(); + } +} + +//----------------------------------------------------------------------------- +// Render +//----------------------------------------------------------------------------- +void OpenGLRenderer::render() +{ + glDrawArrays(GL_TRIANGLES, 0, m_numVertices); + m_numTriangles = m_numVertices = 0; +} + +//----------------------------------------------------------------------------- +// Render Texture Rectangle +//----------------------------------------------------------------------------- +void OpenGLRenderer::renderTexRect( float ulx, float uly, //Upper left vertex + float lrx, float lry, //Lower right vertex + float uls, float ult, //Upper left texcoord + float lrs, float lrt, //Lower right texcoord + bool flip) //Flip +{ + //Initialize first vertex (upper left vertex) + GLVertex rect[2]; + rect[0].x = ulx; + rect[0].y = uly; + rect[0].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f; //FIXME: Use viewport.nearz? + rect[0].w = 1.0f; + rect[0].color.r = 1.0f; + rect[0].color.g = 1.0f; + rect[0].color.b = 1.0f; + rect[0].color.a = 0.0f; + rect[0].secondaryColor.r = 1.0f; + rect[0].secondaryColor.g = 1.0f; + rect[0].secondaryColor.b = 1.0f; + rect[0].secondaryColor.a = 1.0f; + rect[0].s0 = uls; + rect[0].t0 = ult; + rect[0].s1 = uls; + rect[0].t1 = ult; + rect[0].fog = 0.0f; + + //Initialize second vertex (lower right vertex) + rect[1].x = lrx; + rect[1].y = lry; + rect[1].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f; //FIXME: Use viewport.nearz? + rect[1].w = 1.0f; + rect[1].color.r = 1.0f; + rect[1].color.g = 1.0f; + rect[1].color.b = 1.0f; + rect[1].color.a = 0.0f; + rect[1].secondaryColor.r = 1.0f; + rect[1].secondaryColor.g = 1.0f; + rect[1].secondaryColor.b = 1.0f; + rect[1].secondaryColor.a = 1.0f; + rect[1].s0 = lrs; + rect[1].t0 = lrt; + rect[1].s1 = lrs; + rect[1].t1 = lrt; + rect[1].fog = 0.0f; + + glDisable( GL_CULL_FACE ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + //glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f ); + glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f ); + //glOrtho( 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight(), 0, 1.0f, -1.0f ); + //glViewport( 0, 0, m_vi->getWidth(), m_vi->getHeight() ); + //glViewport( 0, 0, 320, 240 ); + //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight()); + + if ( m_rdp->getCombinerMgr()->getUsesTexture0() ) + { + rect[0].s0 = rect[0].s0 * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls; + rect[0].t0 = rect[0].t0 * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult; + rect[1].s0 = (rect[1].s0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls; + rect[1].t0 = (rect[1].t0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult; + + if ((m_textureCache->getCurrentTexture(0)->maskS) && (fmod( rect[0].s0, m_textureCache->getCurrentTexture(0)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorS)) + { + rect[1].s0 -= rect[0].s0; + rect[0].s0 = 0.0f; + } + + if ((m_textureCache->getCurrentTexture(0)->maskT) && (fmod( rect[0].t0, m_textureCache->getCurrentTexture(0)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorT)) + { + rect[1].t0 -= rect[0].t0; + rect[0].t0 = 0.0f; + } +// +// if (OGL.ARB_multitexture) + glActiveTextureARB( GL_TEXTURE0_ARB ); +// + if ((rect[0].s0 >= 0.0f) && (rect[1].s0 <= m_textureCache->getCurrentTexture(0)->width)) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + + if ((rect[0].t0 >= 0.0f) && (rect[1].t0 <= m_textureCache->getCurrentTexture(0)->height)) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + +// + rect[0].s0 *= m_textureCache->getCurrentTexture(0)->scaleS; + rect[0].t0 *= m_textureCache->getCurrentTexture(0)->scaleT; + rect[1].s0 *= m_textureCache->getCurrentTexture(0)->scaleS; + rect[1].t0 *= m_textureCache->getCurrentTexture(0)->scaleT; + } + + if ( m_rdp->getCombinerMgr()->getUsesTexture1() ) + { + rect[0].s1 = rect[0].s1 * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls; + rect[0].t1 = rect[0].t1 * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult; + rect[1].s1 = (rect[1].s1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls; + rect[1].t1 = (rect[1].t1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult; + + if ((m_textureCache->getCurrentTexture(1)->maskS) && (fmod( rect[0].s1, m_textureCache->getCurrentTexture(1)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorS)) + { + rect[1].s1 -= rect[0].s1; + rect[0].s1 = 0.0f; + } + + if ((m_textureCache->getCurrentTexture(1)->maskT) && (fmod( rect[0].t1, m_textureCache->getCurrentTexture(1)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorT)) + { + rect[1].t1 -= rect[0].t1; + rect[0].t1 = 0.0f; + } + + glActiveTextureARB( GL_TEXTURE1_ARB ); + + if ((rect[0].s1 == 0.0f) && (rect[1].s1 <= m_textureCache->getCurrentTexture(1)->width)) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + + if ((rect[0].t1 == 0.0f) && (rect[1].t1 <= m_textureCache->getCurrentTexture(1)->height)) + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + rect[0].s1 *= m_textureCache->getCurrentTexture(1)->scaleS; + rect[0].t1 *= m_textureCache->getCurrentTexture(1)->scaleT; + rect[1].s1 *= m_textureCache->getCurrentTexture(1)->scaleS; + rect[1].t1 *= m_textureCache->getCurrentTexture(1)->scaleT; + } + + + if ( m_rdp->m_otherMode.cycleType == G_CYC_COPY ) /*&& !OGL.forceBilinear )*/ + { + //if (OGL.ARB_multitexture) + glActiveTextureARB( GL_TEXTURE0_ARB ); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + } + +// SetConstant( rect[0].color, combiner.vertex.color, combiner.vertex.alpha ); + //rdp.updateStates(); + m_rdp->getCombinerMgr()->getCombinerColor(&rect[0].color.r); + + //if (OGL.EXT_secondary_color) + m_rdp->getCombinerMgr()->getSecondaryCombinerColor(&rect[0].secondaryColor.r); + // SetConstant( rect[0].secondaryColor, combiner.vertex.secondaryColor, combiner.vertex.alpha ); + +#ifdef HAVE_GLES + GLfloat col[] = { + rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, + rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, + rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, + rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a + }; + + GLfloat tex[] = { + rect[0].s0, rect[0].t0, + rect[1].s0, rect[0].t0, + rect[1].s0, rect[1].t0, + rect[0].s0, rect[1].t0 + }; + GLfloat tex1[] = { + rect[0].s1, rect[0].t1, + rect[1].s1, rect[0].t1, + rect[1].s1, rect[1].t1, + rect[0].s1, rect[1].t1 + }; + + GLfloat vtx[] = { + rect[0].x, rect[0].y, rect[0].z, 1.0f, + rect[1].x, rect[0].y, rect[0].z, 1.0f, + rect[1].x, rect[1].y, rect[0].z, 1.0f, + rect[0].x, rect[1].y, rect[0].z, 1.0f + }; + // Setup pointer array + glColorPointer(4, GL_FLOAT, 0, &col ); + glVertexPointer(4,GL_FLOAT, 0,&vtx); + glClientActiveTexture( GL_TEXTURE1 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex1); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer(2, GL_FLOAT, 0, &tex); + // Draw + glDrawArrays(GL_TRIANGLE_FAN,0,4); + // Restaure default pointer + glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x ); + glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r); + glClientActiveTexture( GL_TEXTURE1 ); + glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 ); + glClientActiveTexture( GL_TEXTURE0 ); + glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 ); +#else + glBegin( GL_QUADS ); + + glColor4f( rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a ); + + //if (OGL.EXT_secondary_color) + glSecondaryColor3fEXT( rect[0].secondaryColor.r, rect[0].secondaryColor.g, rect[0].secondaryColor.b ); + + //if (OGL.ARB_multitexture) + //{ + // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[0].t0 ); + // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[0].t1 ); + // glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); + + // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[0].t0 ); + // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[0].t1 ); + // glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); + + // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[1].t0 ); + // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[1].t1 ); + // glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); + + // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[1].t0 ); + // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[1].t1 ); + // glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f ); + //} +// else + { + + /* + Logger::getSingleton() << "\n\nTexRect x0=" << rect[0].x << " y0=" << rect[0].y << + " x1=" << rect[1].x << "y1=" << rect[1].y << + " t0u0=" << rect[0].s0 << " t0v0=" << rect[0].t0 << + " t0u1=" << rect[1].s0 << " t0v1=" << rect[1].t0 << "\n"; + */ + glTexCoord2f(rect[0].s0, rect[0].t0 ); + //glTexCoord2f(rect[0].s1, rect[0].t1 ); + glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); + + glTexCoord2f(rect[1].s0, rect[0].t0 ); + //glTexCoord2f(rect[1].s1, rect[0].t1 ); + glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); + + glTexCoord2f(rect[1].s0, rect[1].t0 ); + //glTexCoord2f(rect[1].s1, rect[1].t1 ); + glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); + + glTexCoord2f(rect[0].s0, rect[1].t0 ); + //glTexCoord2f(rect[0].s1, rect[1].t1 ); + glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f ); + + + + /* glTexCoord2f( rect[0].s0, rect[0].t0 ); + glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); + + if (flip) + glTexCoord2f( rect[1].s0, rect[0].t0 ); + else + glTexCoord2f( rect[0].s0, rect[1].t0 ); + + glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); + + glTexCoord2f( rect[1].s0, rect[1].t0 ); + glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); + + if (flip) + glTexCoord2f( rect[1].s0, rect[0].t0 ); + else + glTexCoord2f( rect[1].s0, rect[0].t0 ); + glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f );*/ + } + glEnd(); +#endif + glLoadIdentity(); + //OGL_UpdateCullFace(); + //OGL_UpdateViewport(); +} diff --git a/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h new file mode 100755 index 0000000..b5082ae --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h @@ -0,0 +1,112 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef OPEN_GL_RENDERER_H_ +#define OPEN_GL_RENDERER_H_ + +#include "m64p.h" +#include "OpenGL.h" + +//Forward Declarations +struct SPVertex; +class RSP; +class RDP; +class TextureCache; +class VI; +class FogManager; + +#include "MultiTexturingExt.h" + + +//***************************************************************************** +//* OpenGL Vertex +//! Used in vertex buffer by OpenGLRenderer. +//***************************************************************************** +struct GLVertex +{ + float x, y, z, w; //!< Vertex position + struct + { + float r, g, b, a; + } color, secondaryColor; //!< Color and secondary color + float s0, t0, s1, t1; //!< Texture coordinats + float fog; //!< Vertex fog variable +}; + +//***************************************************************************** +//* OpenGL Renderer +//! Class for rendering using OpenGL +//***************************************************************************** +class OpenGLRenderer +{ +public: + + //Get Singleton Instance + static OpenGLRenderer& getSingleton() + { + static OpenGLRenderer instance; + return instance; + } + + //Destructor + ~OpenGLRenderer(); + + //Initialize + bool initialize(RSP* rsp, RDP* rdp, TextureCache* textureCache, VI* vi, FogManager* fogMgr); + + //Flush Vertex buffer + void render(); + + //Add triangle + void addTriangle( SPVertex *vertices, int v0, int v1, int v2 ); + + //Get number of vertices + int getNumVertices() { return m_numVertices; } + + //Render Tex Rect + void renderTexRect( float ulx, float uly, //Upper left vertex + float lrx, float lry, //Lower right vertex + float uls, float ult, //Upper left texcoord + float lrs, float lrt, //Lower right texcoord + bool flip); //Flip + +private: + + //Constructor + OpenGLRenderer(); + +private: + + GLVertex m_vertices[256]; //!< Vertex buffer + unsigned char m_triangles[300][3]; //!< Triangles used to index vertices + + int m_numVertices; //!< Number of vertices in vertex buffer + int m_numTriangles; //!< Number of triangles + + RSP* m_rsp; //!< Pointer to Reality Signal Processor + RDP* m_rdp; //!< Pointer to Reality Drawing Processor + VI* m_vi; //!< Pointer to Video Interface + TextureCache* m_textureCache; //!< Pointer to texture cache + FogManager* m_fogMgr; //!< Pointer to Fog Manager used to render fog. + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/renderer/eglport.c b/source/mupen64plus-video-arachnoid/src/renderer/eglport.c new file mode 100755 index 0000000..9db7809 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/eglport.c @@ -0,0 +1,706 @@ +/** + * + * EGLPORT.C + * Copyright (C) 2011-2013 Scott R. Smith + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "eglport.h" + +#include +#include + +#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 +#include +#include +#include + +#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 0) ? 1 : 0; /* 20 */ + ConfigAttribs[attrib++] = EGL_SAMPLES; /* 21 */ + ConfigAttribs[attrib++] = eglSettings[CFG_FSAA]; /* 22 */ + ConfigAttribs[attrib++] = EGL_NONE; /* 23 */ + + result = peglChooseConfig( eglDisplay, ConfigAttribs, eglConfigs, totalConfigsIn, &totalConfigsFound ); + if (result != EGL_TRUE || totalConfigsFound == 0) + { + CheckEGLErrors( __FILE__, __LINE__ ); + printf( "EGLport ERROR: Unable to query for available configs, found %d.\n", totalConfigsFound ); + return 1; + } + printf( "EGLport: Found %d available configs\n", totalConfigsFound ); + + return 0; +} + +/** @brief Error checking function + * @param file : string reference that contains the source file that the check is occuring in + * @param line : numeric reference that contains the line number that the check is occuring in + * @return : 0 if the function passed, else 1 + */ +int8_t CheckEGLErrors( const char* file, uint16_t line ) +{ + EGLenum error; + const char* errortext; + const char* description; + + error = eglGetError(); + + if (error != EGL_SUCCESS && error != 0) + { + switch (error) + { + case EGL_NOT_INITIALIZED: + errortext = "EGL_NOT_INITIALIZED."; + description = "EGL is not or could not be initialized, for the specified display."; + break; + case EGL_BAD_ACCESS: + errortext = "EGL_BAD_ACCESS EGL"; + description = "cannot access a requested resource (for example, a context is bound in another thread)."; + break; + case EGL_BAD_ALLOC: + errortext = "EGL_BAD_ALLOC EGL"; + description = "failed to allocate resources for the requested operation."; + break; + case EGL_BAD_ATTRIBUTE: + errortext = "EGL_BAD_ATTRIBUTE"; + description = "An unrecognized attribute or attribute value was passed in anattribute list."; + break; + case EGL_BAD_CONFIG: + errortext = "EGL_BAD_CONFIG"; + description = "An EGLConfig argument does not name a valid EGLConfig."; + break; + case EGL_BAD_CONTEXT: + errortext = "EGL_BAD_CONTEXT"; + description = "An EGLContext argument does not name a valid EGLContext."; + break; + case EGL_BAD_CURRENT_SURFACE: + errortext = "EGL_BAD_CURRENT_SURFACE"; + description = "The current surface of the calling thread is a window, pbuffer,or pixmap that is no longer valid."; + break; + case EGL_BAD_DISPLAY: + errortext = "EGL_BAD_DISPLAY"; + description = "An EGLDisplay argument does not name a valid EGLDisplay."; + break; + case EGL_BAD_MATCH: + errortext = "EGL_BAD_MATCH"; + description = "Arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth or stencil) not allocated by an otherwise valid surface."; + break; + case EGL_BAD_NATIVE_PIXMAP: + errortext = "EGL_BAD_NATIVE_PIXMAP"; + description = "An EGLNativePixmapType argument does not refer to a validnative pixmap."; + break; + case EGL_BAD_NATIVE_WINDOW: + errortext = "EGL_BAD_NATIVE_WINDOW"; + description = "An EGLNativeWindowType argument does not refer to a validnative window."; + break; + case EGL_BAD_PARAMETER: + errortext = "EGL_BAD_PARAMETER"; + description = "One or more argument values are invalid."; + break; + case EGL_BAD_SURFACE: + errortext = "EGL_BAD_SURFACE"; + description = "An EGLSurface argument does not name a valid surface (window,pbuffer, or pixmap) configured for rendering"; + break; + case EGL_CONTEXT_LOST: + errortext = "EGL_CONTEXT_LOST"; + description = "A power management event has occurred. The application mustdestroy all contexts and reinitialise client API state and objects to continue rendering."; + break; + default: + errortext = "Unknown EGL Error"; + description = ""; + break; + } + + printf( "EGLport ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n Description: %s\n", file, line, errortext, error, description ); + return 1; + } + + return 0; +} + +/** @brief Obtain a reference to the system's native display + * @param window : pointer to save the display reference + * @return : 0 if the function passed, else 1 + */ +int8_t GetNativeDisplay( void ) +{ + if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */ + { + printf( "EGLport: Using EGL_DEFAULT_DISPLAY\n" ); + nativeDisplay = EGL_DEFAULT_DISPLAY; + } + else if (eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */ + { +#if defined(USE_EGL_SDL) + printf( "EGLport: Opening SDL/X11 display\n" ); + SDL_VERSION(&sysWmInfo.version); + SDL_GetWMInfo(&sysWmInfo); + nativeDisplay = (EGLNativeDisplayType)sysWmInfo.info.x11.display; + + if (nativeDisplay == 0) + { + printf( "EGLport ERROR: unable to get display!\n" ); + return 1; + } +#else + printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" ); +#endif + } + + return 0; +} + +/** @brief Obtain a reference to the system's native window + * @param width : desired pixel width of the window (not used by all platforms) + * @param height : desired pixel height of the window (not used by all platforms) + * @return : 0 if the function passed, else 1 + */ +int8_t GetNativeWindow( uint16_t width, uint16_t height ) +{ + nativeWindow = 0; + +#if defined(WIZ) || defined(CAANOO) + + nativeWindow = (NativeWindowType)malloc(16*1024); + + if(nativeWindow == NULL) { + printf( "EGLport ERROR: Memory for window Failed\n" ); + return 1; + } + +#elif defined(RPI) + + EGLBoolean result; + uint32_t screen_width, screen_height; + static EGL_DISPMANX_WINDOW_T nativewindow; + DISPMANX_ELEMENT_HANDLE_T dispman_element; + DISPMANX_DISPLAY_HANDLE_T dispman_display; + DISPMANX_UPDATE_HANDLE_T dispman_update; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + + /* create an EGL window surface */ + result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height); + if(result < 0) { + printf( "EGLport ERROR: RPi graphicget_display_size failed\n" ); + return 1; + } + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = screen_width; + dst_rect.height = screen_height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = width << 16; + src_rect.height = height << 16; + + dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + dispman_update = vc_dispmanx_update_start( 0 ); + dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, + 0 /*layer*/, &dst_rect, 0 /*src*/, + &src_rect, DISPMANX_PROTECTION_NONE, (VC_DISPMANX_ALPHA_T*)0 /*alpha*/, (DISPMANX_CLAMP_T*)0 /*clamp*/, (DISPMANX_TRANSFORM_T)0 /*transform*/); + + nativewindow.element = dispman_element; + nativewindow.width = screen_width; + nativewindow.height = screen_height; + vc_dispmanx_update_submit_sync( dispman_update ); + + nativeWindow = (NativeWindowType)&nativewindow; + +#else /* default */ + + if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */ + { + nativeWindow = 0; + } + else if(eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */ + { +#if defined(USE_EGL_SDL) + /* SDL_GetWMInfo is populated when display was opened */ + nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window; + + if (nativeWindow == 0) + { + printf( "EGLport ERROR: unable to get window!\n" ); + return 1; + } +#else + printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" ); +#endif + } + else + { + printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] ); + return 1; + } + +#endif /* WIZ / CAANOO */ + + return 0; +} + +/** @brief Release the system's native display + */ +void FreeNativeDisplay( void ) +{ +} + +/** @brief Release the system's native window + */ +void FreeNativeWindow( void ) +{ +#if defined(WIZ) || defined(CAANOO) + if (nativeWindow != NULL) { + free( nativeWindow ); + } + nativeWindow = NULL; +#endif /* WIZ / CAANOO */ +} + +/** @brief Open any system specific resources + */ +void Platform_Open( void ) +{ +#if defined(PANDORA) + /* Pandora VSync */ + fbdev = open( "/dev/fb0", O_RDONLY /* O_RDWR */ ); + if ( fbdev < 0 ) { + printf( "EGLport ERROR: Couldn't open /dev/fb0 for Pandora Vsync\n" ); + } +#elif defined(RPI) + bcm_host_init(); +#endif /* PANDORA */ +} + +/** @brief Release any system specific resources + */ +void Platform_Close( void ) +{ +#if defined(PANDORA) + /* Pandora VSync */ + close( fbdev ); + fbdev = -1; +#endif /* PANDORA */ +} + +/** @brief Check the systems vsync state + */ +void Platform_VSync( void ) +{ +#if defined(PANDORA) + /* Pandora VSync */ + if (fbdev >= 0) { + int arg = 0; + ioctl( fbdev, FBIO_WAITFORVSYNC, &arg ); + } +#endif /* PANDORA */ +} + +/** @brief Get the system tick time (ms) + */ +uint32_t Platform_GetTicks( void ) +{ + uint32_t ticks = 0; +#if defined(USE_EGL_SDL) + ticks = SDL_GetTicks(); +#else + printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" ); +#endif + return ticks; +} diff --git a/source/mupen64plus-video-arachnoid/src/renderer/eglport.h b/source/mupen64plus-video-arachnoid/src/renderer/eglport.h new file mode 100755 index 0000000..736456c --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/renderer/eglport.h @@ -0,0 +1,108 @@ +/** + * + * EGLPORT.H + * Copyright (C) 2011-2013 Scott R. Smith + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef EGLPORT_H +#define EGLPORT_H + +#include +#include "EGL/egl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Defines (in every case choose only one) */ +/** Common: */ +/** DEBUG : enable additional error monitoring per EGL function call */ +/** Native display and window system for use with EGL */ +/** USE_EGL_SDL : used for access to a SDL X11 window */ +/** Platform: settings that are specific to that device */ +/** PANDORA (USE_GLES1 or USE_GLES2) */ +/** WIZ (USE_GLES1) */ +/** CAANOO (USE_GLES1) */ +/** RPI (USE_GLES1 or USE_GLES2) */ +/** GLES Version */ +/** USE_GLES1 : EGL for use with OpenGL-ES 1.X contexts */ +/** USE_GLES2 : EGL for use with OpenGL-ES 2.0 contexts */ + +/** Public API */ +void EGL_Close ( void ); +int8_t EGL_Open ( uint16_t width, uint16_t height ); +void EGL_SwapBuffers ( void ); + +extern int8_t eglColorbits; +extern int8_t eglDepthbits; +extern int8_t eglStencilbits; + +/** Simple Examples */ +/** Raw mode: + EGL_Open( window_width, window_height ); + do while(!quit) { + ... run app + EGL_SwapBuffers(); + } + EGL_Close(); +*/ +/** X11/SDL mode: + SDL_Init( SDL_INIT_VIDEO ); + SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE|SDL_FULLSCREEN); + EGL_Open( window_width, window_height ); + do while(!quit) { + ... run app + EGL_SwapBuffers(); + } + EGL_Close(); + SDL_Quit(); +*/ + +#if defined(DEBUG) +#define GET_EGLERROR(FUNCTION) \ + FUNCTION; \ + { \ + CheckEGLErrors(__FILE__, __LINE__); \ + } +#else +#define GET_EGLERROR(FUNCTION) FUNCTION; +#endif + +#define peglQueryString(A,B) GET_EGLERROR(eglQueryString(A,B)) +#define peglDestroyContext(A,B) GET_EGLERROR(eglDestroyContext(A,B)) +#define peglDestroySurface(A,B) GET_EGLERROR(eglDestroySurface(A,B)) +#define peglTerminate(A) GET_EGLERROR(eglTerminate(A)) +#define peglSwapBuffers(A,B) GET_EGLERROR(eglSwapBuffers(A,B)) +#define peglGetDisplay(A) GET_EGLERROR(eglGetDisplay(A)) +#define peglBindAPI(A) GET_EGLERROR(eglBindAPI(A)) +#define peglCreateContext(A,B,C,D) GET_EGLERROR(eglCreateContext(A,B,C,D)) +#define peglCreateWindowSurface(A,B,C,D) GET_EGLERROR(eglCreateWindowSurface(A,B,C,D)) +#define peglInitialize(A,B,C) GET_EGLERROR(eglInitialize(A,B,C)) +#define peglMakeCurrent(A,B,C,D) GET_EGLERROR(eglMakeCurrent(A,B,C,D)) +#define peglChooseConfig(A,B,C,D,E) GET_EGLERROR(eglChooseConfig(A,B,C,D,E)) +#define peglSwapInterval(A,B) GET_EGLERROR(eglSwapInterval(A,B)) + +#ifdef __cplusplus +} +#endif + +#endif /* EGLPORT_H */ diff --git a/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp new file mode 100755 index 0000000..ed8e700 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp @@ -0,0 +1,129 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "CachedTexture.h" + +#include "m64p.h" +#include "OpenGL.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +CachedTexture::CachedTexture() +{ + m_id = 0; //!< id used by OpenGL to identify texture + m_textureSize = 0; //!< Size of texture in bytes + address = 0; + crc = 0; + offsetS = offsetT = 0; + maskS = maskT = 0; + clampS = clampT = 0; + mirrorS = mirrorT = 0; + line = 0; + size = 0; + format = 0; //!< Texture format + tMem = 0; + palette = 0; //!< What Texture Look Up Table to use + width = height = 0; // N64 width and height + clampWidth = clampHeight = 0; // Size to clamp to + realWidth = realHeight = 0; // Actual texture size + scaleS = scaleT = 0; // Scale to map to 0.0-1.0 + shiftScaleS = shiftScaleT = 0; // Scale to shift +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +CachedTexture::~CachedTexture() +{ + +} + +//----------------------------------------------------------------------------- +//! Activate texture +//----------------------------------------------------------------------------- +void CachedTexture::activate() +{ + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, m_id ); +} + +//----------------------------------------------------------------------------- +//! Deactivate texture +//----------------------------------------------------------------------------- +void CachedTexture::deactivate() +{ + glDisable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, 0 ); +} + +//----------------------------------------------------------------------------- +//! Equal operator +//----------------------------------------------------------------------------- +bool CachedTexture::operator == (const CachedTexture& t) const +{ + return( crc == t.crc && + width == t.width && + height == t.height && + clampWidth == t.clampWidth && + clampHeight == t.clampHeight && + maskS == t.maskS && + maskT == t.maskT && + mirrorS == t.mirrorS && + mirrorT == t.mirrorT && + clampS == t.clampS && + clampT == t.clampT && + format == t.format /* && + size == t.size */ ); +} + +//----------------------------------------------------------------------------- +//! Assign operator +//----------------------------------------------------------------------------- +CachedTexture& CachedTexture::operator = (const CachedTexture& v) +{ + address = v.address; + crc = v.crc; + format = v.format; + size = v.size; + width = v.width; + height = v.height; + clampWidth = v.clampWidth; + clampHeight = v.clampHeight; + palette = v.palette; +/* cache.current[tile]->fulS = gSP.textureTile[tile]->fulS; + cache.current[tile]->fulT = gSP.textureTile[tile]->fulT; + cache.current[tile]->ulS = gSP.textureTile[tile]->ulS; + cache.current[tile]->ulT = gSP.textureTile[tile]->ulT; + cache.current[tile]->lrS = gSP.textureTile[tile]->lrS; + cache.current[tile]->lrT = gSP.textureTile[tile]->lrT;*/ + maskS = v.maskS; + maskT = v.maskT; + mirrorS = v.mirrorS; + mirrorT = v.mirrorT; + clampS = v.clampS; + clampT = v.clampT; + line = v.line; + tMem = v.tMem; + //lastDList = RSP.DList; + //frameBufferTexture = FALSE; + return *this; +} diff --git a/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h new file mode 100755 index 0000000..1efbad7 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/CachedTexture.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef CACHED_TEXTURE_H_ +#define CACHED_TEXTURE_H_ + +//***************************************************************************** +//* Cached Texture +//! Struct used by Texture Cache to store used textures. +//***************************************************************************** +class CachedTexture +{ +public: + + //Constructor / Destrucotr + CachedTexture(); + ~CachedTexture(); + + //Activate / Deactivate + void activate(); + void deactivate(); + + //Get texture size + unsigned int getTextureSize() { return m_textureSize; } + + //Assignment operator + CachedTexture& operator = (const CachedTexture& v); + + //Equal operator + bool operator == (const CachedTexture& t) const; + +public: + + unsigned int m_id; //!< id used by OpenGL to identify texture + unsigned int m_textureSize; //!< Size of texture in bytes + + unsigned int address; + unsigned int crc; //!< A CRC "checksum" (Cyclic redundancy check) +// float fulS, fulT; +// unsigned short ulS, ulT, lrS, lrT; + float offsetS, offsetT; + unsigned int maskS, maskT; + unsigned int clampS, clampT; + unsigned int mirrorS, mirrorT; + unsigned int line; + unsigned int size; + unsigned int format; //!< Texture format + unsigned int tMem; + unsigned int palette; //!< What Texture Look Up Table to use + unsigned int width, height; //!< N64 width and height + unsigned int clampWidth, clampHeight; //!< Size to clamp to + unsigned int realWidth, realHeight; //!< Actual texture size + float scaleS, scaleT; //!< Scale to map to 0.0-1.0 + float shiftScaleS, shiftScaleT; //!< Scale to shift +// unsigned int lastDList; +// unsigned int frameBufferTexture; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp new file mode 100755 index 0000000..c834712 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp @@ -0,0 +1,314 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +//***************************************************************************** +// +// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64. +// http://gln64.emulation64.com/ +// +//***************************************************************************** + +#include "ImageFormatSelector.h" +#include "CachedTexture.h" +#include "assembler.h" +#include "GBIDefs.h" +#include "m64p.h" +#include "OpenGL.h" +#include "Memory.h" + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 + #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 + #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 + #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 + #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif /* GL_EXT_packed_pixels */ + +unsigned long long* TMEM = Memory::getTextureMemory(); + + +inline unsigned int GetNone( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return 0x00000000; +} + +inline unsigned int GetCI4IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetIA31_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetIA31_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetI4_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetI4_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetCI8IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetIA44_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA44_RGBA8888(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetIA44_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA44_RGBA4444(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetI8_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return I8_RGBA8888(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetI8_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return I8_RGBA4444(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetRGBA5551_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA8888( ((unsigned short*)src)[x^i] ); +} + +inline unsigned int GetRGBA5551_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA5551( ((unsigned short*)src)[x^i] ); +} + +inline unsigned int GetIA88_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA8888(((unsigned short*)src)[x^i]); +} + +inline unsigned int GetIA88_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA4444(((unsigned short*)src)[x^i]); +} + +inline unsigned int GetRGBA8888_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return ((unsigned int*)src)[x^i]; +} + +inline unsigned int GetRGBA8888_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA8888_RGBA4444(((unsigned int*)src)[x^i]); +} + +/* +const struct +{ + GetTexelFunc Get16; + unsigned int glType16; + int glInternalFormat16; + GetTexelFunc Get32; + unsigned int glType32; + int glInternalFormat32; + unsigned int autoFormat, lineShift, maxTexels; +} +*/ +ImageFormat ImageFormatSelector::imageFormats[4][5] = +{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat + { // 4-bit + { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // YUV + { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 4, 4096 }, // CI + { GetIA31_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA31_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // IA + { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // I + }, + { // 8-bit + { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 3, 2048 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 4096 }, // YUV + { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 3, 2048 }, // CI + { GetIA44_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA44_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 3, 4096 }, // IA + { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 3, 4096 }, // I + }, + { // 16-bit + { GetRGBA5551_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 2, 2048 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 2, 2048 }, // YUV + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // CI + { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 2048 }, // IA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // I + }, + { // 32-bit + { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 1024 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // YUV + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // CI + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // IA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // I + } +}; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +ImageFormatSelector::ImageFormatSelector() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +ImageFormatSelector::~ImageFormatSelector() +{ + +} + +//----------------------------------------------------------------------------- +// Detect Image Format +//----------------------------------------------------------------------------- +void ImageFormatSelector::detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT) +{ + if (((imageFormats[texture->size][texture->format].autoFormat == GL_RGBA8) || + ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) || + (textureBitDepth == 2)) && (textureBitDepth != 0)) + { + texture->m_textureSize = (texture->realWidth * texture->realHeight) << 2; + if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) + { + if (texture->size == G_IM_SIZ_4b) + getTexelFunc = GetCI4IA_RGBA8888; + else + getTexelFunc = GetCI8IA_RGBA8888; + + internalFormat = GL_RGBA8; + imageType = GL_UNSIGNED_BYTE; + } + else + { + getTexelFunc = imageFormats[texture->size][texture->format].Get32; + internalFormat = imageFormats[texture->size][texture->format].glInternalFormat32; + imageType = imageFormats[texture->size][texture->format].glType32; + } + } + else + { + texture->m_textureSize = (texture->realWidth * texture->realHeight) << 1; + if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) + { + if (texture->size == G_IM_SIZ_4b) + getTexelFunc = GetCI4IA_RGBA4444; + else + getTexelFunc = GetCI8IA_RGBA4444; + + internalFormat = GL_RGBA4; + imageType = GL_UNSIGNED_SHORT_4_4_4_4_EXT; + } + else + { + getTexelFunc = imageFormats[texture->size][texture->format].Get16; + internalFormat = imageFormats[texture->size][texture->format].glInternalFormat16; + imageType = imageFormats[texture->size][texture->format].glType16; + } + } +} diff --git a/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h new file mode 100755 index 0000000..3ab1552 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef IMAGE_FORMAT_SELECTOR_H_ +#define IMAGE_FORMAT_SELECTOR_H_ + +//Function pointer for image decoding +typedef unsigned int (*GetTexelFunc)( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ); + +//Forward declarations +class CachedTexture; + +//***************************************************************************** +//* ImageFormat +//! Struct used when diffining image formats and how to convert/decode/interperite them. +//***************************************************************************** +struct ImageFormat +{ + GetTexelFunc Get16; + unsigned int glType16; + int glInternalFormat16; + GetTexelFunc Get32; + unsigned int glType32; + int glInternalFormat32; + unsigned int autoFormat, lineShift, maxTexels; +}; + +//***************************************************************************** +//* ImageFormatSelector +//! Class for selecting image format decoding functions depending on image format. +//***************************************************************************** +class ImageFormatSelector +{ +public: + + //Constructor / Destructor + ImageFormatSelector(); + ~ImageFormatSelector(); + + //Detect image format + void detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT); + +public: + + //Static variables + static ImageFormat imageFormats[4][5]; //!< Defines how to decode diffrent formats + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp new file mode 100755 index 0000000..c30e7f1 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.cpp @@ -0,0 +1,627 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "TextureCache.h" + +#include "RDP.h" +#include "RSP.h" +#include "CachedTexture.h" +#include "MathLib.h" +#include + 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 + +//----------------------------------------------------------------------------- +//! 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; ygetTextureMemory((tile->tmem + (y * line)) & 511); + crc = m_crcCalculator.calcCRC( crc, src, bpl ); + //TODO: remove if new works + //src += line; + } + + if ( tile->format == G_IM_FMT_CI ) + { + if ( tile->size == G_IM_SIZ_4b ) + crc = m_crcCalculator.calcCRC( crc, &m_rdp->m_paletteCRC16[tile->palette], 4 ); + else if (tile->size == G_IM_SIZ_8b) + crc = m_crcCalculator.calcCRC( crc, &m_rdp->m_paletteCRC256, 4 ); + } + return crc; +} + +void TextureCache::_activateTexture( unsigned int t, CachedTexture *texture ) +{ + // If multitexturing, set the appropriate texture + //if (OGL.ARB_multitexture) + glActiveTextureARB( GL_TEXTURE0_ARB + t ); + + // Bind the cached texture + texture->activate(); + + // Set filter mode. Almost always bilinear, but check anyways + unsigned int textureFiltering = m_rdp->getTextureFiltering(); + if ( textureFiltering == G_TF_BILERP || textureFiltering == G_TF_AVERAGE ) + { + if( m_mipmap > 0 ) + { + // Set Mipmap + if(m_mipmap == 1) // nearest + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + } + else if(m_mipmap == 2) // bilinear + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + } + else if(m_mipmap == 3) // trilinear + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } + + // Tell to hardware to generate mipmap (himself) when glTexImage2D is called + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + } + else // no mipmapping + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE ); + } + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + + } + else + { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + } + + + + // Set clamping modes + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture->clampS ? GL_CLAMP_TO_EDGE : GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture->clampT ? GL_CLAMP_TO_EDGE : GL_REPEAT ); + + //texture->lastDList = RSP.DList; + + moveToTop( texture ); + + m_currentTextures[t] = texture; +} diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureCache.h b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.h new file mode 100755 index 0000000..9712f89 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/TextureCache.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef TEXTURE_CACHE_H_ +#define TEXTURE_CACHE_H_ + +#include "CachedTexture.h" +#include "CRCCalculator2.h" +#include "ImageFormatSelector.h" +#include + +//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 TextureList; + TextureList m_cachedTextures; //!< List of cached textures + + //Pointers to current textures + CachedTexture* m_currentTextures[2]; //!< Two textures for multi-texturing. + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp new file mode 100755 index 0000000..4de0af3 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp @@ -0,0 +1,267 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "TextureLoader.h" +#include "Memory.h" +#include "TextureCache.h" +#include "GBIDefs.h" +#include "assembler.h" +#include "Logger.h" +#include "RDP.h" +#include "CRCCalculator2.h" + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +TextureLoader::TextureLoader() +{ + +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +TextureLoader::~TextureLoader() +{ + +} + +//----------------------------------------------------------------------------- +//* Initialize +//! Saves pointers to objects +//----------------------------------------------------------------------------- +bool TextureLoader::initialize(RDP* rdp, Memory* memory) +{ + m_rdp = rdp; + m_memory = memory; + + m_currentTile = &m_tiles[7]; + return true; +} + +//----------------------------------------------------------------------------- +//* Set Texture Image +//! Stores information about texture image. +//----------------------------------------------------------------------------- +void TextureLoader::setTextureImage(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress) +{ + m_textureImage.address = m_memory->getRDRAMAddress( segmentAddress ); + m_textureImage.format = format; + m_textureImage.size = size; + m_textureImage.width = width + 1; //Note: add plus one, glN64 does it outside of function + m_textureImage.bpl = m_textureImage.width << m_textureImage.size >> 1; +} + +//----------------------------------------------------------------------------- +//* Set Tile +//! Stores information about an rdp tile. +//----------------------------------------------------------------------------- +void TextureLoader::setTile( int format, int size, int line, int tmem, int tile, int palette, + int clampS, int clampT, int mirrorS, int mirrorT, int maskS, + int maskT, int shiftS, int shiftT ) +{ + m_tiles[tile].format = format; + m_tiles[tile].size = size; + m_tiles[tile].line = line; + m_tiles[tile].tmem = tmem; + m_tiles[tile].palette = palette; + m_tiles[tile].clamps = clampS; + m_tiles[tile].clampt = clampT; + m_tiles[tile].mirrors = mirrorS; + m_tiles[tile].mirrort = mirrorT; + m_tiles[tile].masks = maskS; + m_tiles[tile].maskt = maskT; + m_tiles[tile].shiftt = shiftT; + m_tiles[tile].shifts = shiftS; + + if ( !m_tiles[tile].masks ) + m_tiles[tile].clamps = 1; + if ( !m_tiles[tile].maskt ) + m_tiles[tile].clampt = 1; + + // + if (((size == G_IM_SIZ_4b) || (size == G_IM_SIZ_8b)) && (format == G_IM_FMT_RGBA)) { + m_tiles[tile].format = G_IM_FMT_CI; + } +} + +//----------------------------------------------------------------------------- +//* Set Tile Size +//! Stores size information for a rdp tile. +//----------------------------------------------------------------------------- +void TextureLoader::setTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1) +{ + m_tiles[tile].uls = _SHIFTR( s0, 2, 10 ); + m_tiles[tile].ult = _SHIFTR( t0, 2, 10 ); + m_tiles[tile].lrs = _SHIFTR( s1, 2, 10 ); + m_tiles[tile].lrt = _SHIFTR( t1, 2, 10 ); + m_tiles[tile].fuls = _FIXED2FLOAT( s0, 2 ); + m_tiles[tile].fult = _FIXED2FLOAT( t0, 2 ); + m_tiles[tile].flrs = _FIXED2FLOAT( s1, 2 ); + m_tiles[tile].flrt = _FIXED2FLOAT( t1, 2 ); +} + +//----------------------------------------------------------------------------- +//* Load Tile (to texture memory) +//! Kopies texture data from RDRAM to Texture Memory +//----------------------------------------------------------------------------- +void TextureLoader::loadTile(int tile, int s0, int t0, int s1, int t1) +{ + void (*Interleave)( void *mem, unsigned int numDWords ); + + + //unsigned int tile = _SHIFTR( ucode->w1, 24, 3 ); + + unsigned int address, height, bpl, line, y; + unsigned long long *dest; + unsigned char *src; + + //Set new Tile Size + this->setTileSize(tile, s0, t0, s1, t1); + m_currentTile = &m_tiles[tile]; + + if (m_currentTile->line == 0) + return; + + address = m_textureImage.address + m_currentTile->ult * m_textureImage.bpl + (m_currentTile->uls << m_textureImage.size >> 1); + dest = m_memory->getTextureMemory( m_currentTile->tmem ); + bpl = (m_currentTile->lrs - m_currentTile->uls + 1) << m_currentTile->size >> 1; + height = m_currentTile->lrt - m_currentTile->ult + 1; + src = m_memory->getRDRAM(address); + + if (((address + height * bpl) > m_memory->getRDRAMSize()) || (((m_currentTile->tmem << 3) + bpl * height) > 4096)) // Stay within TMEM + { + return; + } + + // Line given for 32-bit is half what it seems it should since they split the + // high and low words. I'm cheating by putting them together. + if (m_currentTile->size == G_IM_SIZ_32b) + { + line = m_currentTile->line << 1; + Interleave = QWordInterleave; + } + else + { + line = m_currentTile->line; + Interleave = DWordInterleave; + } + + for (y = 0; y < height; y++) + { + UnswapCopy( src, dest, bpl ); + if (y & 1) Interleave( dest, line ); + + src += m_textureImage.bpl; + dest += line; + } +} + +//----------------------------------------------------------------------------- +//* Load Block (to texture memory) +//! Kopies texture data from RDRAM to Texture Memory +//----------------------------------------------------------------------------- +void TextureLoader::loadBlock(int tile, int s0, int t0, int s1, int t1) +{ + unsigned int dxt = t1; + + //Set new Tile Size + this->setTileSize(tile, s0, t0, s1, t1); + m_currentTile = &m_tiles[tile]; + + + unsigned int bytes = (s1 + 1) << m_currentTile->size >> 1; + unsigned int address = m_textureImage.address + t0 * m_textureImage.bpl + (s0 << m_textureImage.size >> 1); + + if ((bytes == 0) || ((address + bytes) > m_memory->getRDRAMSize()) || (((m_currentTile->tmem << 3) + bytes) > 4096)) + { + return; + } + + unsigned long long* src = (unsigned long long*)m_memory->getRDRAM(address); + unsigned long long* dest = m_memory->getTextureMemory(m_currentTile->tmem); + + unsigned int line = 0; + + if (dxt > 0) + { + void (*Interleave)( void *mem, unsigned int numDWords ); + + line = (2047 + dxt) / dxt; + unsigned int bpl = line << 3; + unsigned int height = bytes / bpl; + + if (m_currentTile->size == G_IM_SIZ_32b) + Interleave = QWordInterleave; + else + Interleave = DWordInterleave; + + for (unsigned int y = 0; y < height; y++) + { + UnswapCopy( src, dest, bpl ); + if (y & 1) Interleave( dest, line ); + + src += line; + dest += line; + } + } + else + UnswapCopy( src, dest, bytes ); +} + +//----------------------------------------------------------------------------- +//* Load Texture Look up table (to texture memory) +//! Kopies texture data from RDRAM to Texture Memory +//----------------------------------------------------------------------------- +void TextureLoader::loadTLUT(int tile, int s0, int t0, int s1, int t1) +{ + CRCCalculator2 crcCalculator; + + //Set new Tile Size + this->setTileSize(tile, s0, t0, s1, t1); + + + unsigned short count = (m_tiles[tile].lrs - m_tiles[tile].uls + 1) * (m_tiles[tile].lrt - m_tiles[tile].ult + 1); + unsigned int address = m_textureImage.address + m_tiles[tile].ult * m_textureImage.bpl + (m_tiles[tile].uls << m_textureImage.size >> 1); + + //Copy from rdram to texture memory + unsigned short *src = (unsigned short*)m_memory->getRDRAM(address); + unsigned short *dest = (unsigned short*)m_memory->getTextureMemory(m_tiles[tile].tmem); + + unsigned short pal = (m_tiles[tile].tmem - 256) >> 4; + + int i = 0; + while (i < count) + { + for (unsigned short j = 0; (j < 16) && (i < count); j++, i++) + { + unsigned short color = swapword( src[i^1] ); + *dest = color; + dest += 4; + } + + + m_rdp->m_paletteCRC16[pal] = crcCalculator.calcPaletteCRC(0xFFFFFFFF, m_memory->getTextureMemory(256 + (pal << 4)), 16); + pal++; + } + + m_rdp->m_paletteCRC256 = crcCalculator.calcCRC(0xFFFFFFFF, m_rdp->m_paletteCRC16, 64); +} diff --git a/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h new file mode 100755 index 0000000..78ad1c2 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/TextureLoader.h @@ -0,0 +1,154 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef TEXTURE_LOADER_H_ +#define TEXTURE_LOADER_H_ + +#include "GBIDefs.h" + +//Forward declarations +class Memory; +class RDP; + +//***************************************************************************** +//* TextureImage +//! Used to store information about texture image +//***************************************************************************** +struct TextureImage +{ + unsigned int format; + unsigned int size; + unsigned int width; + unsigned int bpl; + unsigned int address; + + //! Constructor + TextureImage() + { + format = size = width = bpl = 0; + address = 0; + } +}; + +//***************************************************************************** +//* RDP Tile +//! Struct used to store information used then loading textures. +//***************************************************************************** +struct RDPTile +{ + unsigned int format, size, line, tmem, palette; + + union + { + struct + { + unsigned int mirrort : 1; + unsigned int clampt : 1; + unsigned int pad0 : 30; + unsigned int mirrors : 1; + unsigned int clamps : 1; + unsigned int pad1 : 30; + }; + struct + { + unsigned int cmt, cms; + }; + }; + + //FrameBuffer *frameBuffer; + unsigned int maskt, masks; + unsigned int shiftt, shifts; + float fuls, fult, flrs, flrt; + unsigned int uls, ult, lrs, lrt; + + unsigned int getWidth() { return lrs - uls + 1; } + unsigned int getHeight() { return lrt - ult + 1; } + + //! Constructor + RDPTile() + { + format = size = line = tmem = palette = 0; + maskt = masks = 0; + shiftt = shifts = 0; + fuls = fult = flrs = flrt = 0; + uls = ult = lrs = lrt = 0; + } +}; + +//***************************************************************************** +//* Texture Loader +//! Class for loading texturs from RDRAM to Texture Memory +//***************************************************************************** +class TextureLoader +{ +public: + + //Constructor / Destructor + TextureLoader(); + ~TextureLoader(); + + bool initialize(RDP* rdp, Memory* memory); + + //Set Texture Image + void setTextureImage(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress); + + //Set Tile + void setTile(int format, int size, int line, int tmem, int tile, int palette, + int clampS, int clampT, int mirrorS, int mirrorT, int maskS, + int maskT, int shiftS, int shiftT); + + //Set Tile Size + void setTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1); + + //Load Tile + void loadTile(int tile, int s0, int t0, int s1, int t1); + + //Load Block + void loadBlock(int tile, int s0, int t0, int s1, int t1); + + //Load Texture Look up table + void loadTLUT(int tile, int s0, int t0, int s1, int t1); + +public: + + //! Returns information about current texture image + TextureImage* getTextureImage() { return &m_textureImage; } + + //! Returns previusly loaded tile + RDPTile* getCurrentTile() { return m_currentTile; } + + //! Returns a tile + //! @param tile which of the eight tiles to return. + RDPTile* getTile(unsigned int tile) { return &m_tiles[tile]; } + +private: + + Memory* m_memory; //!< Pointer to Memory Manager + RDP* m_rdp; //!< Pointer to Reality Signal Processor + + //Tiles + RDPTile m_tiles[8]; //!< Eight tiles + RDPTile* m_currentTile; //!< Previusly loaded tile + TextureImage m_textureImage; //!< Texture Image + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp new file mode 100755 index 0000000..a0d9c3b --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp @@ -0,0 +1,553 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" +#include "DisplayListParser.h" + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode0::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode0::m_rdp = 0; //!< Pointer to Reality Drawing Processor +DisplayListParser* UCode0::m_displayListParser = 0; +Memory* UCode0::m_memory = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode0::UCode0() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode0::~UCode0() +{ +} + +//----------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------- +void UCode0::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp) +{ + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//* Initialize GBI +//! Assigns functions to the GBI +//----------------------------------------------------------------------------- +void UCode0::initializeGBI(GBI* gbi) +{ + // Set GeometryMode flags + GBI_InitFlags( F3D ); + + //GBI Command Command Value Target Command Function + GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, gbi->m_cmds, F3D_SPNoOp ); + GBI_SetGBI( GBI::G_MTX, F3D_MTX, gbi->m_cmds, F3D_Mtx ); + GBI_SetGBI( GBI::G_RESERVED0, F3D_RESERVED0, gbi->m_cmds, F3D_Reserved0 ); + GBI_SetGBI( GBI::G_MOVEMEM, F3D_MOVEMEM, gbi->m_cmds, F3D_MoveMem ); + GBI_SetGBI( GBI::G_VTX, F3D_VTX, gbi->m_cmds, F3D_Vtx ); + GBI_SetGBI( GBI::G_RESERVED1, F3D_RESERVED1, gbi->m_cmds, F3D_Reserved1 ); + GBI_SetGBI( GBI::G_DL, F3D_DL, gbi->m_cmds, F3D_DList ); + GBI_SetGBI( GBI::G_RESERVED2, F3D_RESERVED2, gbi->m_cmds, F3D_Reserved2 ); + GBI_SetGBI( GBI::G_RESERVED3, F3D_RESERVED3, gbi->m_cmds, F3D_Reserved3 ); + GBI_SetGBI( GBI::G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, gbi->m_cmds, F3D_Sprite2D_Base ); + GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, gbi->m_cmds, F3D_MoveWord ); + GBI_SetGBI( GBI::G_TRI1, F3D_TRI1, gbi->m_cmds, F3D_Tri1 ); + GBI_SetGBI( GBI::G_CULLDL, F3D_CULLDL, gbi->m_cmds, F3D_CullDL ); + GBI_SetGBI( GBI::G_POPMTX, F3D_POPMTX, gbi->m_cmds, F3D_PopMtx ); + GBI_SetGBI( GBI::G_TEXTURE, F3D_TEXTURE, gbi->m_cmds, F3D_Texture ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, gbi->m_cmds, F3D_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, gbi->m_cmds, F3D_SetOtherMode_L ); + GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, gbi->m_cmds, F3D_EndDL ); + GBI_SetGBI( GBI::G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, gbi->m_cmds, F3D_SetGeometryMode ); + GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE,gbi->m_cmds, F3D_ClearGeometryMode ); + GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, gbi->m_cmds, F3D_Quad ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, gbi->m_cmds, F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, gbi->m_cmds, F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_RDPHALF_CONT, F3D_RDPHALF_CONT, gbi->m_cmds, F3D_RDPHalf_Cont ); + GBI_SetGBI( GBI::G_TRI4, F3D_TRI4, gbi->m_cmds, F3D_Tri4 ); +} + +//***************************************************************************** +// Matrix Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Add Matrix +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_Mtx(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Mtx", M64MSG_VERBOSE); + RSPUCodeAddMatrix0* temp = (RSPUCodeAddMatrix0*)ucode; + + //Add matrix + m_rsp->RSP_Matrix( temp->segmentAddress, //Segment adress + temp->projection, //Projection or view matrix? + temp->push, //Save Current Matrix? + temp->load ); //Replace aka Load or Mult +} + +//----------------------------------------------------------------------------- +//* Pop Matrix +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_PopMtx(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_PopMtx", M64MSG_VERBOSE); + + //Pop Matrix + m_rsp->RSP_PopMatrix(); +} + +//***************************************************************************** +// Vertex Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Add Vertex +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_Vtx(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Vtx", M64MSG_VERBOSE); + RSPUCodeAddVertices0* temp = (RSPUCodeAddVertices0*)ucode; + + //Add vertex + m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices + 1, temp->firstVertex); +} + +//----------------------------------------------------------------------------- +//* F3D Render 1 Triangle +//! @param ucode instruction from displaylist with input data +//! @todo Triangle flag? +//----------------------------------------------------------------------------- +void UCode0::F3D_Tri1(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Tri1", M64MSG_VERBOSE); + RSPUCodeAddOneTriangleF3D* temp = (RSPUCodeAddOneTriangleF3D*)ucode; + + //Add one triangle //TODO Flag? + m_rsp->RSP_1Triangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10); +} + +//----------------------------------------------------------------------------- +//* F3D Render 4 Triangles +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_Tri4(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Tri4", M64MSG_VERBOSE); + RSPUCodeAddFourTrianglesF3D* temp = (RSPUCodeAddFourTrianglesF3D*)ucode; + + //Add four triangles + m_rsp->RSP_4Triangles( temp->v0, temp->v1, temp->v2, + temp->v3, temp->v4, temp->v5, + temp->v6, temp->v7, temp->v8, + temp->v9, temp->v10, temp->v11); +} + +//----------------------------------------------------------------------------- +//* F3D Render 1 Quad +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_Quad(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Quad", M64MSG_VERBOSE); + RSPUCodeAddOneQuadF3D* temp = (RSPUCodeAddOneQuadF3D*)ucode; + + //Add one Quad + m_rsp->RSP_1Quadrangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10, temp->index3 / 10); +} + +//***************************************************************************** +// Display List Functions +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Display List +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_DList(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_DList", M64MSG_VERBOSE); + RSPUCodeDisplayList* temp = (RSPUCodeDisplayList*)ucode; + + switch ( temp->param ) + { + case G_DL_PUSH : m_rsp->RSP_DisplayList( temp->segmentAddress ); break; + case G_DL_NOPUSH : m_rsp->RSP_BranchList( temp->segmentAddress ); break; + } +} + +//----------------------------------------------------------------------------- +//* End Display List +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_EndDL(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_EndDL", M64MSG_VERBOSE); + + //End Display List + m_rsp->RSP_EndDisplayList(); +} + +//----------------------------------------------------------------------------- +// Cull Display List +//! @todo Cull Display List +//----------------------------------------------------------------------------- +void UCode0::F3D_CullDL(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_CullDL", M64MSG_VERBOSE); + //TODO +} + +//***************************************************************************** +// Texturing +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Texture +//----------------------------------------------------------------------------- +void UCode0::F3D_Texture(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Texture", M64MSG_VERBOSE); + RSPUCodeTexture* temp = (RSPUCodeTexture*)ucode; + + float scaleS = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 ); + float scaleT = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 ); + int on = _SHIFTR( ucode->w0, 0, 8 ); + + m_rsp->RSP_Texture(scaleS, scaleT, (int)temp->level, (int)temp->tile, on); +} + +//***************************************************************************** +// Half +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Half 1 +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_RDPHalf_1(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_RDPHalf_1", M64MSG_VERBOSE); + m_rdp->setHalf1( ucode->w1 ); +} + +//----------------------------------------------------------------------------- +//* Half 2 +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode0::F3D_RDPHalf_2(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_RDPHalf_2", M64MSG_VERBOSE); + m_rdp->setHalf2( ucode->w1 ); +} +//----------------------------------------------------------------------------- +// Half Cont +//----------------------------------------------------------------------------- +void UCode0::F3D_RDPHalf_Cont(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_RDPHalf_Cont", M64MSG_VERBOSE); + //Ignore +} + +//***************************************************************************** +// Geometry Mode +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Set Geometry Mode +//----------------------------------------------------------------------------- +void UCode0::F3D_SetGeometryMode(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_SetGeometryMode", M64MSG_VERBOSE); + m_rsp->RSP_SetGeometryMode(ucode->w1); +} + +//----------------------------------------------------------------------------- +// Clear Geometry Mode +//----------------------------------------------------------------------------- +void UCode0::F3D_ClearGeometryMode(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_ClearGeometryMode", M64MSG_VERBOSE); + m_rsp->RSP_ClearGeometryMode(ucode->w1); +} + +//***************************************************************************** +// Set Other Modes +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Set Other Mode H +//----------------------------------------------------------------------------- +void UCode0::F3D_SetOtherMode_H(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_SetOtherMode_H", M64MSG_VERBOSE); + + unsigned int otherModeType = _SHIFTR(ucode->w0, 8, 8); + unsigned int w1 = ucode->w1; + + switch ( otherModeType ) + { + case G_MDSFT_PIPELINE: + //gDPPipelineMode( w1 >> G_MDSFT_PIPELINE ); + break; + case G_MDSFT_CYCLETYPE: + m_rdp->setCycleType( G_CYCLE_TYPE(w1 >> G_MDSFT_CYCLETYPE) ); + break; + + case G_MDSFT_TEXTPERSP: + //gDPSetTexturePersp( w1 >> G_MDSFT_TEXTPERSP ); + break; + case G_MDSFT_TEXTDETAIL: + //gDPSetTextureDetail( w1 >> G_MDSFT_TEXTDETAIL ); + break; + case G_MDSFT_TEXTLOD: + //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD ); + break; + case G_MDSFT_TEXTLUT: + m_rdp->setTextureLUT( w1 >> G_MDSFT_TEXTLUT ); + break; + case G_MDSFT_TEXTFILT: + m_rdp->setTextureFiltering(w1 >> G_MDSFT_TEXTFILT); + break; + case G_MDSFT_TEXTCONV: + //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV ); + break; + case G_MDSFT_COMBKEY: + //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY ); + break; + case G_MDSFT_RGBDITHER: + //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER ); + break; + case G_MDSFT_ALPHADITHER: + //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER ); + break; + default: + unsigned int shift = _SHIFTR( ucode->w0, 8, 8 ); + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ); + unsigned int mask = ((1 << length) - 1) << shift; + m_rdp->m_otherMode.h &= ~mask; + m_rdp->m_otherMode.h |= w1 & mask; + m_rdp->setUpdateCombiner(true); + break; + } +} + +//----------------------------------------------------------------------------- +// Set Other Mode L +//----------------------------------------------------------------------------- +void UCode0::F3D_SetOtherMode_L(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_SetOtherMode_L", M64MSG_VERBOSE); + + switch (_SHIFTR( ucode->w0, 8, 8 )) + { + case G_MDSFT_ALPHACOMPARE: + m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE); + break; + case G_MDSFT_ZSRCSEL: + m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL ); + break; + case G_MDSFT_RENDERMODE: + m_rdp->setRenderMode(ucode->w1); + break; + default: + unsigned int shift = _SHIFTR( ucode->w0, 8, 8 ); + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ); + unsigned int mask = ((1 << length) - 1) << shift; + + m_rdp->m_otherMode.l &= ~mask; + m_rdp->m_otherMode.l |= ucode->w1 & mask; + break; + } +} + + +//***************************************************************************** +// Other +//***************************************************************************** + +//----------------------------------------------------------------------------- +//* Move Mem +//! @todo Add more case in switch, Like Force Matrix +//----------------------------------------------------------------------------- +void UCode0::F3D_MoveMem(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_MoveMem", M64MSG_VERBOSE); + + unsigned int type = ((ucode->w0)>>16)&0xFF; + unsigned int segmentAddress = ucode->w1; + + switch (type) + { + //Viewport + case F3D_MV_VIEWPORT: + m_rsp->moveMemViewport(segmentAddress); + break; + + case G_MV_MATRIX_1: + m_rsp->RSP_ForceMatrix(segmentAddress); + m_displayListParser->increasePC(24); //// force matrix takes four commands + break; + + //Lights + case G_MV_L0: m_rsp->RSP_Light(0, segmentAddress); break; + case G_MV_L1: m_rsp->RSP_Light(1, segmentAddress); break; + case G_MV_L2: m_rsp->RSP_Light(2, segmentAddress); break; + case G_MV_L3: m_rsp->RSP_Light(3, segmentAddress); break; + case G_MV_L4: m_rsp->RSP_Light(4, segmentAddress); break; + case G_MV_L5: m_rsp->RSP_Light(5, segmentAddress); break; + case G_MV_L6: m_rsp->RSP_Light(6, segmentAddress); break; + case G_MV_L7: m_rsp->RSP_Light(7, segmentAddress); break; + + //Look at + case G_MV_LOOKATX: + //IGNORE + break; + //Look at + case G_MV_LOOKATY: + //IGNORE + break; + + //case RSP_GBI1_MV_MEM_LOOKATY: + // //IGNORE + // break; + //case RSP_GBI1_MV_MEM_LOOKATX: + // //IGNORE + // break; + + //TODO? + //case RSP_GBI1_MV_MEM_TXTATT: break; + //case RSP_GBI1_MV_MEM_MATRIX_1: + // RSP_GFX_Force_Matrix(addr); + // break; + //case RSP_GBI1_MV_MEM_MATRIX_2: break; + //case RSP_GBI1_MV_MEM_MATRIX_3: break; + //case RSP_GBI1_MV_MEM_MATRIX_4: break; + + default: + Logger::getSingleton().printMsg("F3D_MoveMem: Unknown type", M64MSG_WARNING); + break; + } +} + +//----------------------------------------------------------------------------- +//* F3D Sprite2D Base +//! @todo F3D Sprite2D Base +//----------------------------------------------------------------------------- +void UCode0::F3D_Sprite2D_Base(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_Sprite2D_Base - Unimplemented", M64MSG_WARNING); + //TODO +} + +//----------------------------------------------------------------------------- +// Move Word +//----------------------------------------------------------------------------- +void UCode0::F3D_MoveWord(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3D_MoveWord"); + RSPUCodeMoveWordF3D* temp = (RSPUCodeMoveWordF3D*)ucode; + + switch ( temp->type ) + { + case G_MW_MATRIX: + m_rsp->RSP_InsertMatrix(temp->offset, temp->value); + break; + + case G_MW_FOG: + m_rsp->RSP_FogFactor( (short)temp->fm, (short)temp->fo ); + break; + + case G_MW_NUMLIGHT: + m_rsp->RSP_NumLights( (unsigned int)(((ucode->w1 - 0x80000000) >> 5) - 1) ); + break; + + case G_MW_SEGMENT: + m_rsp->moveSegment((temp->offset >> 2) & 0xF, temp->value); + break; + + case G_MW_LIGHTCOL: + if ( (temp->offset & 0x7) == 0 ) + { + m_rsp->RSP_LightColor(temp->offset / 0x20, temp->value); + } + break; + + case G_MW_POINTS: + m_rsp->RSP_ModifyVertex( _SHIFTR( ucode->w0, 8, 16 ) / 40, _SHIFTR( ucode->w0, 0, 8 ) % 40, ucode->w1); + break; + + case G_MW_CLIP: + //gSPClipRatio( w1 ); + break; + + case G_MW_PERSPNORM: + //gSPPerspNormalize( w1 ); + break; + } +} + +//***************************************************************************** +// Non important functions +//***************************************************************************** + +void UCode0::F3D_SPNoOp(MicrocodeArgument* ucode){ + Logger::getSingleton().printMsg("F3D_SPNoOp", M64MSG_VERBOSE); + + //If next command is a no-operation then skip displaylist for some ucodes. + //if( (ucode+1)->words.cmd == 0x00 && gRSP.ucode >= 17 ) + //{ + // m_rsp->RSP_EndDisplayList(); + //} +} + +void UCode0::F3D_Reserved0(MicrocodeArgument* ucode) { + Logger::getSingleton().printMsg("F3D_Reserved0", M64MSG_VERBOSE); +} + +void UCode0::F3D_Reserved1(MicrocodeArgument* ucode){ + Logger::getSingleton().printMsg("F3D_Reserved1", M64MSG_VERBOSE); +} + +void UCode0::F3D_Reserved2(MicrocodeArgument* ucode){ + Logger::getSingleton().printMsg("F3D_Reserved2", M64MSG_VERBOSE); +} + +void UCode0::F3D_Reserved3(MicrocodeArgument* ucode){ + Logger::getSingleton().printMsg("F3D_Reserved3", M64MSG_VERBOSE); +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h new file mode 100755 index 0000000..f802fe7 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode0.h @@ -0,0 +1,168 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_0_H_ +#define UCODE_0_H_ + +//Includes +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; +class DisplayListParser; + +//Definitions +#define F3D_MTX_STACKSIZE 10 + +#define F3D_MTX_MODELVIEW 0x00 +#define F3D_MTX_PROJECTION 0x01 +#define F3D_MTX_MUL 0x00 +#define F3D_MTX_LOAD 0x02 +#define F3D_MTX_NOPUSH 0x00 +#define F3D_MTX_PUSH 0x04 + +#define F3D_TEXTURE_ENABLE 0x00000002 +#define F3D_SHADING_SMOOTH 0x00000200 +#define F3D_CULL_FRONT 0x00001000 +#define F3D_CULL_BACK 0x00002000 +#define F3D_CULL_BOTH 0x00003000 +#define F3D_CLIPPING 0x00000000 + +#define F3D_MV_VIEWPORT 0x80 + +#define F3D_MWO_aLIGHT_1 0x00 +#define F3D_MWO_bLIGHT_1 0x04 +#define F3D_MWO_aLIGHT_2 0x20 +#define F3D_MWO_bLIGHT_2 0x24 +#define F3D_MWO_aLIGHT_3 0x40 +#define F3D_MWO_bLIGHT_3 0x44 +#define F3D_MWO_aLIGHT_4 0x60 +#define F3D_MWO_bLIGHT_4 0x64 +#define F3D_MWO_aLIGHT_5 0x80 +#define F3D_MWO_bLIGHT_5 0x84 +#define F3D_MWO_aLIGHT_6 0xa0 +#define F3D_MWO_bLIGHT_6 0xa4 +#define F3D_MWO_aLIGHT_7 0xc0 +#define F3D_MWO_bLIGHT_7 0xc4 +#define F3D_MWO_aLIGHT_8 0xe0 +#define F3D_MWO_bLIGHT_8 0xe4 + +// FAST3D commands +#define F3D_SPNOOP 0x00 +#define F3D_MTX 0x01 +#define F3D_RESERVED0 0x02 +#define F3D_MOVEMEM 0x03 +#define F3D_VTX 0x04 +#define F3D_RESERVED1 0x05 +#define F3D_DL 0x06 +#define F3D_RESERVED2 0x07 +#define F3D_RESERVED3 0x08 +#define F3D_SPRITE2D_BASE 0x09 + +#define F3D_TRI1 0xBF +#define F3D_CULLDL 0xBE +#define F3D_POPMTX 0xBD +#define F3D_MOVEWORD 0xBC +#define F3D_TEXTURE 0xBB +#define F3D_SETOTHERMODE_H 0xBA +#define F3D_SETOTHERMODE_L 0xB9 +#define F3D_ENDDL 0xB8 +#define F3D_SETGEOMETRYMODE 0xB7 +#define F3D_CLEARGEOMETRYMODE 0xB6 +//#define F3D_LINE3D 0xB5 // Only used in Line3D +#define F3D_QUAD 0xB5 +#define F3D_RDPHALF_1 0xB4 +#define F3D_RDPHALF_2 0xB3 +#define F3D_RDPHALF_CONT 0xB2 +#define F3D_TRI4 0xB1 + +//***************************************************************************** +//! UCode0 (aka F3D - Fast 3D) +//! Microcode used for Super Mario 64!!! +//***************************************************************************** +class UCode0 +{ +public: + + UCode0(); + ~UCode0(); + + static void initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp); + static void initializeGBI(GBI* gbi); + +public: + + // Matrix Functions + static void F3D_Mtx(MicrocodeArgument* ucode); + static void F3D_PopMtx(MicrocodeArgument* ucode); + + //Vertex and indices + static void F3D_Vtx(MicrocodeArgument* ucode); + static void F3D_Tri1(MicrocodeArgument* ucode); + static void F3D_Tri4(MicrocodeArgument* ucode); + static void F3D_Quad(MicrocodeArgument* ucode); + + //Display list + static void F3D_DList(MicrocodeArgument* ucode); + static void F3D_EndDL(MicrocodeArgument* ucode); + static void F3D_CullDL(MicrocodeArgument* ucode); //Unimplemented + + // Texture + static void F3D_Texture(MicrocodeArgument* ucode); + + // Half + static void F3D_RDPHalf_1(MicrocodeArgument* ucode); + static void F3D_RDPHalf_2(MicrocodeArgument* ucode); + static void F3D_RDPHalf_Cont(MicrocodeArgument* ucode); //Unimplmeneted + + // Geometry Mode + static void F3D_SetGeometryMode(MicrocodeArgument* ucode); + static void F3D_ClearGeometryMode(MicrocodeArgument* ucode); + + // Set Other Modes + static void F3D_SetOtherMode_H(MicrocodeArgument* ucode); + static void F3D_SetOtherMode_L(MicrocodeArgument* ucode); + + // Other + static void F3D_MoveMem(MicrocodeArgument* ucode); + static void F3D_MoveWord(MicrocodeArgument* ucode); + static void F3D_Sprite2D_Base(MicrocodeArgument* ucode); //Unimplemented + + //Unimportant + static void F3D_SPNoOp(MicrocodeArgument* ucode); + static void F3D_Reserved0(MicrocodeArgument* ucode); + static void F3D_Reserved1(MicrocodeArgument* ucode); + static void F3D_Reserved2(MicrocodeArgument* ucode); + static void F3D_Reserved3(MicrocodeArgument* ucode); + +private: + + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer to Memory Manager + static DisplayListParser* m_displayListParser; //!< Pointer to Display List Parser + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp new file mode 100755 index 0000000..303ebd0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp @@ -0,0 +1,238 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode1.h" +#include "UCode0.h" + +//Forward declaration +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" + +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode1::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode1::m_rdp = 0; //!< Pointer to Reality Drawing Processor +Memory* UCode1::m_memory = 0; +GBI* UCode1::m_gbi = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode1::UCode1() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode1::~UCode1() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode1::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory) +{ + m_gbi = gbi; + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode1::initializeGBI() +{ + // Set GeometryMode flags + GBI_InitFlags( F3DEX ); + + // GBI Command Command Value //Target Command Function + GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, m_gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_MTX, F3D_MTX, m_gbi->m_cmds, UCode0::F3D_Mtx ); + GBI_SetGBI( GBI::G_RESERVED0, F3D_RESERVED0, m_gbi->m_cmds, UCode0::F3D_Reserved0 ); + GBI_SetGBI( GBI::G_MOVEMEM, F3D_MOVEMEM, m_gbi->m_cmds, UCode0::F3D_MoveMem ); + GBI_SetGBI( GBI::G_VTX, F3D_VTX, m_gbi->m_cmds, F3DEX_Vtx ); + GBI_SetGBI( GBI::G_RESERVED1, F3D_RESERVED1, m_gbi->m_cmds, UCode0::F3D_Reserved1 ); + GBI_SetGBI( GBI::G_DL, F3D_DL, m_gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_RESERVED2, F3D_RESERVED2, m_gbi->m_cmds, UCode0::F3D_Reserved2 ); + GBI_SetGBI( GBI::G_RESERVED3, F3D_RESERVED3, m_gbi->m_cmds, UCode0::F3D_Reserved3 ); + GBI_SetGBI( GBI::G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, m_gbi->m_cmds, UCode0::F3D_Sprite2D_Base ); + GBI_SetGBI( GBI::G_TRI1, F3D_TRI1, m_gbi->m_cmds, F3DEX_Tri1 ); + GBI_SetGBI( GBI::G_CULLDL, F3D_CULLDL, m_gbi->m_cmds, F3DEX_CullDL ); + GBI_SetGBI( GBI::G_POPMTX, F3D_POPMTX, m_gbi->m_cmds, UCode0::F3D_PopMtx ); + GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, m_gbi->m_cmds, UCode0::F3D_MoveWord ); + GBI_SetGBI( GBI::G_TEXTURE, F3D_TEXTURE, m_gbi->m_cmds, UCode0::F3D_Texture ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, m_gbi->m_cmds, UCode0::F3D_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, m_gbi->m_cmds, UCode0::F3D_SetOtherMode_L ); + GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, m_gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, m_gbi->m_cmds, UCode0::F3D_SetGeometryMode ); + GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE, m_gbi->m_cmds, UCode0::F3D_ClearGeometryMode ); + GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, m_gbi->m_cmds, F3DEX_Quad ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, m_gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, m_gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_MODIFYVTX, F3DEX_MODIFYVTX, m_gbi->m_cmds, F3DEX_ModifyVtx ); + GBI_SetGBI( GBI::G_TRI2, F3DEX_TRI2, m_gbi->m_cmds, F3DEX_Tri2 ); + GBI_SetGBI( GBI::G_BRANCH_Z, F3DEX_BRANCH_Z, m_gbi->m_cmds, F3DEX_Branch_Z ); + GBI_SetGBI( GBI::G_LOAD_UCODE, F3DEX_LOAD_UCODE, m_gbi->m_cmds, F3DEX_Load_uCode ); +} + +//----------------------------------------------------------------------------- +//! Load UCode +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Load_uCode(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_Load_uCode - experimental", M64MSG_WARNING); + RSPUCodeLoadUCode* temp = (RSPUCodeLoadUCode*)ucode; + + //unsigned int ucodeDataStart1 = m_memory->getRDRAMAddress( (*(unsigned int*)( m_memory->getRDRAM(pc-12)) ); + unsigned int ucodeDataStart2 = m_rdp->getHalf1(); + + //if ( ucodeDataStart1 != ucodeDataStart2 ) + //{ + // Logger::getSingleton().printMsg("Warning - UCode Data Start differs", M64MSG_INFO); + //} + + //Select UCode + m_gbi->selectUCode( temp->ucodeStart, //UCodeStart + ucodeDataStart2, //UCodeDataStart + temp->ucodeSize+1, //UCodeSize + 8); //UCodeDataSize //Always 8 ??? +} + +//----------------------------------------------------------------------------- +//! Add Vertices +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Vtx(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_Vtx", M64MSG_VERBOSE); + RSPUCodeAddVertices1* temp = (RSPUCodeAddVertices1*)ucode; + + //Add Vertices + m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->firstVertex); +} + +//----------------------------------------------------------------------------- +//! Modify Vertex +//----------------------------------------------------------------------------- +void UCode1::F3DEX_ModifyVtx(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_ModifyVtx", M64MSG_VERBOSE); + RSPUCodeModifyVertex* temp = (RSPUCodeModifyVertex*)ucode; + + switch ( temp->modifyType ) + { + case G_MWO_POINT_RGBA: + m_rsp->RSP_SetVertexColor( temp->vertexIndex, + temp->r/255.0f, + temp->g/255.0f, + temp->b/255.0f, + temp->a/255.0f ); + break; + case G_MWO_POINT_ST: + m_rsp->RSP_SetVertexTexCoord(temp->vertexIndex, + temp->t / 32.0f, + temp->s / 32.0f ); + break; + case G_MWO_POINT_XYSCREEN: + break; + case G_MWO_POINT_ZSCREEN: + break; + }; +} + +//----------------------------------------------------------------------------- +//! Add 1 Triangle +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Tri1(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_Tri1", M64MSG_VERBOSE); + RSPUCodeAddOneTriangleF3DEX* temp = (RSPUCodeAddOneTriangleF3DEX*)ucode; + + //Add one triangle + m_rsp->RSP_1Triangle(temp->index0, temp->index1, temp->index2); +} + +//----------------------------------------------------------------------------- +//! Add 2 Triangles +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Tri2(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_Tri2", M64MSG_VERBOSE); + RSPUCodeAddTwoTrianglesF3DEX* temp = (RSPUCodeAddTwoTrianglesF3DEX*)ucode; + + //Add two triangles + m_rsp->RSP_2Triangles( temp->v0, temp->v1, temp->v2, 0, + temp->v3, temp->v4, temp->v5, 0); +} + +//----------------------------------------------------------------------------- +//! Add 1 Quadrangle +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Quad( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX_Quad", M64MSG_VERBOSE); + RSPUCodeAddOneQuadF3DEX* temp = (RSPUCodeAddOneQuadF3DEX*)ucode; + + //Add one Quad + m_rsp->RSP_1Quadrangle(temp->index0, temp->index1, temp->index2, temp->index3); +} + +//----------------------------------------------------------------------------- +//! Cull Display List +//----------------------------------------------------------------------------- +void UCode1::F3DEX_CullDL(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) + { + Logger::getSingleton().printMsg("F3DEX_CullDL - Unimplemented", M64MSG_WARNING); + warned = true; + } + RSPUCodeCullDisplayList* temp = (RSPUCodeCullDisplayList*)ucode; + + //Cull display list? + m_rsp->RSP_CullDisplayList( temp->vertexIndex, temp->numVerticies ); +} + +//----------------------------------------------------------------------------- +//! Branch Z +//----------------------------------------------------------------------------- +void UCode1::F3DEX_Branch_Z(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX_Branch_Z", M64MSG_VERBOSE); + RSPUCodeBranchZF3DEX* temp = (RSPUCodeBranchZF3DEX*)ucode; + + //Branch Display List? + m_rsp->RSP_BranchLessZ(m_rdp->getHalf1(), temp->vertex, (float)(int)temp->zvalue ); +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h new file mode 100755 index 0000000..2b4087f --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode1.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_1_H_ +#define UCODE_1_H_ + +//Includes +#include "UCodeDefs.h" + +#define F3DEX_MTX_STACKSIZE 18 + +#define F3DEX_MTX_MODELVIEW 0x00 +#define F3DEX_MTX_PROJECTION 0x01 +#define F3DEX_MTX_MUL 0x00 +#define F3DEX_MTX_LOAD 0x02 +#define F3DEX_MTX_NOPUSH 0x00 +#define F3DEX_MTX_PUSH 0x04 + +#define F3DEX_TEXTURE_ENABLE 0x00000002 +#define F3DEX_SHADING_SMOOTH 0x00000200 +#define F3DEX_CULL_FRONT 0x00001000 +#define F3DEX_CULL_BACK 0x00002000 +#define F3DEX_CULL_BOTH 0x00003000 +#define F3DEX_CLIPPING 0x00800000 + +#define F3DEX_MV_VIEWPORT 0x80 + +#define F3DEX_MWO_aLIGHT_1 0x00 +#define F3DEX_MWO_bLIGHT_1 0x04 +#define F3DEX_MWO_aLIGHT_2 0x20 +#define F3DEX_MWO_bLIGHT_2 0x24 +#define F3DEX_MWO_aLIGHT_3 0x40 +#define F3DEX_MWO_bLIGHT_3 0x44 +#define F3DEX_MWO_aLIGHT_4 0x60 +#define F3DEX_MWO_bLIGHT_4 0x64 +#define F3DEX_MWO_aLIGHT_5 0x80 +#define F3DEX_MWO_bLIGHT_5 0x84 +#define F3DEX_MWO_aLIGHT_6 0xa0 +#define F3DEX_MWO_bLIGHT_6 0xa4 +#define F3DEX_MWO_aLIGHT_7 0xc0 +#define F3DEX_MWO_bLIGHT_7 0xc4 +#define F3DEX_MWO_aLIGHT_8 0xe0 +#define F3DEX_MWO_bLIGHT_8 0xe4 + +// F3DEX commands +#define F3DEX_MODIFYVTX 0xB2 +#define F3DEX_TRI2 0xB1 +#define F3DEX_BRANCH_Z 0xB0 +#define F3DEX_LOAD_UCODE 0xAF // 0xCF + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; + +//***************************************************************************** +//! UCode1 (aka F3DEX - Fast 3D EX) +//! Microcode used for most games +//***************************************************************************** +class UCode1 +{ +public: + + UCode1(); + ~UCode1(); + + static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory); + static void initializeGBI(); + + static void F3DEX_Load_uCode(MicrocodeArgument* ucode); + static void F3DEX_Vtx(MicrocodeArgument* ucode); + static void F3DEX_ModifyVtx(MicrocodeArgument* ucode); + static void F3DEX_Tri1(MicrocodeArgument* ucode); + static void F3DEX_Tri2(MicrocodeArgument* ucode); + static void F3DEX_Quad(MicrocodeArgument* ucode); + static void F3DEX_CullDL(MicrocodeArgument* ucode); + static void F3DEX_Branch_Z(MicrocodeArgument* ucode); + +private: + + static GBI* m_gbi; //!< Graphics Binary Interface + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer accessing memory like RDRAM and Texture Memory + +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp new file mode 100755 index 0000000..50776d6 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp @@ -0,0 +1,219 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode10.h" +#include "UCode5.h" + +//Forward declaration +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "DisplayListParser.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" + + +#define CONKER_BFD_ADD_VERTICES 1 /*F3DEX2_VTX ?*/ + +#define RSP_MOVE_WORD_MATRIX 0x00 // NOTE: also used by movemem +#define RSP_MOVE_WORD_NUMLIGHT 0x02 +#define RSP_MOVE_WORD_CLIP 0x04 +#define RSP_MOVE_WORD_SEGMENT 0x06 +#define RSP_MOVE_WORD_FOG 0x08 +#define RSP_MOVE_WORD_LIGHTCOL 0x0a +#define RSP_MOVE_WORD_POINTS 0x0c +#define RSP_MOVE_WORD_PERSPNORM 0x0e + +#define RSP_GBI2_MV_MEM__VIEWPORT 8 +#define RSP_GBI2_MV_MEM__LIGHT 10 +#define RSP_GBI2_MV_MEM__POINT 12 +#define RSP_GBI2_MV_MEM__MATRIX 14 /* NOTE: this is in moveword table */ + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode10::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode10::m_rdp = 0; //!< Pointer to Reality Drawing Processor +Memory* UCode10::m_memory = 0; +GBI* UCode10::m_gbi = 0; +DisplayListParser* UCode10::m_displayListParser = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode10::UCode10() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode10::~UCode10() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode10::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp) +{ + m_gbi = gbi; + m_rsp = rsp; + m_rdp = rdp; + m_memory = mem; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode10::initializeGBI() +{ + //Load F3DEX + UCode5::initializeGBI(); + + GBI_SetGBI( GBI::G_VTX, CONKER_BFD_ADD_VERTICES, m_gbi->m_cmds, ConkerBFD_Vertex ); + GBI_SetGBI( GBI::G_TRI4, 0x10, m_gbi->m_cmds, ConkerBFD_Vertex ); + GBI_SetGBI( GBI::G_TRI4, 0x11, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x12, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x13, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x14, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x15, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x16, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x17, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x18, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x19, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1a, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1b, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1c, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1d, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1e, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_TRI4, 0x1f, m_gbi->m_cmds, ConkerBFD_Add4Triangles ); + GBI_SetGBI( GBI::G_MOVEWORD, F3DEX2_MOVEWORD, m_gbi->m_cmds, ConkerBFD_MoveWord ); + GBI_SetGBI( GBI::G_MOVEMEM, F3DEX2_MOVEMEM, m_gbi->m_cmds, ConkerBFD_MoveMem ); +} + +//----------------------------------------------------------------------------- +//! Conker Bad Fur Day Vertex +//----------------------------------------------------------------------------- +void UCode10::ConkerBFD_Vertex(MicrocodeArgument* ucode) +{ + unsigned int vertexEnd = (((ucode->w0) )&0xFFF)/2; + unsigned int numVertices = (((ucode->w0)>>12)&0xFFF); + + //Add Vertices + m_rsp->getVertexMgr()->addConkerVertices( ucode->w1, numVertices, vertexEnd - numVertices ); + // m_rsp->RSP_Vertex( ucode->w1, numVertices, vertexEnd - numVertices); +} + +//----------------------------------------------------------------------------- +//! Conker Bad Fur Day Add Four Triangles +//----------------------------------------------------------------------------- +void UCode10::ConkerBFD_Add4Triangles(MicrocodeArgument* ucode) +{ + unsigned int w0 = ucode->w0; + unsigned int w1 = ucode->w1; + + unsigned int idx[12]; + idx[0] = (w1 )&0x1F; //Tri1 + idx[1] = (w1>> 5)&0x1F; + idx[2] = (w1>>10)&0x1F; + idx[3] = (w1>>15)&0x1F; //Tri2 + idx[4] = (w1>>20)&0x1F; + idx[5] = (w1>>25)&0x1F; + idx[6] = (w0 )&0x1F; //Tri3 + idx[7] = (w0>> 5)&0x1F; + idx[8] = (w0>>10)&0x1F; + idx[9] = (((w0>>15)&0x7)<<2)|(w1>>30); //Tri4 + idx[10] = (w0>>18)&0x1F; + idx[11] = (w0>>23)&0x1F; + + //Add Triagles + m_rsp->RSP_1Triangle(idx[0], idx[1], idx[2]); + m_rsp->RSP_1Triangle(idx[3], idx[4], idx[5]); + m_rsp->RSP_1Triangle(idx[6], idx[7], idx[8]); + m_rsp->RSP_1Triangle(idx[9], idx[10], idx[11]); + + unsigned int* RDRAMu32 = m_memory->getRDRAMint32(); + + //Get next command + MicrocodeArgument* ucodeNext = (MicrocodeArgument*)&RDRAMu32[(m_displayListParser->getPC()>>2)]; + + //Conker Bad Fur Day Render Fix (because conker has multiple Tri4) + ucode->cmd = GBI::G_TRI4; + if ( ucodeNext->cmd >= 0x10 && ucodeNext->cmd <= 0x1f ) + { + ucodeNext->cmd = GBI::G_TRI4; + } +} + +//----------------------------------------------------------------------------- +//! Conker Bad Fur Day Move Word +//----------------------------------------------------------------------------- +void UCode10::ConkerBFD_MoveWord(MicrocodeArgument* ucode) +{ + unsigned int dwType = ((ucode->w0) >> 16) & 0xFF; + + if( dwType == RSP_MOVE_WORD_NUMLIGHT ) + { + m_rsp->RSP_NumLights( ((ucode->w1)/48) ); + } + else + { + UCode5::F3DEX2_MoveWord(ucode); + } +} + +//----------------------------------------------------------------------------- +//! Conker Bad Fur Day Move Memory +//----------------------------------------------------------------------------- +void UCode10::ConkerBFD_MoveMem(MicrocodeArgument* ucode) +{ + unsigned int dwType = ((ucode->w0) ) & 0xFE; + unsigned int dwAddr = ucode->w1; //RSPSegmentAddr((gfx->words.w1)); + + switch ( dwType ) + { + case RSP_GBI2_MV_MEM__MATRIX: + m_rsp->getVertexMgr()->setConkerAddress(dwAddr); + break; + + case RSP_GBI2_MV_MEM__LIGHT: + { + unsigned int dwOffset2 = ((ucode->w0) >> 5) & 0x3FFF; + if( dwOffset2 >= 0x30 ) + { + m_rsp->RSP_Light(((dwOffset2 - 0x30)/0x30), dwAddr); + } + else + { + //FIX ME + } + } + break; + + default: + UCode5::F3DEX2_MoveMem(ucode); + break; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h new file mode 100755 index 0000000..dddd61d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode10.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_10_H_ +#define UCODE_10_H_ + +//Includes +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; +class DisplayListParser; + +//***************************************************************************** +//! UCode10 +//! Microcode used for Conker's Bad Fur Day +//***************************************************************************** +class UCode10 +{ +public: + + UCode10(); + ~UCode10(); + + static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp); + static void initializeGBI(); + + static void ConkerBFD_Vertex(MicrocodeArgument* ucode); + static void ConkerBFD_Add4Triangles(MicrocodeArgument* ucode); + static void ConkerBFD_MoveWord(MicrocodeArgument* ucode); + static void ConkerBFD_MoveMem(MicrocodeArgument* ucode); + +private: + + static GBI* m_gbi; //!< Graphics Binary Interface + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer accessing memory like RDRAM and Texture Memory + static DisplayListParser* m_displayListParser; + + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp new file mode 100755 index 0000000..21fe1e9 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp @@ -0,0 +1,110 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode2.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" +#include "Memory.h" +#include "DisplayListParser.h" + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +GBI* UCode2::m_gbi = 0; //!< Pointer to Graphics Binary Interface +RSP* UCode2::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode2::m_rdp = 0; //!< Pointer to Reality Drawing Processor +Memory* UCode2::m_memory = 0; +DisplayListParser* UCode2::m_displayListParser = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode2::UCode2() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode2::~UCode2() +{ +} + +//----------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------- +void UCode2::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp) +{ + m_rsp = rsp; + m_rdp = rdp; + m_gbi = gbi; + m_memory = mem; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//* Initialize GBI +//! Assigns functions to the GBI +//----------------------------------------------------------------------------- +void UCode2::initializeGBI() +{ + UCode0::initializeGBI(m_gbi); + GBI_SetGBI(GBI::G_RDPHALF_1, F3D_RDPHALF_1, m_gbi->m_cmds, renderSky); +} + +//----------------------------------------------------------------------------- +//* RDP Half 1 With Sky Rendering +//! Render Sky +//! @todo Set Half 1 also? +//! @todo Use extracted color +//! @todo set x0 and x1 +//----------------------------------------------------------------------------- +void UCode2::renderSky(MicrocodeArgument* ucode) +{ + //Check for error + if ( (ucode->w1)>>24 != 0xCE ) + { + return; + } + + unsigned int w2 = m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + m_displayListParser->getNextWord(); + + //Extract Vertex Coordinats + unsigned int x0 = 0; //TODO Use VI pos or Viewport pos or Scissor pos ? + unsigned int y0 = (unsigned int)int(w2&0xFFFF)/4; + unsigned int x1 = 320; //TODO Use VI Height or Viewport Height or Scissor Height ? + unsigned int y1 = (unsigned int)int(w2>>16)/4; + + m_rdp->RDP_TexRect(x0, y0, x1, y1, 0, 0, 0, 1024, 1024); +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h new file mode 100755 index 0000000..9b87d5e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode2.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_2_H_ +#define UCODE_2_H_ + +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; +class DisplayListParser; + +//***************************************************************************** +//! UCode2 +//! Microcode used for Golden Eye +//! Note: This ucode is very similar to F3D, The diffrence is that this +//! UCode has a special way to render sky. That sky rendering is +//! also used in perfect dark. +//***************************************************************************** +class UCode2 +{ +public: + + //Constructor / Destructor + UCode2(); + ~UCode2(); + + static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp); + static void initializeGBI(); + + static void renderSky(MicrocodeArgument* ucode); + +private: + + static GBI* m_gbi; //!< Pointer to Graphics Binary Interface + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer to Memory Manager + static DisplayListParser* m_displayListParser; //!< Pointer to Display-List Parser + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp new file mode 100755 index 0000000..e69de29 diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode3.h new file mode 100755 index 0000000..e69de29 diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp new file mode 100755 index 0000000..fe81a9f --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp @@ -0,0 +1,126 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode4.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" + +#define F3DWRUS_TRI2 0xB1 + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +GBI* UCode4::m_gbi = 0; +RSP* UCode4::m_rsp = 0; //!< Pointer to Reality Signal Processor + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode4::UCode4() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode4::~UCode4() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode4::initialize(GBI* gbi, RSP* rsp) +{ + m_gbi = gbi; + m_rsp = rsp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode4::initializeGBI() +{ + UCode0::initializeGBI(m_gbi); + + //Init special Wave Race functions + GBI_SetGBI( GBI::G_VTX, F3D_VTX, m_gbi->m_cmds, WaveRace64_Vertex ); + GBI_SetGBI( GBI::G_TRI1, F3D_TRI1, m_gbi->m_cmds, WaveRace64_Tri1 ); + GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, m_gbi->m_cmds, WaveRace64_Quad ); + GBI_SetGBI( GBI::G_TRI2, F3DWRUS_TRI2, m_gbi->m_cmds, WaveRace64_Tri2 ); +} + +//----------------------------------------------------------------------------- +//! Add Vertices +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode4::WaveRace64_Vertex(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("WaveRace64_Vertex", M64MSG_VERBOSE); + RSPUCodeAddVerticesWaveRace64* temp = (RSPUCodeAddVerticesWaveRace64*)ucode; + + //Add Vertices + m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->firstVertexIndex/5); +} + +//----------------------------------------------------------------------------- +//! Add one Triangle +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode4::WaveRace64_Tri1(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("WaveRace64_Tri1", M64MSG_VERBOSE); + RSPUCodeAddOneTriangleF3D* temp = (RSPUCodeAddOneTriangleF3D*)ucode; + + //Add triangle + m_rsp->RSP_1Triangle(temp->index0 / 5, temp->index1 / 5, temp->index2 / 5 /*,temp->flag,*/ ); +} + +//----------------------------------------------------------------------------- +//! Add 2 Triangles +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode4::WaveRace64_Tri2(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("WaveRace64_Tri2", M64MSG_VERBOSE); + RSPUCodeAddTwoTrianglesWaveRace64* temp = (RSPUCodeAddTwoTrianglesWaveRace64*)ucode; + + //Add Two triangles + m_rsp->RSP_2Triangles( temp->v0 / 5, temp->v1 / 5, temp->v2 / 5, 0, + temp->v3 / 5, temp->v4 / 5, temp->v5 / 5, 0); +} + +//----------------------------------------------------------------------------- +//! Add Quad +//! @param ucode instruction from displaylist with input data +//----------------------------------------------------------------------------- +void UCode4::WaveRace64_Quad(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("WaveRace64_Quad", M64MSG_VERBOSE); + RSPUCodeAddOneQuadF3D* temp = (RSPUCodeAddOneQuadF3D*)ucode; + + //Add Quad + m_rsp->RSP_1Quadrangle(temp->index0/5, temp->index1/5, temp->index2/5, temp->index3/5); +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h new file mode 100755 index 0000000..4c9eb6e --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode4.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_4_H_ +#define UCODE_4_H_ + +//Includes +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; + +//***************************************************************************** +//! UCode4 +//! Microcode used for Wave Race 64 +//***************************************************************************** +class UCode4 +{ +public: + + UCode4(); + ~UCode4(); + + static void initialize(GBI* gbi, RSP* rsp); + static void initializeGBI(); + + static void WaveRace64_Vertex(MicrocodeArgument* ucode); + static void WaveRace64_Tri1(MicrocodeArgument* ucode); + static void WaveRace64_Tri2(MicrocodeArgument* ucode); + static void WaveRace64_Quad(MicrocodeArgument* ucode); + +private: + + static GBI* m_gbi; + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + +}; + + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp new file mode 100755 index 0000000..01c0b5d --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp @@ -0,0 +1,515 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode5.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" +#include "DisplayListParser.h" + + +#define F3DEX2_MTX_STACKSIZE 18 + +#define F3DEX2_MTX_MODELVIEW 0x00 +#define F3DEX2_MTX_PROJECTION 0x04 +#define F3DEX2_MTX_MUL 0x00 +#define F3DEX2_MTX_LOAD 0x02 +#define F3DEX2_MTX_NOPUSH 0x00 +#define F3DEX2_MTX_PUSH 0x01 + +#define F3DEX2_TEXTURE_ENABLE 0x00000000 +#define F3DEX2_SHADING_SMOOTH 0x00200000 +#define F3DEX2_CULL_FRONT 0x00000200 +#define F3DEX2_CULL_BACK 0x00000400 +#define F3DEX2_CULL_BOTH 0x00000600 +#define F3DEX2_CLIPPING 0x00800000 + +#define F3DEX2_MV_VIEWPORT 8 + +#define F3DEX2_MWO_aLIGHT_1 0x00 +#define F3DEX2_MWO_bLIGHT_1 0x04 +#define F3DEX2_MWO_aLIGHT_2 0x18 +#define F3DEX2_MWO_bLIGHT_2 0x1c +#define F3DEX2_MWO_aLIGHT_3 0x30 +#define F3DEX2_MWO_bLIGHT_3 0x34 +#define F3DEX2_MWO_aLIGHT_4 0x48 +#define F3DEX2_MWO_bLIGHT_4 0x4c +#define F3DEX2_MWO_aLIGHT_5 0x60 +#define F3DEX2_MWO_bLIGHT_5 0x64 +#define F3DEX2_MWO_aLIGHT_6 0x78 +#define F3DEX2_MWO_bLIGHT_6 0x7c +#define F3DEX2_MWO_aLIGHT_7 0x90 +#define F3DEX2_MWO_bLIGHT_7 0x94 +#define F3DEX2_MWO_aLIGHT_8 0xa8 +#define F3DEX2_MWO_bLIGHT_8 0xac + + +#define F3DEX2_RDPHALF_2 0xF1 +#define F3DEX2_SETOTHERMODE_H 0xE3 +#define F3DEX2_SETOTHERMODE_L 0xE2 +#define F3DEX2_RDPHALF_1 0xE1 +#define F3DEX2_SPNOOP 0xE0 +#define F3DEX2_ENDDL 0xDF +#define F3DEX2_DL 0xDE +#define F3DEX2_LOAD_UCODE 0xDD +#define F3DEX2_MTX 0xDA +#define F3DEX2_GEOMETRYMODE 0xD9 +#define F3DEX2_POPMTX 0xD8 +#define F3DEX2_TEXTURE 0xD7 +#define F3DEX2_DMA_IO 0xD6 +#define F3DEX2_SPECIAL_1 0xD5 +#define F3DEX2_SPECIAL_2 0xD4 +#define F3DEX2_SPECIAL_3 0xD3 + +#define F3DEX2_VTX 0x01 +#define F3DEX2_MODIFYVTX 0x02 +#define F3DEX2_CULLDL 0x03 +#define F3DEX2_BRANCH_Z 0x04 +#define F3DEX2_TRI1 0x05 +#define F3DEX2_TRI2 0x06 +#define F3DEX2_QUAD 0x07 +#define F3DEX2_LINE3D 0x08 + + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode5::m_rsp = 0; //!< Pointer to Reality Signal Processor +RDP* UCode5::m_rdp = 0; //!< Pointer to Reality Drawing Processor +Memory* UCode5::m_memory = 0; +GBI* UCode5::m_gbi = 0; +DisplayListParser* UCode5::m_displayListParser = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode5::UCode5() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode5::~UCode5() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode5::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp) +{ + m_gbi = gbi; + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode5::initializeGBI() +{ + //Set flags + GBI_InitFlags( F3DEX2 ); + + + // GBI Command Command Value Command Function + GBI_SetGBI( GBI::G_RDPHALF_2, F3DEX2_RDPHALF_2, m_gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3DEX2_SETOTHERMODE_H, m_gbi->m_cmds, F3DEX2_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3DEX2_SETOTHERMODE_L, m_gbi->m_cmds, F3DEX2_SetOtherMode_L ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3DEX2_RDPHALF_1, m_gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_SPNOOP, F3DEX2_SPNOOP, m_gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_ENDDL, F3DEX2_ENDDL, m_gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_DL, F3DEX2_DL, m_gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_LOAD_UCODE, F3DEX2_LOAD_UCODE, m_gbi->m_cmds, UCode1::F3DEX_Load_uCode ); + GBI_SetGBI( GBI::G_MOVEMEM, F3DEX2_MOVEMEM, m_gbi->m_cmds, F3DEX2_MoveMem ); + GBI_SetGBI( GBI::G_MOVEWORD, F3DEX2_MOVEWORD, m_gbi->m_cmds, F3DEX2_MoveWord ); + GBI_SetGBI( GBI::G_MTX, F3DEX2_MTX, m_gbi->m_cmds, F3DEX2_Mtx ); + GBI_SetGBI( GBI::G_GEOMETRYMODE, F3DEX2_GEOMETRYMODE, m_gbi->m_cmds, F3DEX2_GeometryMode ); + GBI_SetGBI( GBI::G_POPMTX, F3DEX2_POPMTX, m_gbi->m_cmds, F3DEX2_PopMtx ); + GBI_SetGBI( GBI::G_TEXTURE, F3DEX2_TEXTURE, m_gbi->m_cmds, F3DEX2_Texture ); + GBI_SetGBI( GBI::G_DMA_IO, F3DEX2_DMA_IO, m_gbi->m_cmds, F3DEX2_DMAIO ); + GBI_SetGBI( GBI::G_SPECIAL_1, F3DEX2_SPECIAL_1, m_gbi->m_cmds, F3DEX2_Special_1 ); + GBI_SetGBI( GBI::G_SPECIAL_2, F3DEX2_SPECIAL_2, m_gbi->m_cmds, F3DEX2_Special_2 ); + GBI_SetGBI( GBI::G_SPECIAL_3, F3DEX2_SPECIAL_3, m_gbi->m_cmds, F3DEX2_Special_3 ); + GBI_SetGBI( GBI::G_VTX, F3DEX2_VTX, m_gbi->m_cmds, F3DEX2_Vtx ); + GBI_SetGBI( GBI::G_MODIFYVTX, F3DEX2_MODIFYVTX, m_gbi->m_cmds, UCode1::F3DEX_ModifyVtx ); + GBI_SetGBI( GBI::G_CULLDL, F3DEX2_CULLDL, m_gbi->m_cmds, UCode1::F3DEX_CullDL ); + GBI_SetGBI( GBI::G_BRANCH_Z, F3DEX2_BRANCH_Z, m_gbi->m_cmds, UCode1::F3DEX_Branch_Z ); + GBI_SetGBI( GBI::G_TRI1, F3DEX2_TRI1, m_gbi->m_cmds, F3DEX2_Tri1 ); + GBI_SetGBI( GBI::G_TRI2, F3DEX2_TRI2, m_gbi->m_cmds, UCode1::F3DEX_Tri2 ); + GBI_SetGBI( GBI::G_QUAD, F3DEX2_QUAD, m_gbi->m_cmds, F3DEX2_Quad ); + GBI_SetGBI( GBI::G_LINE3D, F3DEX2_LINE3D, m_gbi->m_cmds, F3DEX2_Line3D ); +} + +//***************************************************************************** +// Matrices +//***************************************************************************** + +//----------------------------------------------------------------------------- +//! Add Matrix +//! @todo Bomberman2 hack +//! @todo South park rally hack +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Mtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Mtx", M64MSG_VERBOSE); + RSPUCodeAddMatrixF3DEX2* temp = (RSPUCodeAddMatrixF3DEX2*)ucode; + + //TODO Bomberman2 hack + if( temp->param == 0 && temp->lenght == 0 ) + { + //Bomberman2TextRect(ucode); + Logger::getSingleton().printMsg("F3DEX2_Mtx - Bomberman2TextRect - Unimplemented", M64MSG_WARNING); + return; + } + + //Add Matrix + m_rsp->RSP_Matrix( temp->segmentAddress, temp->projection, !temp->nopush, temp->load ); + + //For Conker Bad Fur Day + m_rsp->getVertexMgr()->setConkerAddress(0); + + //TODO South park rally hack +} + +//----------------------------------------------------------------------------- +//! Pop Matrix +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_PopMtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_PopMtx", M64MSG_VERBOSE); + + m_rsp->RSP_PopMatrixN( ucode->w1 >> 6 ); +} + +//***************************************************************************** +//Textures +//***************************************************************************** + +//----------------------------------------------------------------------------- +//! Set Texture +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Texture( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Texture", M64MSG_VERBOSE); + + float scaleS = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 ); + float scaleT = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 ); + int level = _SHIFTR( ucode->w0, 11, 3 ); + int tile = _SHIFTR( ucode->w0, 8, 3 ); + int on = _SHIFTR( ucode->w0, 1, 7 ); + + m_rsp->RSP_Texture(scaleS, scaleT, level, tile, on); +} + +//***************************************************************************** +// Vertices and indices +//***************************************************************************** + +//----------------------------------------------------------------------------- +// Vertices +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Vtx( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Vtx", M64MSG_VERBOSE); + RSPUCodeAddVerticesF3DEX2* temp = (RSPUCodeAddVerticesF3DEX2*)ucode; + + //Add Vertices + m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices, temp->vertexEnd - temp->numVertices); +} + +//----------------------------------------------------------------------------- +// Add 1 Triangle +//! @todo Add triangle flag +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Tri1( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Tri1", M64MSG_VERBOSE); + RSPUCodeAddOneTriangleF3DEX2* temp = (RSPUCodeAddOneTriangleF3DEX2*)ucode; + + //Add one triangle + m_rsp->RSP_1Triangle( temp->index0 / 2, temp->index1 / 2, temp->index2 / 2); //TODO flag +} + +//----------------------------------------------------------------------------- +// Add 1 Quad +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Quad( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Quad", M64MSG_VERBOSE); + RSPUCodeAddOneQuadF3DEX2* temp = (RSPUCodeAddOneQuadF3DEX2*)ucode; + + //Add two triangles + m_rsp->RSP_2Triangles( temp->v0 / 2, temp->v1 / 2, temp->v2 / 2, 0, + temp->v3 / 2, temp->v4 / 2, temp->v5 / 2, 0 ); +} + +//----------------------------------------------------------------------------- +// Render Line 3D +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_Line3D( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_Line3D - Unimplemented", M64MSG_WARNING); +} + + +//***************************************************************************** +// Misc +//***************************************************************************** + +//----------------------------------------------------------------------------- +// MoveMem +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_MoveMem( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_MoveMem", M64MSG_VERBOSE); + + switch (_SHIFTR( ucode->w0, 0, 8 )) + { + case F3DEX2_MV_VIEWPORT: + m_rsp->moveMemViewport( ucode->w1 ); + break; + case G_MV_MATRIX: + m_rsp->RSP_ForceMatrix( ucode->w1 ); + m_displayListParser->increasePC(8); // force matrix takes two commands + break; + case G_MV_LIGHT: + /* + unsigned int dwOffset2 = ((ucode->w0) >> 5) & 0x3FFF; + + switch (dwOffset2) + { + case 0x00: + { + s8 * pcBase = g_pRDRAMs8 + addr; + LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATX %f %f %f", + (float)pcBase[8 ^ 0x3], + (float)pcBase[9 ^ 0x3], + (float)pcBase[10 ^ 0x3]); + + } + break; + case 0x18: + { + s8 * pcBase = g_pRDRAMs8 + addr; + LOG_UCODE(" RSP_GBI1_MV_MEM_LOOKATY %f %f %f", + (float)pcBase[8 ^ 0x3], + (float)pcBase[9 ^ 0x3], + (float)pcBase[10 ^ 0x3]); + } + break; + default: //0x30/48/60 + { + uint32 dwLight = (dwOffset2 - 0x30)/0x18; + LOG_UCODE(" Light %d:", dwLight); + RSP_MoveMemLight(dwLight, addr); + } + break; + } + break; + */ + unsigned int offset = _SHIFTR( ucode->w0, 8, 8 ) << 3; + + if (offset >= 48) + { + m_rsp->RSP_Light( ((offset - 24) / 24) - 1, ucode->w1); + } + else + { + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("F3DEX2_MoveMem - Light - Unimplemented", M64MSG_WARNING); + warned = true; + } + } + + break; + } +} + +//----------------------------------------------------------------------------- +// Move Word +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_MoveWord(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("F3DEX2_MoveWord", M64MSG_VERBOSE); + RSPUCodeMoveWordF3DEX2* temp = (RSPUCodeMoveWordF3DEX2*)ucode; + + switch ( temp->type ) + { + case G_MW_FORCEMTX: + Logger::getSingleton().printMsg("ForceMatrix - Unimplemented", M64MSG_WARNING); // Handled in movemem??? + break; + + case G_MW_MATRIX: + m_rsp->RSP_InsertMatrix( _SHIFTR( ucode->w0, 0, 16 ), ucode->w1 ); + break; + + case G_MW_NUMLIGHT: + m_rsp->RSP_NumLights(temp->value / 24); + break; + + case G_MW_SEGMENT: + m_rsp->moveSegment(temp->offset>>2, temp->value & 0x00FFFFFF); + break; + + case G_MW_CLIP: + //gSPClipRatio( ucode->w1 ); + break; + + case G_MW_FOG: + m_rsp->RSP_FogFactor( (short)temp->fm, (short)temp->fo); + break; + + case G_MW_PERSPNORM: + //gSPPerspNormalize( w1 ); + break; + + case G_MW_LIGHTCOL: + if ( (temp->offset & 0x7) == 0 ) + { + m_rsp->RSP_LightColor(temp->offset / 0x18, temp->value); + } + break; + } +} + +//----------------------------------------------------------------------------- +// Geometry Mode +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_GeometryMode( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_GeometryMode", M64MSG_VERBOSE); + //clear set + m_rsp->RSP_GeometryMode( ~_SHIFTR( ucode->w0, 0, 24 ), ucode->w1 ); +} + +//----------------------------------------------------------------------------- +//* Set Other Mode H +//! @todo more case in switch +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_SetOtherMode_H( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_H", M64MSG_VERBOSE); + + switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1)) + { + case G_MDSFT_CYCLETYPE: m_rdp->setCycleType( ucode->w1 >> G_MDSFT_CYCLETYPE ); break; + case G_MDSFT_TEXTLUT: m_rdp->setTextureLUT( ucode->w1 >> G_MDSFT_TEXTLUT ); break; + + //TODO + case G_MDSFT_PIPELINE: //m_rdp->setPiplineMode( w1 >> G_MDSFT_PIPELINE ); + break; + case G_MDSFT_TEXTPERSP: //m_rdp->setTexturePerspective( w1 >> G_MDSFT_TEXTPERSP ); + break; + case G_MDSFT_TEXTDETAIL: //m_rdp->setTextureDetail( w1 >> G_MDSFT_TEXTDETAIL ); + break; + case G_MDSFT_TEXTLOD: //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD ); + break; + case G_MDSFT_TEXTFILT: //gDPSetTextureFilter( w1 >> G_MDSFT_TEXTFILT ); + break; + case G_MDSFT_TEXTCONV: //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV ); + break; + case G_MDSFT_COMBKEY: //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY ); + break; + case G_MDSFT_RGBDITHER: //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER ); + break; + case G_MDSFT_ALPHADITHER: //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER ); + break; + default: + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L - Unknown type", M64MSG_WARNING); + + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1; + unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length; + unsigned int mask = ((1 << length) - 1) << shift; + + m_rdp->m_otherMode.h &= ~mask; + m_rdp->m_otherMode.h |= ucode->w1 & mask; + + m_rdp->setUpdateCombiner(true); + break; + } +} + +//----------------------------------------------------------------------------- +// Set Other Mode L +//----------------------------------------------------------------------------- +void UCode5::F3DEX2_SetOtherMode_L( MicrocodeArgument* ucode ) +{ + Logger::getSingleton().printMsg("F3DEX2_SetOtherMode_L", M64MSG_VERBOSE); + + switch (32 - _SHIFTR( ucode->w0, 8, 8 ) - (_SHIFTR( ucode->w0, 0, 8 ) + 1)) + { + case G_MDSFT_ALPHACOMPARE: + m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE); + break; + case G_MDSFT_ZSRCSEL: + m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL ); + break; + case G_MDSFT_RENDERMODE: + m_rdp->setRenderMode( ucode->w1 ); + break; + default: + unsigned int length = _SHIFTR( ucode->w0, 0, 8 ) + 1; + unsigned int shift = 32 - _SHIFTR( ucode->w0, 8, 8 ) - length; + unsigned int mask = ((1 << length) - 1) << shift; + m_rdp->m_otherMode.l &= ~mask; + m_rdp->m_otherMode.l |= ucode->w1 & mask; + break; + } +} + +//***************************************************************************** +// Other +//***************************************************************************** + +void UCode5::F3DEX2_DMAIO( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_DMAIO", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_1( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_1", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_2( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_2", M64MSG_VERBOSE); + //Ignore? +} +void UCode5::F3DEX2_Special_3( MicrocodeArgument* ucode ) { + Logger::getSingleton().printMsg("F3DEX2_Special_3", M64MSG_VERBOSE); + //Ignore? +} + +//***************************************************************************** +// Unimportant Functions +//***************************************************************************** +void UCode5::F3DEX2_Reserved1(MicrocodeArgument* ucode) { + Logger::getSingleton().printMsg("F3DEX2_Reserved1", M64MSG_VERBOSE); + //Ignore +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h new file mode 100755 index 0000000..4b59e73 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode5.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_5_H_ +#define UCODE_5_H_ + +//Includes +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; +class DisplayListParser; + +#define F3DEX2_MOVEMEM 0xDC +#define F3DEX2_MOVEWORD 0xDB + +//***************************************************************************** +//! UCode5 (aka F3DEX2) +//! Microcode used for Zelda and newer games +//***************************************************************************** +class UCode5 +{ +public: + + // Constructor / Destructor + UCode5(); + ~UCode5(); + + static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp); + static void initializeGBI(); + + //Matrices + static void F3DEX2_Mtx( MicrocodeArgument* ucode ); + static void F3DEX2_PopMtx( MicrocodeArgument* ucode ); + + //Textures + static void F3DEX2_Texture( MicrocodeArgument* ucode ); + + //Vertices + static void F3DEX2_Vtx( MicrocodeArgument* ucode ); + static void F3DEX2_Tri1( MicrocodeArgument* ucode ); + static void F3DEX2_Quad( MicrocodeArgument* ucode ); + static void F3DEX2_Line3D( MicrocodeArgument* ucode ); + + //Misc + static void F3DEX2_MoveMem( MicrocodeArgument* ucode ); + static void F3DEX2_MoveWord( MicrocodeArgument* ucode ); + static void F3DEX2_GeometryMode( MicrocodeArgument* ucode ); + static void F3DEX2_SetOtherMode_H( MicrocodeArgument* ucode ); + static void F3DEX2_SetOtherMode_L( MicrocodeArgument* ucode ); + + //Other + static void F3DEX2_DMAIO( MicrocodeArgument* ucode ); + static void F3DEX2_Special_1( MicrocodeArgument* ucode ); + static void F3DEX2_Special_2( MicrocodeArgument* ucode ); + static void F3DEX2_Special_3( MicrocodeArgument* ucode ); + static void F3DEX2_Reserved1( MicrocodeArgument* ucode ); + +private: + + static GBI* m_gbi; //!< Graphics Binary Interface + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer accessing memory like RDRAM and Texture Memory + static DisplayListParser* m_displayListParser; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp new file mode 100755 index 0000000..d64e3a0 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp @@ -0,0 +1,197 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode6.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" +#include "DisplayListParser.h" +#include "RSPMatrixManager.h" + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +GBI* UCode6::m_gbi = 0; // Pointer to Graphics Binary Interface +RSP* UCode6::m_rsp = 0; // Pointer to Reality Signal Processor +RDP* UCode6::m_rdp = 0; // Pointer to Reality Drawing Processor +DisplayListParser* UCode6::m_displayListParser = 0; +Memory* UCode6::m_memory = 0; +unsigned int UCode6::m_vertexIndex = 0; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode6::UCode6() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode6::~UCode6() +{ +} + +//----------------------------------------------------------------------------- +// Initialize +//----------------------------------------------------------------------------- +void UCode6::initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp) +{ + m_gbi = gbi; + m_rsp = rsp; + m_rdp = rdp; + m_memory = memory; + m_displayListParser = dlp; +} + +//----------------------------------------------------------------------------- +//* Initialize GBI +//! Assigns functions to the GBI +//----------------------------------------------------------------------------- +void UCode6::initializeGBI() +{ + GBI_InitFlags( F3D ); + + // GBI Command Command Value Command Function + GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, m_gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_DMA_MTX, F3DDKR_DMA_MTX, m_gbi->m_cmds, F3DDKR_DMA_Mtx ); + GBI_SetGBI( GBI::G_MOVEMEM, F3D_MOVEMEM, m_gbi->m_cmds, UCode0::F3D_MoveMem ); + GBI_SetGBI( GBI::G_DMA_VTX, F3DDKR_DMA_VTX, m_gbi->m_cmds, F3DDKR_DMA_Vtx ); + GBI_SetGBI( GBI::G_DL, F3D_DL, m_gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_DMA_DL, F3DDKR_DMA_DL, m_gbi->m_cmds, F3DDKR_DMA_DList ); + GBI_SetGBI( GBI::G_DMA_TRI, F3DDKR_DMA_TRI, m_gbi->m_cmds, F3DDKR_DMA_Tri ); + GBI_SetGBI( GBI::G_DMA_OFFSETS, F3DDKR_DMA_OFFSETS, m_gbi->m_cmds, F3DDKR_DMA_Offsets ); + GBI_SetGBI( GBI::G_CULLDL, F3D_CULLDL, m_gbi->m_cmds, UCode0::F3D_CullDL ); + GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, m_gbi->m_cmds, F3DDKR_MoveWord ); + GBI_SetGBI( GBI::G_TEXTURE, F3D_TEXTURE, m_gbi->m_cmds, UCode0::F3D_Texture ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, m_gbi->m_cmds, UCode0::F3D_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, m_gbi->m_cmds, UCode0::F3D_SetOtherMode_L ); + GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, m_gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, m_gbi->m_cmds, UCode0::F3D_SetGeometryMode ); + GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE, m_gbi->m_cmds, UCode0::F3D_ClearGeometryMode ); + GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, m_gbi->m_cmds, UCode0::F3D_Quad ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, m_gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, m_gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_RDPHALF_CONT, F3D_RDPHALF_CONT, m_gbi->m_cmds, UCode0::F3D_RDPHalf_Cont ); + GBI_SetGBI( GBI::G_TRI4, F3D_TRI4, m_gbi->m_cmds, UCode0::F3D_Tri4 ); +} + +//----------------------------------------------------------------------------- +// DMA Matrix +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_DMA_Mtx(MicrocodeArgument* ucode) +{ + if (_SHIFTR( ucode->w0, 0, 16 ) != 64) + { + //GBI_DetectUCode(); // Something's wrong + return; + } + + unsigned int index = _SHIFTR( ucode->w0, 16, 4 ); + unsigned int multiply; + + if (index == 0) // DKR + { + index = _SHIFTR( ucode->w0, 22, 2 ); + multiply = 0; + } + else // Gemini + { + multiply = _SHIFTR( ucode->w0, 23, 1 ); + } + + m_rsp->RSP_DMAMatrix( ucode->w1, index, multiply ); +} + +//----------------------------------------------------------------------------- +// DMA Vertex +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_DMA_Vtx(MicrocodeArgument* ucode) +{ + if ((ucode->w0 & F3DDKR_VTX_APPEND)) + { + if ( m_rsp->getVertexMgr()->getBillboard() ) { + m_vertexIndex = 1; + } + } + else { + m_vertexIndex = 0; + } + + unsigned int n = _SHIFTR( ucode->w0, 19, 5 ) + 1; + + m_rsp->RSP_DMAVertex( ucode->w1, n, m_vertexIndex + _SHIFTR( ucode->w0, 9, 5 ) ); + + m_vertexIndex += n; +} + +//----------------------------------------------------------------------------- +// DMA Triangle +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_DMA_Tri(MicrocodeArgument* ucode) +{ + m_rsp->RSP_DMATriangles( ucode->w1, _SHIFTR( ucode->w0, 4, 12 ) ); + m_vertexIndex = 0; +} + +//----------------------------------------------------------------------------- +// DMA Display List +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_DMA_DList(MicrocodeArgument* ucode) +{ + m_rsp->RSP_DMADisplayList( ucode->w0, ucode->w1 /*_SHIFTR( ucode->w0, 16, 8 )*/ ); +} + +//----------------------------------------------------------------------------- +// DMA Offsets +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_DMA_Offsets(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("PerfectDark_Vertex", M64MSG_VERBOSE); + RSPUCodeSetDMAOffsets* temp = (RSPUCodeSetDMAOffsets*)ucode; + + //Set DMA Offsets + m_rsp->RSP_SetDMAOffsets(temp->addressOffsetMatrix, temp->addressOffsetVertex); +} + +//----------------------------------------------------------------------------- +// MoveWord +//----------------------------------------------------------------------------- +void UCode6::F3DDKR_MoveWord(MicrocodeArgument* ucode) +{ + switch (_SHIFTR( ucode->w0, 0, 8 )) + { + case 0x02: + m_rsp->getVertexMgr()->setBillboard( ucode->w1 & 1 ); + break; + case 0x0A: + m_rsp->getMatrixMgr()->selectViewMatrix(_SHIFTR( ucode->w1, 6, 2 )); + break; + default: + UCode0::F3D_MoveWord( ucode ); + break; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h new file mode 100755 index 0000000..30e8bab --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode6.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_6_H_ +#define UCODE_6_H_ + +//Includes +#include "UCodeDefs.h" + +#define F3DDKR_VTX_APPEND 0x00010000 +#define F3DDKR_DMA_MTX 0x01 +#define F3DDKR_DMA_VTX 0x04 +#define F3DDKR_DMA_TRI 0x05 +#define F3DDKR_DMA_DL 0x07 +#define F3DDKR_DMA_OFFSETS 0xBF + +//Forward declaration +class GBI; +class RSP; +class RDP; +class Memory; +class DisplayListParser; + +//***************************************************************************** +//! UCode6 +//! Microcode used for Diddy Kong Racing +//***************************************************************************** +class UCode6 +{ +public: + + UCode6(); + ~UCode6(); + + static void initialize(GBI* gbi, RSP* rsp, RDP* rdp, Memory* mem, DisplayListParser* dlp); + static void initializeGBI(); + + static void F3DDKR_MoveWord(MicrocodeArgument* ucode); + static void F3DDKR_DMA_Offsets(MicrocodeArgument* ucode); + static void F3DDKR_DMA_DList(MicrocodeArgument* ucode); + static void F3DDKR_DMA_Tri(MicrocodeArgument* ucode); + static void F3DDKR_DMA_Vtx(MicrocodeArgument* ucode); + static void F3DDKR_DMA_Mtx(MicrocodeArgument* ucode); + +private: + + static GBI* m_gbi; //!< Pointer to Graphics Binary Interface + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + static RDP* m_rdp; //!< Pointer to Reality Drawing Processor + static Memory* m_memory; //!< Pointer to Memory Manager + static DisplayListParser* m_displayListParser; //!< Pointer to Display list parser + + static unsigned int m_vertexIndex; + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp new file mode 100755 index 0000000..d7e7de9 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp @@ -0,0 +1,249 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode7.h" +#include "UCode0.h" +#include "UCode1.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "Memory.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" + +#define S2DEX_BG_1CYC 0x01 +#define S2DEX_BG_COPY 0x02 +#define S2DEX_OBJ_RECTANGLE 0x03 +#define S2DEX_OBJ_SPRITE 0x04 +#define S2DEX_OBJ_MOVEMEM 0x05 +#define S2DEX_LOAD_UCODE 0xAF +#define S2DEX_SELECT_DL 0xB0 +#define S2DEX_OBJ_RENDERMODE 0xB1 +#define S2DEX_OBJ_RECTANGLE_R 0xB2 +#define S2DEX_OBJ_LOADTXTR 0xC1 +#define S2DEX_OBJ_LDTX_SPRITE 0xC2 +#define S2DEX_OBJ_LDTX_RECT 0xC3 +#define S2DEX_OBJ_LDTX_RECT_R 0xC4 +#define S2DEX_RDPHALF_0 0xE4 + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode7::m_rsp = 0; //!< Pointer to Reality Signal Processor + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode7::UCode7() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode7::~UCode7() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode7::initialize(RSP* rsp) +{ + m_rsp = rsp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode7::initializeGBI(GBI* gbi) +{ + // Set GeometryMode flags + GBI_InitFlags( F3DEX ); + + // GBI Command Command Value Command Function + GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_BG_1CYC, S2DEX_BG_1CYC, gbi->m_cmds, S2DEX_BG_1Cyc ); + GBI_SetGBI( GBI::G_BG_COPY, S2DEX_BG_COPY, gbi->m_cmds, S2DEX_BG_Copy ); + GBI_SetGBI( GBI::G_OBJ_RECTANGLE, S2DEX_OBJ_RECTANGLE, gbi->m_cmds, S2DEX_Obj_Rectangle ); + GBI_SetGBI( GBI::G_OBJ_SPRITE, S2DEX_OBJ_SPRITE, gbi->m_cmds, S2DEX_Obj_Sprite ); + GBI_SetGBI( GBI::G_OBJ_MOVEMEM, S2DEX_OBJ_MOVEMEM, gbi->m_cmds, S2DEX_Obj_MoveMem ); + GBI_SetGBI( GBI::G_DL, F3D_DL, gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_SELECT_DL, S2DEX_SELECT_DL, gbi->m_cmds, S2DEX_Select_DL ); + GBI_SetGBI( GBI::G_OBJ_RENDERMODE, S2DEX_OBJ_RENDERMODE, gbi->m_cmds, S2DEX_Obj_RenderMode ); + GBI_SetGBI( GBI::G_OBJ_RECTANGLE_R, S2DEX_OBJ_RECTANGLE_R, gbi->m_cmds, S2DEX_Obj_Rectangle_R ); + GBI_SetGBI( GBI::G_OBJ_LOADTXTR, S2DEX_OBJ_LOADTXTR, gbi->m_cmds, S2DEX_Obj_LoadTxtr ); + GBI_SetGBI( GBI::G_OBJ_LDTX_SPRITE, S2DEX_OBJ_LDTX_SPRITE, gbi->m_cmds, S2DEX_Obj_LdTx_Sprite ); + GBI_SetGBI( GBI::G_OBJ_LDTX_RECT, S2DEX_OBJ_LDTX_RECT, gbi->m_cmds, S2DEX_Obj_LdTx_Rect ); + GBI_SetGBI( GBI::G_OBJ_LDTX_RECT_R, S2DEX_OBJ_LDTX_RECT_R, gbi->m_cmds, S2DEX_Obj_LdTx_Rect_R ); + GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, gbi->m_cmds, UCode0::F3D_MoveWord ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, gbi->m_cmds, UCode0::F3D_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, gbi->m_cmds, UCode0::F3D_SetOtherMode_L ); + GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_LOAD_UCODE, S2DEX_LOAD_UCODE, gbi->m_cmds, UCode1::F3DEX_Load_uCode ); +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_BG_1Cyc(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_BG_1Cyc - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_BG_Copy(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_BG_Copy - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! Obj Ractangle +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_Rectangle(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_Rectangle - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_Sprite(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_Sprite - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_MoveMem(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_MoveMem - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_LoadTxtr(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_LoadTxtr - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_LdTx_Sprite(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Sprite - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_LdTx_Rect_R(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Rect_R - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! Select Display List +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Select_DL(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Select_DL - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_RenderMode(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_RenderMode - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_Rectangle_R(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_Rectangle_R - Unimplemented", M64MSG_WARNING); + warned = true; + } +} + +//----------------------------------------------------------------------------- +//! +//----------------------------------------------------------------------------- +void UCode7::S2DEX_Obj_LdTx_Rect(MicrocodeArgument* ucode) +{ + static bool warned = false; + if ( !warned ) { + Logger::getSingleton().printMsg("S2DEX_Obj_LdTx_Rect - Unimplemented", M64MSG_WARNING); + warned = true; + } +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h new file mode 100755 index 0000000..5565591 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode7.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_7_H_ +#define UCODE_7_H_ + +//Includes +#include "UCodeDefs.h" + +//Forward declaration +class GBI; +class RSP; + +//***************************************************************************** +//! UCode4 (aka S2DEX) +//! Microcode used for Yoshi's Story +//***************************************************************************** +class UCode7 +{ +public: + + UCode7(); + ~UCode7(); + + static void initialize(RSP* rsp); + static void initializeGBI(GBI* gbi); + + static void S2DEX_Select_DL(MicrocodeArgument* ucode); + static void S2DEX_BG_1Cyc(MicrocodeArgument* ucode); + static void S2DEX_BG_Copy(MicrocodeArgument* ucode); + static void S2DEX_Obj_Rectangle(MicrocodeArgument* ucode); + static void S2DEX_Obj_Sprite(MicrocodeArgument* ucode); + static void S2DEX_Obj_MoveMem(MicrocodeArgument* ucode); + static void S2DEX_Obj_RenderMode(MicrocodeArgument* ucode); + static void S2DEX_Obj_Rectangle_R(MicrocodeArgument* ucode); + static void S2DEX_Obj_LoadTxtr(MicrocodeArgument* ucode); + static void S2DEX_Obj_LdTx_Sprite(MicrocodeArgument* ucode); + static void S2DEX_Obj_LdTx_Rect(MicrocodeArgument* ucode); + static void S2DEX_Obj_LdTx_Rect_R(MicrocodeArgument* ucode); + +private: + + static RSP* m_rsp; //!< Pointer to Reality Signal Processor + +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp new file mode 100755 index 0000000..e69de29 diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode8.h new file mode 100755 index 0000000..e69de29 diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp new file mode 100755 index 0000000..62b62bb --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp @@ -0,0 +1,120 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCode9.h" +#include "UCode0.h" +#include "GBI.h" +#include "RSP.h" +#include "UCodeDefs.h" +#include "GBIDefs.h" +#include "Logger.h" + +#define F3DPD_VTXCOLORBASE 0x07 + +//----------------------------------------------------------------------------- +// Static Variables +//----------------------------------------------------------------------------- +RSP* UCode9::m_rsp = 0; //!< Pointer to Reality Signal Processor + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +UCode9::UCode9() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +UCode9::~UCode9() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +void UCode9::initialize(RSP* rsp) +{ + m_rsp = rsp; +} + +//----------------------------------------------------------------------------- +//! Initialize GBI +//----------------------------------------------------------------------------- +void UCode9::initializeGBI(GBI* gbi) +{ + // Set GeometryMode flags + GBI_InitFlags( F3D ); + + // GBI Command Command Value Command Function + GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, gbi->m_cmds, UCode0::F3D_SPNoOp ); + GBI_SetGBI( GBI::G_MTX, F3D_MTX, gbi->m_cmds, UCode0::F3D_Mtx ); + GBI_SetGBI( GBI::G_RESERVED0, F3D_RESERVED0, gbi->m_cmds, UCode0::F3D_Reserved0 ); + GBI_SetGBI( GBI::G_MOVEMEM, F3D_MOVEMEM, gbi->m_cmds, UCode0::F3D_MoveMem ); + GBI_SetGBI( GBI::G_VTX, F3D_VTX, gbi->m_cmds, PerfectDark_Vertex ); + GBI_SetGBI( GBI::G_RESERVED1, F3D_RESERVED1, gbi->m_cmds, UCode0::F3D_Reserved1 ); + GBI_SetGBI( GBI::G_DL, F3D_DL, gbi->m_cmds, UCode0::F3D_DList ); + GBI_SetGBI( GBI::G_VTXCOLORBASE, F3DPD_VTXCOLORBASE, gbi->m_cmds, PerfectDark_VertexColorBase ); + GBI_SetGBI( GBI::G_RESERVED3, F3D_RESERVED3, gbi->m_cmds, UCode0::F3D_Reserved3 ); + GBI_SetGBI( GBI::G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, gbi->m_cmds, UCode0::F3D_Sprite2D_Base ); + GBI_SetGBI( GBI::G_TRI1, F3D_TRI1, gbi->m_cmds, UCode0::F3D_Tri1 ); + GBI_SetGBI( GBI::G_CULLDL, F3D_CULLDL, gbi->m_cmds, UCode0::F3D_CullDL ); + GBI_SetGBI( GBI::G_POPMTX, F3D_POPMTX, gbi->m_cmds, UCode0::F3D_PopMtx ); + GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, gbi->m_cmds, UCode0::F3D_MoveWord ); + GBI_SetGBI( GBI::G_TEXTURE, F3D_TEXTURE, gbi->m_cmds, UCode0::F3D_Texture ); + GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, gbi->m_cmds, UCode0::F3D_SetOtherMode_H ); + GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, gbi->m_cmds, UCode0::F3D_SetOtherMode_L ); + GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, gbi->m_cmds, UCode0::F3D_EndDL ); + GBI_SetGBI( GBI::G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, gbi->m_cmds, UCode0::F3D_SetGeometryMode ); + GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE,F3D_CLEARGEOMETRYMODE, gbi->m_cmds, UCode0::F3D_ClearGeometryMode ); + GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, gbi->m_cmds, UCode0::F3D_Quad ); + GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, gbi->m_cmds, UCode0::F3D_RDPHalf_1 ); + GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, gbi->m_cmds, UCode0::F3D_RDPHalf_2 ); + GBI_SetGBI( GBI::G_RDPHALF_CONT, F3D_RDPHALF_CONT, gbi->m_cmds, UCode0::F3D_RDPHalf_Cont ); + GBI_SetGBI( GBI::G_TRI4, F3D_TRI4, gbi->m_cmds, UCode0::F3D_Tri4 ); + + //Set DMA Offset + m_rsp->RSP_SetDMAOffsets(0,0); +} + +//----------------------------------------------------------------------------- +//! Perfect Dark Vertex +//----------------------------------------------------------------------------- +void UCode9::PerfectDark_Vertex(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("PerfectDark_Vertex", M64MSG_VERBOSE); + RSPUCode9AddColorIndexVertices* temp = (RSPUCode9AddColorIndexVertices*)ucode; + + //Set Color Index Vertices + m_rsp->RSP_CIVertex(temp->segmentAddress, temp->numVertices + 1, temp->firstVertexIndex); +} + +//----------------------------------------------------------------------------- +//! Perfect Dark Color Base +//----------------------------------------------------------------------------- +void UCode9::PerfectDark_VertexColorBase(MicrocodeArgument* ucode) +{ + Logger::getSingleton().printMsg("PerfectDark_VertexColorBase", M64MSG_VERBOSE); + RSPUCodeSetVertexColorBase* temp = (RSPUCodeSetVertexColorBase*)ucode; + + //Set Vertex Color Base + m_rsp->RSP_SetVertexColorBase(temp->rdramAddress); +} diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h new file mode 100755 index 0000000..dfc15c3 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCode9.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_9_H_ +#define UCODE_9_H_ + +//Includes +#include "UCodeDefs.h" + +class GBI; +class RSP; + +//***************************************************************************** +//! UCode9 +//! Microcode used to play Perfect Dark +//***************************************************************************** +class UCode9 +{ +public: + + //Constructor / Destructor + UCode9(); + ~UCode9(); + + static void initialize(RSP* rsp); + static void initializeGBI(GBI* gbi); + + static void PerfectDark_Vertex(MicrocodeArgument* ucode); + static void PerfectDark_VertexColorBase(MicrocodeArgument* ucode); + +private: + + static RSP* m_rsp; //!< Pointer to Reality Signal Processor +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h new file mode 100755 index 0000000..802a247 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef UCODE_DATA_H_ +#define UCODE_DATA_H_ + +//***************************************************************************** +// UCode Definitions +//***************************************************************************** +#define F3D 0 // Super Mario 64 +#define F3DEX 1 +#define F3DEX2 2 +#define L3D 3 +#define L3DEX 4 +#define L3DEX2 5 +#define S2DEX 6 +#define S2DEX2 7 +#define F3DPD 8 +#define F3DDKR 9 +#define F3DWRUS 10 +#define NONE 11 + +//***************************************************************************** +//* UCode Data +//! Used to Identify witch ucode diffrent games use +//***************************************************************************** +struct UcodeData +{ + unsigned int ucode; //!< ID of ucode + unsigned int crc_size; //!< Hash value used to identify ucode + unsigned int crc_800; //!< Hash value used to identify ucode + const char* ucode_name; //!< Name used to identify ucode + bool non_nearclip; //!< Does ucode support near clipping? + bool reject; //!< +}; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp new file mode 100755 index 0000000..82b28c4 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp @@ -0,0 +1,348 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "UCodeSelector.h" +#include "Memory.h" +#include "CRCCalculator.h" +#include "UCodeIdentificationData.h" +#include +#include +#include +#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 +#if defined(WIN32) && !defined(__MINGW32__) +#include +#endif + +//***************************************************************************** +//* Memory Leak Detector Class +//! Class for checking if there are any memory leaks. +//***************************************************************************** +class CMemoryLeakDetector +{ +public: + + //Constructor + CMemoryLeakDetector() + { +#if defined(WIN32) && !defined(__MINGW32__) + ::OutputDebugString(">>> Memory leak detection enabled <<<\n"); +#endif + } + + //Destructor + ~CMemoryLeakDetector() + { +#if defined(WIN32) && !defined(__MINGW32__) + if ( !_CrtDumpMemoryLeaks() ) + { + ::OutputDebugString(">>> No memory leak detected <<<\n"); + } +#endif + } +}; + +CMemoryLeakDetector md; + +#endif diff --git a/source/mupen64plus-video-arachnoid/src/video_api_export.ver b/source/mupen64plus-video-arachnoid/src/video_api_export.ver new file mode 100644 index 0000000..c4db656 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/video_api_export.ver @@ -0,0 +1,22 @@ +{ global: +PluginStartup; +PluginShutdown; +PluginGetVersion; +ChangeWindow; +InitiateGFX; +MoveScreen; +ProcessDList; +ProcessRDPList; +RomClosed; +RomOpen; +ShowCFB; +UpdateScreen; +ViStatusChanged; +ViWidthChanged; +ReadScreen2; +SetRenderingCallback; +ResizeVideoOutput; +FBRead; +FBWrite; +FBGetFrameBufferInfo; +local: *; };