mupen64plus-video-arachnoid/.hg_archival.txt0000644000000000000000000000022412165424550017530 0ustar 00000000000000repo: 976896f303442924a04de6fb0725b98269a9bbe3 node: d88e66b6a15a517db588fdb5eabf1ad4b7de0056 branch: default latesttag: 2.0.0 latesttagdistance: 1 mupen64plus-video-arachnoid/.hgignore0000644000000000000000000000012412165424550016244 0ustar 00000000000000syntax: regexp ^projects/unix/_obj/ ^projects/unix/mupen64plus-video-arachnoid.so$ mupen64plus-video-arachnoid/.hgtags0000644000000000000000000000021712165424550015722 0ustar 000000000000007713c313dc69e551761636645e9ad94d2e3a93c6 1.99.4 567e98c190507a3818bf851ecb2b5de600de7896 1.99.5 2e14d1a541b7a6c2a09c4c6173370ca336f4c001 2.0.0 mupen64plus-video-arachnoid/COPYING0000644000000000000000000004310312165424550015500 0ustar 00000000000000 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. mupen64plus-video-arachnoid/README0000644000000000000000000000051712165424550015327 0ustar 00000000000000Arachnoid 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. mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.sln0000755000000000000000000000157012165424550023001 0ustar 00000000000000Microsoft 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 mupen64plus-video-arachnoid/projects/msvc9/GraphicsPlugin.vcproj0000755000000000000000000004735012165424550023516 0ustar 00000000000000 mupen64plus-video-arachnoid/projects/unix/Makefile0000755000000000000000000003061212165424550020725 0ustar 00000000000000#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * 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 $(warning Architecture "$(HOST_CPU)" not officially supported.') endif endif # base CFLAGS, LDLIBS, and LDFLAGS OPTFLAGS ?= -O3 -flto 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) 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)/renderer/OpenGL2DRenderer.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 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 mupen64plus-video-arachnoid/src/Assembler/assembler.h0000755000000000000000000002375212165424550021312 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.cpp0000755000000000000000000003510112165424550024157 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); }; mupen64plus-video-arachnoid/src/Combiner/AdvancedCombinerManager.h0000755000000000000000000000672112165424550023632 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.cpp0000755000000000000000000006711312165424550024026 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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() { ARB_texture_env_combine = isExtensionSupported( "GL_ARB_texture_env_combine" ); ARB_texture_env_crossbar = isExtensionSupported( "GL_ARB_texture_env_crossbar" ); 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; } mupen64plus-video-arachnoid/src/Combiner/AdvancedTexEnvCombiner.h0000755000000000000000000001420012165424550023460 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 #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 #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 mupen64plus-video-arachnoid/src/Combiner/CombinerBase.cpp0000755000000000000000000001517012165424550022035 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/Combiner/CombinerBase.h0000755000000000000000000001061612165424550021502 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/CombinerCache.cpp0000755000000000000000000000521612165424550022166 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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(); } mupen64plus-video-arachnoid/src/Combiner/CombinerCache.h0000755000000000000000000000444212165424550021633 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.cpp0000755000000000000000000000760512165424550023552 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/Combiner/CombinerStageCreator.h0000755000000000000000000000236212165424550023212 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.cpp0000755000000000000000000001134112165424550023364 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } } } mupen64plus-video-arachnoid/src/Combiner/CombinerStageMerger.h0000755000000000000000000000230512165424550023031 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/CombinerStructs.h0000755000000000000000000001101412165424550022270 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.cpp0000755000000000000000000000612612165424550022257 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 ); } mupen64plus-video-arachnoid/src/Combiner/DummyCombiner.h0000755000000000000000000000417412165424550021725 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.cpp0000755000000000000000000002277212165424550023554 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/Combiner/SimpleTexEnvCombiner.h0000755000000000000000000000433112165424550023210 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/DisplayListParser.cpp0000755000000000000000000001676112165424550021373 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } } mupen64plus-video-arachnoid/src/DisplayListParser.h0000755000000000000000000000662212165424550021033 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ExtensionChecker.cpp0000755000000000000000000000373112165424550021207 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/ExtensionChecker.h0000755000000000000000000000222312165424550020647 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/FogManager.cpp0000755000000000000000000001727612165424550017765 0ustar 00000000000000/****************************************************************************** * 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 #ifdef GL_GLEXT_PROTOTYPES 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 //----------------------------------------------------------------------------- //! 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 ) { 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; } } glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); } //----------------------------------------------------------------------------- //! 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 ); } mupen64plus-video-arachnoid/src/FogManager.h0000755000000000000000000000501612165424550017417 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/GBI/GBI.cpp0000755000000000000000000002474212165424550016755 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/GBI/GBI.h0000755000000000000000000001424112165424550016413 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/GBI/GBIDefs.h0000755000000000000000000002543512165424550017224 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/GraphicsPlugin.cpp0000755000000000000000000003725212165424550020672 0ustar 00000000000000/****************************************************************************** * 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 //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 ); 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"); //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) CoreVideo_Quit(); 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); { 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(); } 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; 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(); } //----------------------------------------------------------------------------- // 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) { if (front) glReadBuffer(GL_FRONT); else glReadBuffer(GL_BACK); 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) { } mupen64plus-video-arachnoid/src/GraphicsPlugin.h0000755000000000000000000000742112165424550020332 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/Memory.cpp0000755000000000000000000000463612165424550017223 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/Memory.h0000755000000000000000000000536412165424550016667 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/MultiTexturingExt.cpp0000755000000000000000000000422512165424550021432 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 #ifndef GL_GLEXT_VERSION PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB; #endif bool g_MultiTextureARBSupport = false; //----------------------------------------------------------------------------- //! Function for initializeing multitextureing extensions //----------------------------------------------------------------------------- bool initializeMultiTexturingExtensions() { //Initialize Extentions 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; } mupen64plus-video-arachnoid/src/MultiTexturingExt.h0000755000000000000000000002351712165424550021104 0ustar 00000000000000/****************************************************************************** * 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 #ifndef GL_ARB_multitexture #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 #ifndef GL_ARB_multitexture #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 mupen64plus-video-arachnoid/src/N64Games.h0000755000000000000000000000316112165424550016734 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/OpenGL.h0000755000000000000000000000240612165424550016535 0ustar 00000000000000/****************************************************************************** * 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 #include #endif #ifndef WIN32 #include #endif #endif mupen64plus-video-arachnoid/src/OpenGLManager.cpp0000755000000000000000000002647212165424550020374 0ustar 00000000000000/****************************************************************************** * 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); m_drawFlag = 0; CoreVideo_GL_SwapBuffers(); //glFlush(); } //----------------------------------------------------------------------------- // Set Wireframe //----------------------------------------------------------------------------- void OpenGLManager::setWireFrame(bool wireframe) { m_wireframe = wireframe; if ( wireframe ) { glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); } else { glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); } } //----------------------------------------------------------------------------- // 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; } mupen64plus-video-arachnoid/src/OpenGLManager.h0000755000000000000000000001061612165424550020032 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/RDP/RDP.cpp0000755000000000000000000007765312165424550017036 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/RDP/RDP.h0000755000000000000000000002625412165424550016472 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RDP/RDPInstructions.cpp0000755000000000000000000004440212165424550021445 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/RDP/RDPInstructions.h0000755000000000000000000000703512165424550021113 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RDP/RDPUCodeStructs.h0000755000000000000000000001354312165424550020777 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RSP/RSP.cpp0000755000000000000000000005664512165424550017072 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/RSP/RSP.h0000755000000000000000000002275212165424550016527 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RSP/RSPLightManager.cpp0000755000000000000000000000722412165424550021342 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/RSP/RSPLightManager.h0000755000000000000000000000612012165424550021001 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.cpp0000755000000000000000000002201012165424550021525 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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]; } mupen64plus-video-arachnoid/src/RSP/RSPMatrixManager.h0000755000000000000000000000644012165424550021203 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.cpp0000755000000000000000000004475712165424550021564 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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++; } } mupen64plus-video-arachnoid/src/RSP/RSPVertexManager.h0000755000000000000000000001063512165424550021215 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/RomDetector.cpp0000755000000000000000000001110612165424550020170 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/RomDetector.h0000755000000000000000000001176512165424550017650 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/SecondaryColorExt.cpp0000755000000000000000000001012712165424550021352 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 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; PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT; #endif bool initializeSecondaryColorExtension() { 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; } return false; } mupen64plus-video-arachnoid/src/SecondaryColorExt.h0000755000000000000000000001077612165424550021031 0ustar 00000000000000/****************************************************************************** * 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_ mupen64plus-video-arachnoid/src/UCodeDefs.h0000755000000000000000000004025112165424550017212 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/VI.cpp0000755000000000000000000000612012165424550016257 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/VI.h0000755000000000000000000000342612165424550015732 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/config/Config.cpp0000755000000000000000000001110312165424550020410 0ustar 00000000000000/****************************************************************************** * 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 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"); } mupen64plus-video-arachnoid/src/config/Config.h0000755000000000000000000000422612165424550020065 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/config/ConfigMap.h0000755000000000000000000000516312165424550020524 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 }; #endif mupen64plus-video-arachnoid/src/config/StringFunctions.cpp0000755000000000000000000001051212165424550022345 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/config/StringFunctions.h0000755000000000000000000000620212165424550022013 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/config/StringValue.h0000755000000000000000000000752012165424550021123 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.cpp0000755000000000000000000002107112165424550022413 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 //----------------------------------------------------------------------------- //OpenGL Texture Definitions //----------------------------------------------------------------------------- typedef GLvoid (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum texture); PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; #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 glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //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(); { 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(); } _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(); { 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(); } _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 if ( glActiveTexture == 0 ) { glActiveTexture = (PFNGLACTIVETEXTUREPROC) CoreVideo_GL_GetProcAddress("glActiveTexture"); } #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); } mupen64plus-video-arachnoid/src/framebuffer/FrameBuffer.h0000755000000000000000000000405512165424550022063 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/hash/CRCCalculator.cpp0000755000000000000000000001202412165424550021305 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/hash/CRCCalculator.h0000755000000000000000000000435612165424550020763 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/hash/CRCCalculator2.cpp0000755000000000000000000000755012165424550021377 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/hash/CRCCalculator2.h0000755000000000000000000000436412165424550021044 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/log/Logger.cpp0000755000000000000000000000476512165424550017756 0ustar 00000000000000/****************************************************************************** * 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); } } mupen64plus-video-arachnoid/src/log/Logger.h0000755000000000000000000000402712165424550017412 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/m64p.h0000755000000000000000000000566712165424550016213 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/main.cpp0000755000000000000000000004655412165424550016704 0ustar 00000000000000/****************************************************************************** * 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 mupen64plus-video-arachnoid/src/math/MathLib.h0000755000000000000000000000554712165424550017673 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/math/Matrix4.cpp0000755000000000000000000001053312165424550020225 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/math/Matrix4.h0000755000000000000000000002230412165424550017671 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/osal_dynamiclib.h0000755000000000000000000000367212165424550020550 0ustar 00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 */ mupen64plus-video-arachnoid/src/osal_dynamiclib_unix.cpp0000755000000000000000000000474012165424550022143 0ustar 00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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; } mupen64plus-video-arachnoid/src/osal_dynamiclib_win32.cpp0000755000000000000000000000617612165424550022127 0ustar 00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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; } mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.cpp0000755000000000000000000001563112165424550022557 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); glBegin(GL_QUADS); glVertex3f(x0, y0, depth); glVertex3f(x1, y0, depth); glVertex3f(x1, y1, depth); glVertex3f(x0, y1, depth); glEnd(); //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 ); //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(); //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 ); //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(); //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? } mupen64plus-video-arachnoid/src/renderer/OpenGL2DRenderer.h0000755000000000000000000000551012165424550022217 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.cpp0000755000000000000000000004315612165424550022374 0ustar 00000000000000/****************************************************************************** * 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" 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(); 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 ); 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(); glLoadIdentity(); //OGL_UpdateCullFace(); //OGL_UpdateViewport(); } mupen64plus-video-arachnoid/src/renderer/OpenGLRenderer.h0000755000000000000000000000720512165424550022034 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/texture/CachedTexture.cpp0000755000000000000000000001116412165424550022175 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } mupen64plus-video-arachnoid/src/texture/CachedTexture.h0000755000000000000000000000554512165424550021650 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp0000755000000000000000000003427612165424550023352 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } } mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.h0000755000000000000000000000505012165424550023003 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/texture/TextureCache.cpp0000755000000000000000000005073112165424550022034 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, texture->realWidth, texture->realHeight, 0, GL_RGBA, imageType, dest ); 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; } mupen64plus-video-arachnoid/src/texture/TextureCache.h0000755000000000000000000000676112165424550021505 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/texture/TextureLoader.cpp0000755000000000000000000002247112165424550022237 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/texture/TextureLoader.h0000755000000000000000000001124612165424550021702 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode0.cpp0000755000000000000000000005321512165424550020311 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/ucodes/UCode0.h0000755000000000000000000001333212165424550017752 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode1.cpp0000755000000000000000000002532712165424550020315 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 ); } mupen64plus-video-arachnoid/src/ucodes/UCode1.h0000755000000000000000000000726512165424550017763 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode10.cpp0000755000000000000000000002131212165424550020363 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/ucodes/UCode10.h0000755000000000000000000000431012165424550020027 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode2.cpp0000755000000000000000000001000712165424550020303 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/ucodes/UCode2.h0000755000000000000000000000445212165424550017757 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode3.cpp0000755000000000000000000000000012165424550020274 0ustar 00000000000000mupen64plus-video-arachnoid/src/ucodes/UCode3.h0000755000000000000000000000000012165424550017741 0ustar 00000000000000mupen64plus-video-arachnoid/src/ucodes/UCode4.cpp0000755000000000000000000001206212165424550020310 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/ucodes/UCode4.h0000755000000000000000000000352112165424550017755 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode5.cpp0000755000000000000000000005056412165424550020322 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 } mupen64plus-video-arachnoid/src/ucodes/UCode5.h0000755000000000000000000000623412165424550017762 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode6.cpp0000755000000000000000000002012712165424550020313 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/ucodes/UCode6.h0000755000000000000000000000524512165424550017764 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode7.cpp0000755000000000000000000002363512165424550020323 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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; } } mupen64plus-video-arachnoid/src/ucodes/UCode7.h0000755000000000000000000000447212165424550017766 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCode8.cpp0000755000000000000000000000000012165424550020301 0ustar 00000000000000mupen64plus-video-arachnoid/src/ucodes/UCode8.h0000755000000000000000000000000012165424550017746 0ustar 00000000000000mupen64plus-video-arachnoid/src/ucodes/UCode9.cpp0000755000000000000000000001415212165424550020317 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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); } mupen64plus-video-arachnoid/src/ucodes/UCode9.h0000755000000000000000000000333112165424550017761 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCodeIdentificationData.h0000755000000000000000000000422212165424550023334 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/ucodes/UCodeSelector.cpp0000755000000000000000000004726512165424550021742 0ustar 00000000000000/****************************************************************************** * Arachnoid Graphics Plugin for Mupen64Plus * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ * * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public 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 mupen64plus-video-arachnoid/src/video_api_export.ver0000644000000000000000000000046612165424550021317 0ustar 00000000000000{ global: PluginStartup; PluginShutdown; PluginGetVersion; ChangeWindow; InitiateGFX; MoveScreen; ProcessDList; ProcessRDPList; RomClosed; RomOpen; ShowCFB; UpdateScreen; ViStatusChanged; ViWidthChanged; ReadScreen2; SetRenderingCallback; ResizeVideoOutput; FBRead; FBWrite; FBGetFrameBufferInfo; local: *; };