m64p: Add a clean clone of mupen64plus-video-glide64

This commit is contained in:
pjgat09 2013-05-04 23:15:34 +00:00
parent 29226acd54
commit d12829b1ee
85 changed files with 72080 additions and 0 deletions

View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupen64plus-video-glide64", "mupen64plus-video-glide64.vcproj", "{F3E6138A-C318-4020-B408-A9A24D8B3DE7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|Win32.ActiveCfg = Debug|Win32
{F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Debug|Win32.Build.0 = Debug|Win32
{F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|Win32.ActiveCfg = Release|Win32
{F3E6138A-C318-4020-B408-A9A24D8B3DE7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,453 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="mupen64plus-video-glide64"
ProjectGUID="{F3E6138A-C318-4020-B408-A9A24D8B3DE7}"
RootNamespace="mupen64plusvideoglide64"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.14/include"
PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="4"
CallingConvention="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib ..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib "
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)&quot;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../src;../../src/wrapper;../../../mupen64plus-core/src/api;../../../mupen64plus-win32-deps/SDL-1.2.14/include"
PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib ..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib "
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)..\..\..\mupen64plus-ui-console\projects\msvc8\$(ConfigurationName)&quot;"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\src\3dmath.cpp"
>
</File>
<File
RelativePath="..\..\src\Combine.cpp"
>
</File>
<File
RelativePath="..\..\src\Config.cpp"
>
</File>
<File
RelativePath="..\..\src\CRC.cpp"
>
</File>
<File
RelativePath="..\..\src\Debugger.cpp"
>
</File>
<File
RelativePath="..\..\src\DepthBufferRender.cpp"
>
</File>
<File
RelativePath="..\..\src\Ini.cpp"
>
</File>
<File
RelativePath="..\..\src\Main.cpp"
>
</File>
<File
RelativePath="..\..\src\osal_dynamiclib_win32.c"
>
</File>
<File
RelativePath="..\..\src\rdp.cpp"
>
</File>
<File
RelativePath="..\..\src\TexBuffer.cpp"
>
</File>
<File
RelativePath="..\..\src\TexCache.cpp"
>
</File>
<File
RelativePath="..\..\src\Util.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Wrapper"
>
<File
RelativePath="..\..\src\wrapper\2xsai.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\2xsai.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\3dfx.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\combiner.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\config.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\filter.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\g3ext.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\geometry.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\glide.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\glidesys.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\glideutl.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\hq2x.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\hq4x.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\main.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\wrapper\main.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\sst1vid.h"
>
</File>
<File
RelativePath="..\..\src\wrapper\textures.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\wrapper\"
/>
</FileConfiguration>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,412 @@
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# * Mupen64plus-video-glide64 - Makefile *
# * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
# * Copyright (C) 2010 Jon Ring *
# * Copyright (C) 2007-2009 Richard Goedeken *
# * Copyright (C) 2007-2008 DarkJeztr Tillin9 *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation; either version 2 of the License, or *
# * (at your option) any later version. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU General Public License for more details. *
# * *
# * You should have received a copy of the GNU General Public 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 Glide64 plugin in Mupen64Plus
# detect operating system
UNAME ?= $(shell uname -s)
OS := NONE
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
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)
CPU := NONE
ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
CPU := X86
ifeq ("$(BITS)", "32")
ARCH_DETECTED := 64BITS_32
PIC ?= 0
else
ARCH_DETECTED := 64BITS
PIC ?= 1
endif
endif
ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
CPU := X86
ARCH_DETECTED := 32BITS
PIC ?= 0
endif
ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","")
CPU := PPC
ARCH_DETECTED := 32BITS
BIG_ENDIAN := 1
PIC ?= 1
NO_ASM := 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
NO_ASM := 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
NO_ASM := 1
$(warning Architecture "$(HOST_CPU)" not officially supported.')
endif
endif
ifeq ("$(CPU)","NONE")
$(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
endif
# base CFLAGS, LDLIBS, and LDFLAGS
OPTFLAGS ?= -O3
WARNFLAGS ?= -Wall
CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src -I../../src/wrapper -DGCC
CXXFLAGS += -fvisibility-inlines-hidden
LDFLAGS += $(SHARED)
# default configuration programs
SDL_CONFIG = $(CROSS_COMPILE)sdl-config
PKG_CONFIG = $(CROSS_COMPILE)pkg-config
ifeq ($(CPU), X86)
CFLAGS += -msse
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
LDFLAGS += -fPIC
else
CFLAGS += -fno-PIC
LDFLAGS += -fno-PIC
endif
ifeq ($(BIG_ENDIAN), 1)
CFLAGS += -DM64P_BIG_ENDIAN
endif
# tweak flags for 32-bit build on 64-bit system
ifeq ($(ARCH_DETECTED), 64BITS_32)
ifeq ($(OS), FREEBSD)
$(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
endif
CFLAGS += -m32
LDFLAGS += -m32 -Wl,-m,elf_i386
endif
# set special flags per-system
ifeq ($(OS), LINUX)
# only export api symbols
LDFLAGS += -Wl,-version-script,$(SRCDIR)/video_api_export.ver
LDLIBS += -ldl
endif
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 += -pipe -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
LDFLAGS += -bundle -arch x86_64
LDLIBS += -ldl
else
CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
LDFLAGS += -bundle -arch i686
LDLIBS += -ldl
endif
endif
endif
ifeq ($(OS), FREEBSD)
LDLIBS += -lc
endif
# search for OpenGL libraries
GL_LIBS=
ifeq ($(OS), OSX)
GL_LIBS = -framework OpenGL
endif
ifeq ($(OS), MINGW)
GL_LIBS = -lopengl32
endif
ifeq ("$(GL_LIBS)", "")
ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
$(error $(PKG_CONFIG) not found)
endif
ifeq ($(shell $(PKG_CONFIG) --modversion gl 2>/dev/null),)
$(error No OpenGL development libraries found!)
endif
CFLAGS += $(shell $(PKG_CONFIG) --cflags gl)
GL_LIBS = $(shell $(PKG_CONFIG) --libs gl)
endif
LDLIBS += $(GL_LIBS)
# test for presence of SDL
ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),)
$(error No SDL development libraries found!)
endif
ifeq ($(OS),FREEBSD)
CFLAGS += $(shell $(SDL_CONFIG) --cflags)
LDLIBS += $(shell $(SDL_CONFIG) --libs)
endif
ifeq ($(OS),OSX)
CFLAGS += $(shell $(SDL_CONFIG) --cflags)
# sdl-config on mac screws up when we're trying to build a library and not an executable
# SDL 1.3 is supposed to fix that, if it's ever released
LDLIBS += -L/usr/local/lib -lSDL -Wl,-framework,Cocoa
endif
ifeq ($(OS),LINUX)
CFLAGS += $(shell $(SDL_CONFIG) --cflags)
LDLIBS += $(shell $(SDL_CONFIG) --libs)
endif
ifeq ($(OS), MINGW)
CFLAGS += $(shell $(SDL_CONFIG) --cflags)
LDLIBS += $(shell $(SDL_CONFIG) --libs)
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)
else
$(error Mupen64Plus API header files not found! Use makefile parameter APIDIR to force a location.)
endif
endif
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) $(LDFLAGS) $(TARGET_ARCH)
# set special flags for given Makefile parameters
ifeq ($(DEBUG),1)
CFLAGS += -g
INSTALL_STRIP_FLAG ?=
else
INSTALL_STRIP_FLAG ?= -s
endif
ifeq ($(NO_ASM), 1)
CFLAGS += -DNO_ASM
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)/3dmath.cpp \
$(SRCDIR)/CRC.cpp \
$(SRCDIR)/Combine.cpp \
$(SRCDIR)/Config.cpp \
$(SRCDIR)/Debugger.cpp \
$(SRCDIR)/DepthBufferRender.cpp \
$(SRCDIR)/Ini.cpp \
$(SRCDIR)/Main.cpp \
$(SRCDIR)/TexBuffer.cpp \
$(SRCDIR)/TexCache.cpp \
$(SRCDIR)/Util.cpp \
$(SRCDIR)/rdp.cpp \
$(SRCDIR)/wrapper/2xsai.cpp \
$(SRCDIR)/wrapper/combiner.cpp \
$(SRCDIR)/wrapper/config.cpp \
$(SRCDIR)/wrapper/filter.cpp \
$(SRCDIR)/wrapper/geometry.cpp \
$(SRCDIR)/wrapper/hq2x.cpp \
$(SRCDIR)/wrapper/hq4x.cpp \
$(SRCDIR)/wrapper/main.cpp \
$(SRCDIR)/wrapper/textures.cpp
ifeq ($(OS),MINGW)
SOURCE += $(SRCDIR)/osal_dynamiclib_win32.c
else
SOURCE += $(SRCDIR)/osal_dynamiclib_unix.c
endif
# generate a list of object files build, make a temporary directory for them
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(filter %.c, $(SOURCE)))
OBJECTS += $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SOURCE)))
OBJDIRS = $(dir $(OBJECTS))
$(shell $(MKDIR) $(OBJDIRS))
# build targets
TARGET = mupen64plus-video-glide64$(POSTFIX).$(SO_EXTENSION)
targets:
@echo "Mupen64plus-video-glide64 N64 Graphics plugin makefile. "
@echo " Targets:"
@echo " all == Build Mupen64plus-video-glide64 plugin"
@echo " clean == remove object files"
@echo " rebuild == clean and re-build all"
@echo " install == Install Mupen64Plus-video-glide64 plugin"
@echo " uninstall == Uninstall Mupen64Plus-video-glide64 plugin"
@echo " Options:"
@echo " BITS=32 == build 32-bit binaries on 64-bit machine"
@echo " NO_ASM=1 == build without inline assembly code (x86 MMX/SSE)"
@echo " APIDIR=path == path to find Mupen64Plus Core headers"
@echo " OPTFLAGS=flag == compiler optimization (default: -O3)"
@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 " SHAREDIR=path == path to install shared data files (default: PREFIX/share/mupen64plus)"
@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 " LTO=1 == enable experimental build with link-time optimization"
@echo " V=1 == show verbose compiler output"
all: $(TARGET)
install: $(TARGET)
$(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
$(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
$(INSTALL) -d "$(DESTDIR)$(SHAREDIR)"
$(INSTALL) -m 0644 "../../data/Glide64.ini" "$(DESTDIR)$(SHAREDIR)"
uninstall:
$(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
$(RM) "$(DESTDIR)$(SHAREDIR)/Glide64.ini"
clean:
$(RM) -r $(OBJDIR) $(TARGET)
rebuild: clean all
# build dependency files
CFLAGS += -MD
-include $(OBJECTS:.o=.d)
CXXFLAGS += $(CFLAGS)
ifeq ($(LTO), 1)
CFLAGS += -flto -ffunction-sections -fdata-sections
CXXFLAGS += -flto -ffunction-sections -fdata-sections
LDFLAGS += -fuse-linker-plugin -Wl,--gc-sections $(CXXFLAGS)
endif
# 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

View File

@ -0,0 +1,394 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_types.h"
#include "m64p_plugin.h"
#include "m64p_config.h"
#include "m64p_vidext.h"
#include "3dmath.h"
#if !defined(NO_ASM)
#include <xmmintrin.h>
#endif
void calc_light (VERTEX *v)
{
float light_intensity = 0.0f;
register float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b};
for (DWORD l=0; l<rdp.num_lights; l++)
{
light_intensity = DotProduct (rdp.light_vector[l], v->vec);
if (light_intensity > 0.0f)
{
color[0] += rdp.light[l].r * light_intensity;
color[1] += rdp.light[l].g * light_intensity;
color[2] += rdp.light[l].b * light_intensity;
}
}
if (color[0] > 1.0f) color[0] = 1.0f;
if (color[1] > 1.0f) color[1] = 1.0f;
if (color[2] > 1.0f) color[2] = 1.0f;
v->r = (BYTE)(color[0]*255.0f);
v->g = (BYTE)(color[1]*255.0f);
v->b = (BYTE)(color[2]*255.0f);
}
__inline void TransformVector (float *src, float *dst, float mat[4][4])
{
dst[0] = mat[0][0]*src[0] + mat[1][0]*src[1] + mat[2][0]*src[2];
dst[1] = mat[0][1]*src[0] + mat[1][1]*src[1] + mat[2][1]*src[2];
dst[2] = mat[0][2]*src[0] + mat[1][2]*src[1] + mat[2][2]*src[2];
}
//*
void calc_linear (VERTEX *v)
{
float vec[3];
TransformVector (v->vec, vec, rdp.model);
// TransformVector (v->vec, vec, rdp.combined);
NormalizeVector (vec);
float x, y;
if (!rdp.use_lookat)
{
x = vec[0];
y = vec[1];
}
else
{
x = DotProduct (rdp.lookat[0], vec);
y = DotProduct (rdp.lookat[1], vec);
}
if (rdp.cur_cache[0])
{
// scale >> 6 is size to map to
v->ou = (acosf(x)/3.1415f) * (rdp.tiles[rdp.cur_tile].org_s_scale >> 6);
v->ov = (acosf(y)/3.1415f) * (rdp.tiles[rdp.cur_tile].org_t_scale >> 6);
}
}
//*/
/*
void calc_linear (VERTEX *v)
{
float vec[3];
TransformVector (v->vec, vec, rdp.combined);
NormalizeVector (vec);
if (rdp.cur_cache[0])
{
// scale >> 6 is size to map to
v->ou = (acosf(vec[0])/3.1415f) * (rdp.tiles[rdp.cur_tile].org_s_scale >> 6);
v->ov = (acosf(vec[1])/3.1415f) * (rdp.tiles[rdp.cur_tile].org_t_scale >> 6);
}
}
//*/
void calc_sphere (VERTEX *v)
{
//RDP("calc_sphere\n");
float vec[3];
int s_scale, t_scale;
if (settings.chopper)
{
s_scale = min(rdp.tiles[rdp.cur_tile].org_s_scale >> 6, rdp.tiles[rdp.cur_tile].lr_s);
t_scale = min(rdp.tiles[rdp.cur_tile].org_t_scale >> 6, rdp.tiles[rdp.cur_tile].lr_t);
}
else
{
s_scale = rdp.tiles[rdp.cur_tile].org_s_scale >> 6;
t_scale = rdp.tiles[rdp.cur_tile].org_t_scale >> 6;
}
TransformVector (v->vec, vec, rdp.model);
// TransformVector (v->vec, vec, rdp.combined);
NormalizeVector (vec);
float x = DotProduct (rdp.lookat[0], vec);
float y = DotProduct (rdp.lookat[1], vec);
v->ou = (x * 0.5f + 0.5f) * s_scale;
v->ov = (y * 0.5f + 0.5f) * t_scale;
}
void __stdcall MulMatricesNOSSE(float m1[4][4],float m2[4][4],float r[4][4])
{
/*for (int i=0; i<4; i++)
{
for (int j=0; j<4; j++)
{
r[i][j] =
m1[i][0] * m2[0][j] +
m1[i][1] * m2[1][j] +
m1[i][2] * m2[2][j] +
m1[i][3] * m2[3][j];
}
}*/
r[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0] + m1[0][3]*m2[3][0];
r[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1] + m1[0][3]*m2[3][1];
r[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2] + m1[0][3]*m2[3][2];
r[0][3] = m1[0][0]*m2[0][3] + m1[0][1]*m2[1][3] + m1[0][2]*m2[2][3] + m1[0][3]*m2[3][3];
r[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0] + m1[1][3]*m2[3][0];
r[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1] + m1[1][3]*m2[3][1];
r[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2] + m1[1][3]*m2[3][2];
r[1][3] = m1[1][0]*m2[0][3] + m1[1][1]*m2[1][3] + m1[1][2]*m2[2][3] + m1[1][3]*m2[3][3];
r[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0] + m1[2][3]*m2[3][0];
r[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1] + m1[2][3]*m2[3][1];
r[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2] + m1[2][3]*m2[3][2];
r[2][3] = m1[2][0]*m2[0][3] + m1[2][1]*m2[1][3] + m1[2][2]*m2[2][3] + m1[2][3]*m2[3][3];
r[3][0] = m1[3][0]*m2[0][0] + m1[3][1]*m2[1][0] + m1[3][2]*m2[2][0] + m1[3][3]*m2[3][0];
r[3][1] = m1[3][0]*m2[0][1] + m1[3][1]*m2[1][1] + m1[3][2]*m2[2][1] + m1[3][3]*m2[3][1];
r[3][2] = m1[3][0]*m2[0][2] + m1[3][1]*m2[1][2] + m1[3][2]*m2[2][2] + m1[3][3]*m2[3][2];
r[3][3] = m1[3][0]*m2[0][3] + m1[3][1]*m2[1][3] + m1[3][2]*m2[2][3] + m1[3][3]*m2[3][3];
}
void __stdcall MulMatricesSSE(float m1[4][4],float m2[4][4],float r[4][4])
{
#if defined(__GNUC__) && !defined(NO_ASM)
/* [row][col]*/
typedef float v4sf __attribute__ ((vector_size (16)));
v4sf row0 = __builtin_ia32_loadups(m2[0]);
v4sf row1 = __builtin_ia32_loadups(m2[1]);
v4sf row2 = __builtin_ia32_loadups(m2[2]);
v4sf row3 = __builtin_ia32_loadups(m2[3]);
for (int i = 0; i < 4; ++i)
{
v4sf leftrow = __builtin_ia32_loadups(m1[i]);
// Fill tmp with four copies of leftrow[0]
v4sf tmp = leftrow;
tmp = _mm_shuffle_ps (tmp, tmp, 0);
// Calculate the four first summands
v4sf destrow = tmp * row0;
// Fill tmp with four copies of leftrow[1]
tmp = leftrow;
tmp = _mm_shuffle_ps (tmp, tmp, 1 + (1 << 2) + (1 << 4) + (1 << 6));
destrow += tmp * row1;
// Fill tmp with four copies of leftrow[2]
tmp = leftrow;
tmp = _mm_shuffle_ps (tmp, tmp, 2 + (2 << 2) + (2 << 4) + (2 << 6));
destrow += tmp * row2;
// Fill tmp with four copies of leftrow[3]
tmp = leftrow;
tmp = _mm_shuffle_ps (tmp, tmp, 3 + (3 << 2) + (3 << 4) + (3 << 6));
destrow += tmp * row3;
__builtin_ia32_storeups(r[i], destrow);
}
#elif !defined(NO_ASM)
__asm
{
mov eax, dword ptr [r]
mov ecx, dword ptr [m1]
mov edx, dword ptr [m2]
movaps xmm0,[edx]
movaps xmm1,[edx+16]
movaps xmm2,[edx+32]
movaps xmm3,[edx+48]
// r[0][0],r[0][1],r[0][2],r[0][3]
movaps xmm4,xmmword ptr[ecx]
movaps xmm5,xmm4
movaps xmm6,xmm4
movaps xmm7,xmm4
shufps xmm4,xmm4,00000000b
shufps xmm5,xmm5,01010101b
shufps xmm6,xmm6,10101010b
shufps xmm7,xmm7,11111111b
mulps xmm4,xmm0
mulps xmm5,xmm1
mulps xmm6,xmm2
mulps xmm7,xmm3
addps xmm4,xmm5
addps xmm4,xmm6
addps xmm4,xmm7
movaps xmmword ptr[eax],xmm4
// r[1][0],r[1][1],r[1][2],r[1][3]
movaps xmm4,xmmword ptr[ecx+16]
movaps xmm5,xmm4
movaps xmm6,xmm4
movaps xmm7,xmm4
shufps xmm4,xmm4,00000000b
shufps xmm5,xmm5,01010101b
shufps xmm6,xmm6,10101010b
shufps xmm7,xmm7,11111111b
mulps xmm4,xmm0
mulps xmm5,xmm1
mulps xmm6,xmm2
mulps xmm7,xmm3
addps xmm4,xmm5
addps xmm4,xmm6
addps xmm4,xmm7
movaps xmmword ptr[eax+16],xmm4
// r[2][0],r[2][1],r[2][2],r[2][3]
movaps xmm4,xmmword ptr[ecx+32]
movaps xmm5,xmm4
movaps xmm6,xmm4
movaps xmm7,xmm4
shufps xmm4,xmm4,00000000b
shufps xmm5,xmm5,01010101b
shufps xmm6,xmm6,10101010b
shufps xmm7,xmm7,11111111b
mulps xmm4,xmm0
mulps xmm5,xmm1
mulps xmm6,xmm2
mulps xmm7,xmm3
addps xmm4,xmm5
addps xmm4,xmm6
addps xmm4,xmm7
movaps xmmword ptr[eax+32],xmm4
// r[3][0],r[3][1],r[3][2],r[3][3]
movaps xmm4,xmmword ptr[ecx+48]
movaps xmm5,xmm4
movaps xmm6,xmm4
movaps xmm7,xmm4
shufps xmm4,xmm4,00000000b
shufps xmm5,xmm5,01010101b
shufps xmm6,xmm6,10101010b
shufps xmm7,xmm7,11111111b
mulps xmm4,xmm0
mulps xmm5,xmm1
mulps xmm6,xmm2
mulps xmm7,xmm3
addps xmm4,xmm5
addps xmm4,xmm6
addps xmm4,xmm7
movaps xmmword ptr[eax+48],xmm4
}
#endif // _WIN32
}
MULMATRIX MulMatrices = MulMatricesNOSSE;
void math_init()
{
BOOL IsSSE = FALSE;
#if defined(__GNUC__) && !defined(NO_ASM)
int edx, eax;
#if defined(__x86_64__)
asm volatile(" cpuid; "
: "=a"(eax), "=d"(edx)
: "0"(1)
: "rbx", "rcx"
);
#else
asm volatile(" push %%ebx; "
" push %%ecx; "
" cpuid; "
" pop %%ecx; "
" pop %%ebx; "
: "=a"(eax), "=d"(edx)
: "0"(1)
:
);
#endif
// Check for SSE
if (edx & (1 << 25))
IsSSE = TRUE;
#elif !defined(NO_ASM)
DWORD dwEdx;
__try
{
__asm
{
mov eax,1
cpuid
mov dwEdx,edx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return;
}
if (dwEdx & (1<<25))
{
if (dwEdx & (1<<24))
{
__try
{
__asm xorps xmm0, xmm0
IsSSE = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return;
}
}
}
#endif // _WIN32
if (IsSSE)
{
MulMatrices = MulMatricesSSE;
WriteLog(M64MSG_INFO, "SSE detected.\n");
}
}

View File

@ -0,0 +1,74 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#include <math.h>
#include "rdp.h"
#include "m64p.h"
__inline float DotProduct(register float *v1, register float *v2)
{
register float result;
result = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
return(result);
}
__inline void NormalizeVector(float *v)
{
register float len;
len = sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
if (len > 0.0f)
{
v[0] /= len;
v[1] /= len;
v[2] /= len;
}
}
__inline void InverseTransformVector (float *src, float *dst, float mat[4][4])
{
dst[0] = mat[0][0]*src[0] + mat[0][1]*src[1] + mat[0][2]*src[2];
dst[1] = mat[1][0]*src[0] + mat[1][1]*src[1] + mat[1][2]*src[2];
dst[2] = mat[2][0]*src[0] + mat[2][1]*src[1] + mat[2][2]*src[2];
}
void calc_light (VERTEX *v);
void calc_linear (VERTEX *v);
void calc_sphere (VERTEX *v);
void math_init();
typedef void (__stdcall *MULMATRIX)(float m1[4][4],float m2[4][4],float r[4][4]);
extern MULMATRIX MulMatrices;

View File

@ -0,0 +1,7 @@
Dave2001
Gonetz
Gugaman
Hacktarux
Josh
Ziggy
Günther

View File

@ -0,0 +1,77 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// CRC32 calculation functions
//
// Created by Gonetz, 2004
//
//****************************************************************
#include "CRC.h"
#define CRC32_POLYNOMIAL 0x04C11DB7
unsigned int CRCTable[ 256 ];
unsigned int Reflect( unsigned long ref, char ch )
{
unsigned int value = 0;
// Swap bit 0 for bit 7
// bit 1 for bit 6, etc.
for (char i = 1; i < (ch + 1); i++)
{
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
}
return value;
}
void CRC_BuildTable()
{
unsigned int crc;
for (unsigned i = 0; i <= 255; i++)
{
crc = Reflect( i, 8 ) << 24;
for (unsigned j = 0; j < 8; j++)
crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
CRCTable[i] = Reflect( crc, 32 );
}
}

View File

@ -0,0 +1,91 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// CRC32 calculation functions
//
// Created by Gonetz, 2004
//
//****************************************************************
#if !defined(WIN32) && defined(GCC)
#define Crc32 _Crc32
#define CRCTable _CRCTable
#endif
extern unsigned int CRCTable[ 256 ];
void CRC_BuildTable();
inline unsigned int CRC_Calculate( unsigned int crc, const void *buffer, unsigned int count )
{
#if !defined(__GNUC__) && !defined(NO_ASM)
unsigned int Crc32=crc;
__asm {
mov esi, buffer
mov edx, count
add edx, esi
mov ecx, crc
loop1:
mov bl, byte ptr [esi]
movzx eax, cl
inc esi
xor al, bl
shr ecx, 8
mov ebx, [CRCTable+eax*4]
xor ecx, ebx
cmp edx, esi
jne loop1
xor Crc32, ecx
}
return Crc32;
#else
unsigned int result = crc;
for (const char * p = (const char*)buffer; p != (const char*)buffer + count; ++p)
{
unsigned char al = result;
al ^= *p;
result >>= 8;
result ^= CRCTable[al];
}
result ^= crc;
return result;
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,118 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#ifndef COMBINE_H
#define COMBINE_H
#include "Gfx1.3.h"
// texture MOD types
#define TMOD_TEX_INTER_COLOR_USING_FACTOR 1
#define TMOD_TEX_INTER_COL_USING_COL1 2
#define TMOD_FULL_COLOR_SUB_TEX 3
#define TMOD_COL_INTER_COL1_USING_TEX 4
#define TMOD_COL_INTER_COL1_USING_TEXA 5
#define TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX 6
#define TMOD_COL_INTER_TEX_USING_TEXA 7
#define TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA 8
#define TMOD_TEX_SCALE_FAC_ADD_FAC 9
#define TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX 10
#define TMOD_TEX_SCALE_COL_ADD_COL 11
#define TMOD_TEX_ADD_COL 12
#define TMOD_TEX_SUB_COL 13
#define TMOD_TEX_SUB_COL_MUL_FAC 14
#define TMOD_COL_INTER_TEX_USING_COL1 15
#define TMOD_COL_MUL_TEXA_ADD_TEX 16
#define TMOD_COL_INTER_TEX_USING_TEX 17
#define TMOD_TEX_INTER_NOISE_USING_COL 18
#define TMOD_TEX_INTER_COL_USING_TEXA 19
#define TMOD_TEX_MUL_COL 20
#define TMOD_TEX_SCALE_FAC_ADD_COL 21
#define COMBINE_EXT_COLOR 1
#define COMBINE_EXT_ALPHA 2
#define TEX_COMBINE_EXT_COLOR 1
#define TEX_COMBINE_EXT_ALPHA 2
typedef struct
{
DWORD ccolor; // constant color to set at the end, color and alpha
DWORD c_fnc, c_fac, c_loc, c_oth; // grColorCombine flags
DWORD a_fnc, a_fac, a_loc, a_oth; // grAlphaCombine flags
DWORD tex, tmu0_func, tmu0_fac, tmu0_invert, tmu1_func, tmu1_fac, tmu1_invert;
DWORD tmu0_a_func, tmu0_a_fac, tmu0_a_invert, tmu1_a_func, tmu1_a_fac, tmu1_a_invert;
int dc0_lodbias, dc1_lodbias;
BYTE dc0_detailscale, dc1_detailscale;
float dc0_detailmax, dc1_detailmax;
float lodbias0, lodbias1;
DWORD abf1, abf2;
DWORD mod_0, modcolor_0, modcolor1_0, modcolor2_0, modfactor_0;
DWORD mod_1, modcolor_1, modcolor1_1, modcolor2_1, modfactor_1;
//combine extensions
DWORD c_ext_a, c_ext_a_mode, c_ext_b, c_ext_b_mode, c_ext_c, c_ext_d;
BOOL c_ext_c_invert, c_ext_d_invert;
DWORD a_ext_a, a_ext_a_mode, a_ext_b, a_ext_b_mode, a_ext_c, a_ext_d;
BOOL a_ext_c_invert, a_ext_d_invert;
DWORD t0c_ext_a, t0c_ext_a_mode, t0c_ext_b, t0c_ext_b_mode, t0c_ext_c, t0c_ext_d;
BOOL t0c_ext_c_invert, t0c_ext_d_invert;
DWORD t0a_ext_a, t0a_ext_a_mode, t0a_ext_b, t0a_ext_b_mode, t0a_ext_c, t0a_ext_d;
BOOL t0a_ext_c_invert, t0a_ext_d_invert;
DWORD t1c_ext_a, t1c_ext_a_mode, t1c_ext_b, t1c_ext_b_mode, t1c_ext_c, t1c_ext_d;
BOOL t1c_ext_c_invert, t1c_ext_d_invert;
DWORD t1a_ext_a, t1a_ext_a_mode, t1a_ext_b, t1a_ext_b_mode, t1a_ext_c, t1a_ext_d;
BOOL t1a_ext_c_invert, t1a_ext_d_invert;
GRCOLORCOMBINEEXT grColorCombineExt;
GRCOLORCOMBINEEXT grAlphaCombineExt;
GRTEXCOLORCOMBINEEXT grTexColorCombineExt;
GRTEXCOLORCOMBINEEXT grTexAlphaCombineExt;
GRCONSTANTCOLORVALUEEXT grConstantColorValueExt;
DWORD tex_ccolor;
BOOL combine_ext;
BYTE cmb_ext_use;
BYTE tex_cmb_ext_use;
} COMBINE;
extern COMBINE cmb;
void Combine ();
void CombineBlender ();
void CountCombine ();
void InitCombine ();
void ColorCombinerToExtension ();
void AlphaCombinerToExtension ();
void TexColorCombinerToExtension (GrChipID_t tmu);
void TexAlphaCombinerToExtension (GrChipID_t tmu);
#endif //COMBINE _H

View File

@ -0,0 +1,68 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2010 Jon Ring
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence 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 "m64p.h"
static m64p_handle video_general_section;
static m64p_handle video_glide64_section;
BOOL Config_Open()
{
if (ConfigOpenSection("Video-General", &video_general_section) != M64ERR_SUCCESS ||
ConfigOpenSection("Video-Glide64", &video_glide64_section) != M64ERR_SUCCESS)
{
WriteLog(M64MSG_ERROR, "Could not open configuration");
return FALSE;
}
ConfigSetDefaultBool(video_general_section, "Fullscreen", false, "Use fullscreen mode if True, or windowed mode if False");
ConfigSetDefaultInt(video_general_section, "ScreenWidth", 640, "Width of output window or fullscreen width");
ConfigSetDefaultInt(video_general_section, "ScreenHeight", 480, "Height of output window or fullscreen height");
return TRUE;
}
PackedScreenResolution Config_ReadScreenSettings()
{
PackedScreenResolution packedResolution;
packedResolution.width = ConfigGetParamInt(video_general_section, "ScreenWidth");
packedResolution.height = ConfigGetParamInt(video_general_section, "ScreenHeight");
packedResolution.fullscreen = ConfigGetParamBool(video_general_section, "Fullscreen");
return packedResolution;
}
int Config_ReadInt(const char *itemname, const char *desc, int def_value, BOOL create, BOOL isBoolean)
{
WriteLog(M64MSG_VERBOSE, "Getting value %s", itemname);
if (isBoolean)
{
ConfigSetDefaultBool(video_glide64_section, itemname, def_value, desc);
return ConfigGetParamBool(video_glide64_section, itemname);
}
else
{
ConfigSetDefaultInt(video_glide64_section, itemname, def_value, desc);
return ConfigGetParamInt(video_glide64_section, itemname);
}
}

View File

@ -0,0 +1,34 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2010 Jon Ring
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence 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 "winlnxdefs.h"
#include "m64p.h"
BOOL Config_Open();
PackedScreenResolution Config_ReadScreenSettings();
int Config_ReadInt(const char *itemname, const char *desc, int def_value, BOOL create=TRUE, BOOL isBoolean=TRUE);
#endif /* CONFIG_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#define SELECTED_NONE 0x00000000
#define SELECTED_TRI 0x00000001
#define SELECTED_TEX 0x00000002
typedef struct TEX_INFO_t
{
DWORD cur_cache[2]; // Current cache #
BYTE format;
BYTE size;
DWORD width, height;
WORD line, wid;
BYTE palette;
BYTE clamp_s, clamp_t;
BYTE mirror_s, mirror_t;
BYTE mask_s, mask_t;
BYTE shift_s, shift_t;
WORD ul_s, ul_t, lr_s, lr_t;
WORD t_ul_s, t_ul_t, t_lr_s, t_lr_t;
float scale_s, scale_t;
int tmu;
} TEX_INFO;
typedef struct TRI_INFO_t
{
DWORD nv; // Number of vertices
VERTEX *v; // Vertices (2d screen coords) of the triangle, used to outline
DWORD cycle1, cycle2, cycle_mode; // Combine mode at the time of rendering
BYTE uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both
DWORD geom_mode; // geometry mode flags
DWORD othermode_h; // setothermode_h flags
DWORD othermode_l; // setothermode_l flags
DWORD tri_n; // Triangle number
DWORD flags;
int type; // 0-normal, 1-texrect, 2-fillrect
// texture info
TEX_INFO t[2];
// colors
DWORD fog_color;
DWORD fill_color;
DWORD prim_color;
DWORD blend_color;
DWORD env_color;
DWORD prim_lodmin, prim_lodfrac;
TRI_INFO_t *pNext;
} TRI_INFO;
typedef struct
{
BOOL capture; // Capture moment for debugging?
DWORD selected; // Selected object (see flags above)
TRI_INFO *tri_sel;
DWORD tex_scroll; // texture scrolling
DWORD tex_sel;
// CAPTURE INFORMATION
BYTE *screen; // Screen capture
TRI_INFO *tri_list; // Triangle information list
TRI_INFO *tri_last; // Last in the list (first in)
DWORD tmu; // tmu #
DWORD draw_mode;
// Page number
int page;
} DEBUGGER;
#define PAGE_GENERAL 0
#define PAGE_TEX1 1
#define PAGE_TEX2 2
#define PAGE_COLORS 3
#define PAGE_FBL 4
#define PAGE_OTHERMODE_L 5
#define PAGE_OTHERMODE_H 6
#define PAGE_TEXELS 7
#define PAGE_COORDS 8
#define PAGE_TEX_INFO 9
#define TRI_TRIANGLE 0
#define TRI_TEXRECT 1
#define TRI_FILLRECT 2
#define TRI_BACKGROUND 3
#ifdef _WIN32
static char *tri_type[4] = { "TRIANGLE", "TEXRECT", "FILLRECT", "BACKGROUND" };
#endif // _WIN32
extern DEBUGGER debug;
void debug_init ();
void debug_capture ();
void debug_cacheviewer ();
void debug_mouse ();
void debug_keys ();
void output (float x, float y, BOOL scale, const char *fmt, ...);

View File

@ -0,0 +1,353 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
//****************************************************************
//
// Software rendering into N64 depth buffer
// Idea and N64 depth value format by Orkin
// Polygon rasterization algorithm is taken from FATMAP2 engine by Mats Byggmastar, mri@penti.sit.fi
//
// Created by Gonetz, Dec 2004
//
//****************************************************************
#include "Gfx1.3.h"
#include "rdp.h"
#include "DepthBufferRender.h"
WORD * zLUT = 0;
void ZLUT_init()
{
if (zLUT)
return;
zLUT = new WORD[0x40000];
for(int i=0; i<0x40000; i++)
{
DWORD exponent = 0;
DWORD testbit = 1 << 17;
while((i & testbit) && (exponent < 7))
{
exponent++;
testbit = 1 << (17 - exponent);
}
DWORD mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff;
zLUT[i] = (WORD)(((exponent << 11) | mantissa) << 2);
}
/*
for(i=0; i<0x40000; i++)
{
int j = i + 1;
WORD z = zLUT[i];
while (zLUT[i] == zLUT[j])
j++;
int w = (j - i) >> 2;
if (w > 0)
{
int k;
for (k = 1; k < 4; k++)
for (int t = 0; t < w; t++)
zLUT[i+k*w+t] = z + k;
i = j - 1;
}
}
*/
}
void ZLUT_release()
{
delete[] zLUT;
zLUT = 0;
}
static vertexi * max_vtx; // Max y vertex (ending vertex)
static vertexi * start_vtx, * end_vtx; // First and last vertex in array
static vertexi * right_vtx, * left_vtx; // Current right and left vertex
static int right_height, left_height;
static int right_x, right_dxdy, left_x, left_dxdy;
static int left_z, left_dzdy;
__inline int iceil(int x)
{
x += 0xffff;
return (x >> 16);
}
__inline int imul16(int x, int y) // (x * y) >> 16
{
return (((long long)x) * ((long long)y)) >> 16;
}
__inline int imul14(int x, int y) // (x * y) >> 14
{
return (((long long)x) * ((long long)y)) >> 14;
}
/*
int idiv16(int x, int y); // (x << 16) / y
#pragma aux idiv16 = \
" mov edx,eax "\
" sar edx,16 "\
" shl eax,16 "\
" idiv ebx "\
parm [eax] [ebx] modify exact [eax edx] value [eax]
*/
__inline int idiv16(int x, int y) // (x << 16) / y
{
//x = (((long long)x) << 16) / ((long long)y);
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov eax, x
mov ebx, y
mov edx,eax
sar edx,16
shl eax,16
idiv ebx
mov x, eax
}
#elif !defined(NO_ASM)
int reminder;
asm ("idivl %[divisor]"
: "=a" (x), "=d" (reminder)
: [divisor] "g" (y), "d" (x >> 16), "a" (x << 16));
#endif
return x;
}
static void RightSection(void)
{
// Walk backwards trough the vertex array
vertexi * v2, * v1 = right_vtx;
if(right_vtx > start_vtx) v2 = right_vtx-1;
else v2 = end_vtx; // Wrap to end of array
right_vtx = v2;
// v1 = top vertex
// v2 = bottom vertex
// Calculate number of scanlines in this section
right_height = iceil(v2->y) - iceil(v1->y);
if(right_height <= 0) return;
// Guard against possible div overflows
if(right_height > 1) {
// OK, no worries, we have a section that is at least
// one pixel high. Calculate slope as usual.
int height = v2->y - v1->y;
right_dxdy = idiv16(v2->x - v1->x, height);
}
else {
// Height is less or equal to one pixel.
// Calculate slope = width * 1/height
// using 18:14 bit precision to avoid overflows.
int inv_height = (0x10000 << 14) / (v2->y - v1->y);
right_dxdy = imul14(v2->x - v1->x, inv_height);
}
// Prestep initial values
int prestep = (iceil(v1->y) << 16) - v1->y;
right_x = v1->x + imul16(prestep, right_dxdy);
}
static void LeftSection(void)
{
// Walk forward trough the vertex array
vertexi * v2, * v1 = left_vtx;
if(left_vtx < end_vtx) v2 = left_vtx+1;
else v2 = start_vtx; // Wrap to start of array
left_vtx = v2;
// v1 = top vertex
// v2 = bottom vertex
// Calculate number of scanlines in this section
left_height = iceil(v2->y) - iceil(v1->y);
if(left_height <= 0) return;
// Guard against possible div overflows
if(left_height > 1) {
// OK, no worries, we have a section that is at least
// one pixel high. Calculate slope as usual.
int height = v2->y - v1->y;
left_dxdy = idiv16(v2->x - v1->x, height);
left_dzdy = idiv16(v2->z - v1->z, height);
}
else {
// Height is less or equal to one pixel.
// Calculate slope = width * 1/height
// using 18:14 bit precision to avoid overflows.
int inv_height = (0x10000 << 14) / (v2->y - v1->y);
left_dxdy = imul14(v2->x - v1->x, inv_height);
left_dzdy = imul14(v2->z - v1->z, inv_height);
}
// Prestep initial values
int prestep = (iceil(v1->y) << 16) - v1->y;
left_x = v1->x + imul16(prestep, left_dxdy);
left_z = v1->z + imul16(prestep, left_dzdy);
}
void Rasterize(vertexi * vtx, int vertices, int dzdx)
{
start_vtx = vtx; // First vertex in array
// Search trough the vtx array to find min y, max y
// and the location of these structures.
vertexi * min_vtx = vtx;
max_vtx = vtx;
int min_y = vtx->y;
int max_y = vtx->y;
vtx++;
for(int n=1; n<vertices; n++) {
if(vtx->y < min_y) {
min_y = vtx->y;
min_vtx = vtx;
}
else
if(vtx->y > max_y) {
max_y = vtx->y;
max_vtx = vtx;
}
vtx++;
}
// OK, now we know where in the array we should start and
// where to end while scanning the edges of the polygon
left_vtx = min_vtx; // Left side starting vertex
right_vtx = min_vtx; // Right side starting vertex
end_vtx = vtx-1; // Last vertex in array
// Search for the first usable right section
do {
if(right_vtx == max_vtx) return;
RightSection();
} while(right_height <= 0);
// Search for the first usable left section
do {
if(left_vtx == max_vtx) return;
LeftSection();
} while(left_height <= 0);
WORD * destptr = (WORD*)(gfx.RDRAM+rdp.zimg);
int y1 = iceil(min_y);
int shift;
//destptr += iceil(min_y) * rdp.zi_width;
for(;;)
{
int x1 = iceil(left_x);
int width = iceil(right_x) - x1;
if(width > 0) {
// Prestep initial color intensity i
if (y1 >= rdp.zi_lry) return;
//if (x1+width > rdp.zi_lrx) width = rdp.zi_lrx-x1;
int prestep = (x1 << 16) - left_x;
int z = left_z + imul16(prestep, dzdx);
// if (y1 > max_y) return;
// FRDP("Depth render. x1: %d, y1: %d, width: %d\n", x1, y1, width);
shift = x1 + y1*rdp.zi_width;
// if (shift + width > rdp.zi_nb_pixels)
// return;
//draw to depth buffer
int trueZ;
int idx;
WORD encodedZ;
for (int x = 0; x < width; x++)
{
trueZ = z/8192;
if (trueZ < 0) trueZ = 0;
else if (trueZ > 0x3FFFF) trueZ = 0x3FFFF;
encodedZ = zLUT[trueZ];
idx = (shift+x)^1;
if(encodedZ < destptr[idx])
destptr[idx] = encodedZ;
z += dzdx;
}
}
//destptr += rdp.zi_width;
y1++;
// Scan the right side
if(--right_height <= 0) { // End of this section?
do {
if(right_vtx == max_vtx) return;
RightSection();
} while(right_height <= 0);
}
else
right_x += right_dxdy;
// Scan the left side
if(--left_height <= 0) { // End of this section?
do {
if(left_vtx == max_vtx) return;
LeftSection();
} while(left_height <= 0);
}
else {
left_x += left_dxdy;
left_z += left_dzdy;
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
//****************************************************************
//
// Created by Gonetz, Dec 2004
//
//****************************************************************
#ifndef DEPTH_BUFFER_RENDER_H
#define DEPTH_BUFFER_RENDER_H
struct vertexi
{
long x,y; // Screen position in 16:16 bit fixed point
long z; // z value in 16:16 bit fixed point
};
extern WORD * zLUT;
void ZLUT_init();
void ZLUT_release();
void Rasterize(vertexi * vtx, int vertices, int dzdx);
#endif //DEPTH_BUFFER_RENDER_H

View File

@ -0,0 +1,783 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
// ** NOTE: this file has been modified from it's original version, which can be
// downloaded along with Project64 **
/**********************************************************************************
Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com)
All questions or suggestions should go through the mailing list.
http://www.egroups.com/group/Plugin64-Dev
***********************************************************************************
Notes:
------
Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which
are both passed to the DLL in InitiateGFX will generate an Interrupt from with in
the plugin.
The Setting of the RSP flags and generating an SP interrupt should not be done in
the plugin
**********************************************************************************/
// THIS FILE IS A PRECOMPILED HEADER TO DECREASE BUILD TIME. INCLUDE ALL STANDARD
// .H FILES HERE
#ifndef _GFX_H_INCLUDED__
#define _GFX_H_INCLUDED__
#include "m64p.h"
#if defined(WIN32) && defined(GCC)
// ZIGGY ARRRRGG what a pain in the #$@$
//# include "Gfx #1.3-mangling.h"
#ifdef GCC
#include <stdio.h>
//#define printf(...)
#endif
#endif
#define _WIN32_WINNT 0x0400
#ifdef _WIN32
#include <windows.h>
#else // _WIN32
#include "winlnxdefs.h"
#endif // _WIN32
#include <stdio.h>
#include <ostream>
#include <fstream>
#include <cstddef> // offsetof
#ifndef _WIN32
#include <cmath>
#endif
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#include <mmsystem.h>
#include <commctrl.h>
#endif // _WIN32
#include <time.h>
#include <glide.h>
#include <g3ext.h>
#include "rdp.h"
#if defined(__cplusplus)
extern "C" {
#endif
// tooltips have an error on debug mode, this can be overcome by clicking ignore,
// but I'd rather just disable tooltips altogether since nobody else should
// have the debug version anyway.
#ifndef _DEBUG
//#ifndef __INTEL_COMPILER // tooltips don't work with intel compiler
#define USE_TOOLTIPS
//#endif
#endif
#ifndef VPDEBUG
# define _FINAL_RELEASE_
#endif
// #ifdef WIN32
// # define _FINAL_RELEASE_
// #else
// //# define _FINAL_RELEASE_
// #endif
//********
// Logging
// ********************************
// ** TAKE OUT BEFORE RELEASE!!! **
//#define LOGGING // log of spec functions called
//#define LOG_KEY // says "Key!!!" in the log when space bar is pressed
//#define LOG_UCODE
//#define ALTTAB_FIX
//#define EXTREME_LOGGING // lots of logging
// note that some of these things are inserted/removed
// from within the code & may not be changed by this define.
//#define TLUT_LOGGING // log every entry of the TLUT?
// ********************************
#define FPS // fps counter able? (not enabled necessarily)
#define LOGNOTKEY // Log if not pressing:
#ifdef WIN32
#define LOGKEY VK_LCONTROL // this key
#else
#include <SDL.h>
#define LOGKEY KMOD_LCTRL
inline int GetAsyncKeyState(int key) {
return (SDL_GetModState() & key) != 0;
}
#endif
#define LOG_COMMANDS // log the whole 64-bit command as (0x........, 0x........)
#define CATCH_EXCEPTIONS // catch exceptions so it doesn't freeze and will report
// "The gfx plugin has caused an exception" instead.
#define FLUSH // flush the file buffer. slower logging, but makes sure
// the command is logged before continuing (in case of
// crash or exception, the log will not be cut short)
#ifndef _FINAL_RELEASE_
#define RDP_LOGGING // Allow logging (will not log unless checked, but allows the option)
// Logging functions will not be compiled if this is not present.
//#define RDP_ERROR_LOG
#endif
#define FPS_FRAMES 10 // Number of frames in which to make an FPS count
//#define SHOW_FULL_TEXVIEWER // shows the entire contents of the texture in the cache viewer,
// usually used to debug clamping issues.
// Usually enabled
#define LARGE_TEXTURE_HANDLING // allow large-textured objects to be split?
#ifdef ALTTAB_FIX
extern HHOOK hhkLowLevelKybd;
extern LRESULT CALLBACK LowLevelKeyboardProc(int nCode,
WPARAM wParam, LPARAM lParam);
#endif
// Simulations
//#define SIMULATE_VOODOO1
//#define SIMULATE_BANSHEE
//********
#ifdef EXT_LOGGING
extern std::ofstream extlog;
#define EXT(x) extlog.open("ext.txt",ios::app); extlog << x; extlog.close();
#else
#define EXT(x)
#endif
#ifndef _FINAL_RELEASE_
#define UNIMP_LOG // Keep enabled, option in dialog
#define BRIGHT_RED // Keep enabled, option in dialog
#endif
#define COLORED_DEBUGGER // ;) pretty colors
#ifdef FPS
extern LARGE_INTEGER perf_freq;
extern LARGE_INTEGER fps_last;
extern LARGE_INTEGER fps_next;
extern float fps;
extern DWORD fps_count;
#endif
// rdram mask at 0x400000 bytes (bah, not right for majora's mask)
//#define BMASK 0x7FFFFF
extern unsigned long BMASK;
#define WMASK 0x3FFFFF
#define DMASK 0x1FFFFF
extern int num_tmu;
extern int max_tex_size;
extern long sup_mirroring;
extern BOOL sup_32bit_tex;
extern DWORD update_screen_count;
extern DWORD resolutions[0x18][2];
//#define PERFORMANCE
#ifdef PERFORMANCE
extern __int64 perf_cur;
extern __int64 perf_next;
#endif
#ifdef LOGGING
extern std::ofstream loga;
#define LOG(x) loga.open("log.txt",ios::app); loga << x; loga.flush(); loga.close();
#else
#define LOG(x) WriteLog(M64MSG_VERBOSE, "%s", x);
#endif
#ifdef RDP_LOGGING
extern int dumping;
extern BOOL log_open;
extern std::ofstream rdp_log;
//#define rdp_log std::cerr;
#define OPEN_RDP_LOG() EXT("OPEN_RDP_LOG ()\n"); if (settings.logging && !log_open) { /*rdp_log.open ("rdp.txt");*/ log_open=TRUE; }
#define CLOSE_RDP_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.logging && log_open) { /*rdp_log.close ();*/ log_open=FALSE; }
#ifdef LOGNOTKEY
#define RDP(x) EXT("RDP (...)\n"); if (dumping && settings.logging && log_open) { if (!(GetAsyncKeyState(LOGKEY)&0x8000)) { fprintf(stderr, x);/*rdp_log << x; rdp_log.flush();*/ } }
#else
#define RDP(x) EXT("RDP (...)\n"); if (dumping && settings.logging && log_open) { fprintf(stderr, x);/*rdp_log << x; rdp_log.flush();*/ }
#endif
#else
#define OPEN_RDP_LOG()
#define CLOSE_RDP_LOG()
#define RDP(x)
#endif
#ifdef RDP_ERROR_LOG
extern BOOL elog_open;
extern std::ofstream rdp_err;
//#define rdp_err std::cerr
#define OPEN_RDP_E_LOG() EXT("OPEN_RDP_E_LOG ()\n"); if (settings.elogging && !elog_open) { /*rdp_err.open ("rdp_e.txt");*/ elog_open=TRUE; }
#define CLOSE_RDP_E_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.elogging && elog_open) { /*rdp_err.close (); */elog_open=FALSE; }
#define RDP_E(x) if (dumping && settings.elogging) { FRDP_E (x); }
#else
#define OPEN_RDP_E_LOG()
#define CLOSE_RDP_E_LOG()
#define RDP_E(x)
#endif
#ifdef RDP_LOGGING
__inline void FRDP (const char *fmt, ...)
{
#ifdef RDP_LOGGING
if (!dumping || !settings.logging || !log_open) return;
#ifdef LOGNOTKEY
if (GetAsyncKeyState(LOGKEY)&0x8000) return;
#endif
va_list ap;
va_start(ap, fmt);
vsprintf(out_buf, fmt, ap);
RDP (out_buf);
va_end(ap);
#endif
}
__inline void FRDP_E (const char *fmt, ...)
{
#ifdef RDP_ERROR_LOG
if (!dumping || !settings.elogging || !elog_open) return;
#ifdef LOGNOTKEY
if (GetAsyncKeyState(LOGKEY)&0x8000) return;
#endif
sprintf (out_buf, "%08x: (%08x, %08x) ", rdp.pc[rdp.pc_i]-8, rdp.cmd0, rdp.cmd1);
rdp_err << out_buf;
va_list ap2;
va_start(ap2, fmt);
vsprintf(out_buf, fmt, ap2);
// rdp_err << out_buf;
// rdp_err.flush();
fprintf(stderr, out_buf);
va_end(ap2);
#endif
}
#else
#ifndef GCC
#define FRDP(...)
#define FRDP_E(...)
#else // _WIN32
inline void FRDP (const char *fmt, ...) {}
inline void FRDP_E (const char *fmt, ...) {}
#endif // _WIN32
#endif
extern BOOL fullscreen;
extern BOOL romopen;
extern BOOL to_fullscreen;
extern BOOL debugging;
extern HINSTANCE hInstance;
extern BOOL evoodoo;
extern BOOL ev_fullscreen;
extern BOOL exception;
extern PROPSHEETHEADER m_PropSheet;
extern PROPSHEETPAGE m_psp[3];
BOOL InitGfx (BOOL);
void ReleaseGfx ();
void DrawFrameBuffer ();
// The highest 8 bits are the segment # (1-16), and the lower 24 bits are the offset to
// add to it.
__inline DWORD segoffset (DWORD so)
{
return (rdp.segment[(so>>24)&0x0f] + (so&BMASK))&BMASK;
}
/* Plugin types */
#define PLUGIN_TYPE_GFX 2
//TODO: remove
//#define EXPORT __declspec(dllexport)
//#define CALL _cdecl
/***** Structures *****/
typedef struct {
WORD Version; /* Set to 0x0103 */
WORD Type; /* Set to PLUGIN_TYPE_GFX */
char Name[100]; /* Name of the DLL */
/* If DLL supports memory these memory options then set them to TRUE or FALSE
if it does not support it */
BOOL NormalMemory; /* a normal BYTE array */
BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre
bswap on a dword (32 bits) boundry */
} PLUGIN_INFO;
#if 0
//TODO: remove
typedef struct {
HWND hWnd; /* Render window */
HWND hStatusBar; /* if render window does not have a status bar then this is NULL */
BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
// bswap on a dword (32 bits) boundry
// eg. the first 8 bytes are stored like this:
// 4 3 2 1 8 7 6 5
BYTE * HEADER; // This is the rom header (first 40h bytes of the rom
// This will be in the same memory format as the rest of the memory.
BYTE * RDRAM;
BYTE * DMEM;
BYTE * IMEM;
DWORD * MI_INTR_REG;
DWORD * DPC_START_REG;
DWORD * DPC_END_REG;
DWORD * DPC_CURRENT_REG;
DWORD * DPC_STATUS_REG;
DWORD * DPC_CLOCK_REG;
DWORD * DPC_BUFBUSY_REG;
DWORD * DPC_PIPEBUSY_REG;
DWORD * DPC_TMEM_REG;
DWORD * VI_STATUS_REG;
DWORD * VI_ORIGIN_REG;
DWORD * VI_WIDTH_REG;
DWORD * VI_INTR_REG;
DWORD * VI_V_CURRENT_LINE_REG;
DWORD * VI_TIMING_REG;
DWORD * VI_V_SYNC_REG;
DWORD * VI_H_SYNC_REG;
DWORD * VI_LEAP_REG;
DWORD * VI_H_START_REG;
DWORD * VI_V_START_REG;
DWORD * VI_V_BURST_REG;
DWORD * VI_X_SCALE_REG;
DWORD * VI_Y_SCALE_REG;
void (*CheckInterrupts)( void );
} GFX_INFO;
#endif
extern GFX_INFO gfx;
extern BOOL no_dlist;
typedef GrContext_t (FX_CALL *GRWINOPENEXT)( FxU32 hWnd,
GrScreenResolution_t resolution,
GrScreenRefresh_t refresh,
GrColorFormat_t format,
GrOriginLocation_t origin,
GrPixelFormat_t pixelformat,
int nColBuffers,
int nAuxBuffers) ;
typedef void (FX_CALL *GRTEXBUFFEREXT)( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t lodmin,
GrLOD_t lodmax,
GrAspectRatio_t aspect,
GrTextureFormat_t fmt,
FxU32 evenOdd) ;
typedef void (FX_CALL *GRAUXBUFFEREXT)( GrBuffer_t buffer ) ;
typedef void (FX_CALL *GRCOLORCOMBINEEXT) (GrCCUColor_t a,
GrCombineMode_t a_mode,
GrCCUColor_t b,
GrCombineMode_t b_mode,
GrCCUColor_t c,
FxBool c_invert,
GrCCUColor_t d,
FxBool d_invert,
FxU32 shift,
FxBool invert) ;
typedef void (FX_CALL *GRTEXCOLORCOMBINEEXT) (GrChipID_t tmu,
GrTCCUColor_t a,
GrCombineMode_t a_mode,
GrTCCUColor_t b,
GrCombineMode_t b_mode,
GrTCCUColor_t c,
FxBool c_invert,
GrTCCUColor_t d,
FxBool d_invert,
FxU32 shift,
FxBool invert);
typedef void (FX_CALL *GRCONSTANTCOLORVALUEEXT)
(GrChipID_t tmu,
GrColor_t value);
typedef void (FX_CALL *GRSTIPPLE)( FxI32 mode) ;
typedef void (FX_CALL *GRCONFIGWRAPPEREXT)(HINSTANCE instance, HWND hwnd);
typedef GrScreenResolution_t (FX_CALL *GRWRAPPERFULLSCREENRESOLUTIONEXT)();
// ZIGGY framebuffer copy extension
// allow to copy the depth or color buffer from back/front to front/back
// (GL has separate back and front depth buffer, unlike glide, so this extension
// makes sense only in a wrapper)
#define GR_FBCOPY_MODE_DEPTH 0
#define GR_FBCOPY_MODE_COLOR 1
#define GR_FBCOPY_BUFFER_BACK 0
#define GR_FBCOPY_BUFFER_FRONT 1
typedef void (FX_CALL *GRFRAMEBUFFERCOPYEXT)(int x, int y, int w, int h,
int buffer_from, int buffer_to, int mode);
extern GRFRAMEBUFFERCOPYEXT grFramebufferCopyExt;
extern GRTEXBUFFEREXT grTextureBufferExt;
extern GRTEXBUFFEREXT grTextureAuxBufferExt;
extern GRAUXBUFFEREXT grAuxBufferExt;
extern GRSTIPPLE grStippleModeExt;
extern GRSTIPPLE grStipplePatternExt;
#ifndef GR_STIPPLE_DISABLE
#define GR_STIPPLE_DISABLE 0x0
#define GR_STIPPLE_PATTERN 0x1
#define GR_STIPPLE_ROTATE 0x2
#endif
void ReadSettings ();
void ReadSpecialSettings (const char name[21]);
void WriteSettings ();
#if 0
//TODO: remove
/******************************************************************
Function: CaptureScreen
Purpose: This function dumps the current frame to a file
input: pointer to the directory to save the file to
output: none
*******************************************************************/
EXPORT void CALL CaptureScreen ( char * Directory );
/******************************************************************
Function: ChangeWindow
Purpose: to change the window between fullscreen and window
mode. If the window was in fullscreen this should
change the screen to window mode and vice vesa.
input: none
output: none
*******************************************************************/
EXPORT void CALL ChangeWindow (void);
/******************************************************************
Function: CloseDLL
Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise.
input: none
output: none
*******************************************************************/
EXPORT void CALL CloseDLL (void);
/******************************************************************
Function: DllAbout
Purpose: This function is optional function that is provided
to give further information about the DLL.
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllAbout ( HWND hParent );
/******************************************************************
Function: DllConfig
Purpose: This function is optional function that is provided
to allow the user to configure the dll
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllConfig ( HWND hParent );
/******************************************************************
Function: DllTest
Purpose: This function is optional function that is provided
to allow the user to test the dll
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void CALL DllTest ( HWND hParent );
EXPORT void CALL ReadScreen(void **dest, int *width, int *height);
/******************************************************************
Function: DrawScreen
Purpose: This function is called when the emulator receives a
WM_PAINT message. This allows the gfx to fit in when
it is being used in the desktop.
input: none
output: none
*******************************************************************/
EXPORT void CALL DrawScreen (void);
/******************************************************************
Function: GetDllInfo
Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be
filled by the function. (see def above)
output: none
*******************************************************************/
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo );
/******************************************************************
Function: InitiateGFX
Purpose: 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.
Input: Gfx_Info is passed to this function which is defined
above.
Output: 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 call the function CheckInterrupts to tell the emulator
that there is a waiting interrupt.
*******************************************************************/
EXPORT BOOL CALL InitiateGFX (GFX_INFO Gfx_Info);
/******************************************************************
Function: MoveScreen
Purpose: This function is called in response to the emulator
receiving a WM_MOVE passing the xpos and ypos passed
from that message.
input: xpos - the x-coordinate of the upper-left corner of the
client area of the window.
ypos - y-coordinate of the upper-left corner of the
client area of the window.
output: none
*******************************************************************/
EXPORT void CALL MoveScreen (int xpos, int ypos);
/******************************************************************
Function: ProcessDList
Purpose: This function is called when there is a Dlist to be
processed. (High level GFX list)
input: none
output: none
*******************************************************************/
EXPORT void CALL ProcessDList(void);
/******************************************************************
Function: ProcessRDPList
Purpose: This function is called when there is a Dlist to be
processed. (Low level GFX list)
input: none
output: none
*******************************************************************/
EXPORT void CALL ProcessRDPList(void);
/******************************************************************
Function: RomClosed
Purpose: This function is called when a rom is closed.
input: none
output: none
*******************************************************************/
EXPORT void CALL RomClosed (void);
/******************************************************************
Function: RomOpen
Purpose: This function is called when a rom is open. (from the
emulation thread)
input: none
output: none
*******************************************************************/
EXPORT void CALL RomOpen (void);
/******************************************************************
Function: ShowCFB
Purpose: Useally once Dlists are started being displayed, cfb is
ignored. This function tells the dll to start displaying
them again.
input: none
output: none
*******************************************************************/
EXPORT void CALL ShowCFB (void);
/******************************************************************
Function: UpdateScreen
Purpose: This function is called in response to a vsync of the
screen were the VI bit in MI_INTR_REG has already been
set
input: none
output: none
*******************************************************************/
EXPORT void CALL UpdateScreen (void);
/******************************************************************
Function: ViStatusChanged
Purpose: This function is called to notify the dll that the
ViStatus registers value has been changed.
input: none
output: none
*******************************************************************/
EXPORT void CALL ViStatusChanged (void);
/******************************************************************
Function: ViWidthChanged
Purpose: This function is called to notify the dll that the
ViWidth registers value has been changed.
input: none
output: none
*******************************************************************/
EXPORT void CALL ViWidthChanged (void);
/******************************************************************
Function: FrameBufferWrite
Purpose: This function is called to notify the dll that the
frame buffer has been modified by CPU at the given address.
input: addr rdram address
val val
size 1 = BYTE, 2 = WORD, 4 = DWORD
output: none
*******************************************************************/
EXPORT void CALL FBWrite(DWORD, DWORD);
typedef struct
{
DWORD addr;
DWORD val;
DWORD size; // 1 = BYTE, 2 = WORD, 4=DWORD
} FrameBufferModifyEntry;
/******************************************************************
Function: FrameBufferWriteList
Purpose: This function is called to notify the dll that the
frame buffer has been modified by CPU at the given address.
input: FrameBufferModifyEntry *plist
size = size of the plist, max = 1024
output: none
*******************************************************************/
EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, DWORD size);
/******************************************************************
Function: FrameBufferRead
Purpose: This function is called to notify the dll that the
frame buffer memory is beening read at the given address.
DLL should copy content from its render buffer to the frame buffer
in N64 RDRAM
DLL is responsible to maintain its own frame buffer memory addr list
DLL should copy 4KB block content back to RDRAM frame buffer.
Emulator should not call this function again if other memory
is read within the same 4KB range
input: addr rdram address
val val
size 1 = BYTE, 2 = WORD, 4 = DWORD
output: none
*******************************************************************/
EXPORT void CALL FBRead(DWORD addr);
/************************************************************************
Function: FBGetFrameBufferInfo
Purpose: This function is called by the emulator core to retrieve depth
buffer information from the video plugin in order to be able
to notify the video plugin about CPU depth buffer read/write
operations
size:
= 1 byte
= 2 word (16 bit) <-- this is N64 default depth buffer format
= 4 dword (32 bit)
when depth buffer information is not available yet, set all values
in the FrameBufferInfo structure to 0
input: FrameBufferInfo *pinfo
pinfo is pointed to a FrameBufferInfo structure which to be
filled in by this function
output: Values are return in the FrameBufferInfo structure
************************************************************************/
EXPORT void CALL FBGetFrameBufferInfo(void *pinfo);
/******************************************************************
NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE
ORIGINAL SPEC
Function: SetConfigDir
Purpose: To pass the location where config files should be read/
written to.
input: path to config directory
output: none
*******************************************************************/
EXPORT void CALL SetConfigDir( char *configDir );
/******************************************************************
NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE
ORIGINAL SPEC
Function: SetRenderingCallback
Purpose: Allows emulator to register a callback function that will
be called by the graphics plugin just before the the
frame buffers are swapped.
This was added as a way for the emulator to draw emulator-
specific things to the screen, e.g. On-screen display.
input: pointer to callback function. The function expects
to receive the current window width and height.
output: none
*******************************************************************/
EXPORT void CALL SetRenderingCallback(void (*callback)());
#endif
#if defined(__cplusplus)
}
#endif
#endif //_GFX_H_INCLUDED__

View File

@ -0,0 +1,8 @@
For Linux :
Just type "make" and install the Glide64.so file that should be hopefully produced
into the plugins directory of the emulator.
For FreeBSD :
Instead, use "gmake", also

View File

@ -0,0 +1,540 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
// INI code v1.1
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_types.h"
#include "m64p_plugin.h"
#include "m64p_config.h"
#include "m64p_vidext.h"
#include "Ini.h"
#include "Gfx1.3.h"
#include <limits.h>
#ifndef _WIN32
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#endif // _WIN32
#include <errno.h>
#ifndef _WIN32
#include <sys/resource.h>
#endif
#ifdef _WIN32
#define PATH_MAX _MAX_PATH
#endif
/* PATH_MAX only may be defined by limits.h */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
FILE *ini;
int sectionstart;
int last_line; // last good line
int last_line_ret; // last line ended in return?
WORD cr = 0x0A0D;
static char configdir[PATH_MAX] = {0};
BOOL INI_Open ()
{
// Get the path of the dll, ex: C:\Games\Project64\Plugin\Glide64.dll
char path[PATH_MAX];
if(strlen(configdir) > 0)
{
strncpy(path, configdir, PATH_MAX);
// make sure there's a trailing '/'
//if(path[strlen(path)-1] != '/')
// strncat(path, "/", PATH_MAX - strlen(path));
}
else
{
#ifdef _WIN32
GetModuleFileName (hInstance, path, PATH_MAX);
#else // _WIN32
# ifdef __FreeBSD__
int n = readlink("/proc/curproc/files", path, PATH_MAX);
#else
int n = readlink("/proc/self/exe", path, PATH_MAX);
#endif
if (n == -1) strcpy(path, "./");
else
{
char path2[PATH_MAX];
int i;
path[n] = '\0';
strcpy(path2, path);
for (i=strlen(path2)-1; i>0; i--)
{
if(path2[i] == '/') break;
}
if(i == 0) strcpy(path, "./");
else
{
DIR *dir;
struct dirent *entry;
int gooddir = 0;
path2[i+1] = '\0';
dir = opendir(path2);
while((entry = readdir(dir)) != NULL)
{
if(!strcmp(entry->d_name, "plugins"))
gooddir = 1;
}
closedir(dir);
if(!gooddir) strcpy(path, "./");
}
}
#endif // _WIN32
// Find the previous backslash
int i;
for (i=strlen(path)-1; i>0; i--)
{
#ifdef _WIN32
if (path[i] == '\\')
#else // _WIN32
if (path[i] == '/')
#endif // _WIN32
break;
}
if (path == 0) return FALSE;
path[i+1] = 0;
#ifndef _WIN32
strcat(path, "plugins/");
#endif // _WIN32
}
//strncat (path, "Glide64.ini", PATH_MAX - strlen(path));
WriteLog(M64MSG_INFO, "opening %s\n", path);
// Open the file
ini = fopen (path, "rb");
if (ini == NULL)
{
WriteLog(M64MSG_ERROR, "Could not find Glide64.ini!");
return FALSE;
/*
ini = fopen (path, "w+b");
if (ini == NULL)
{
return FALSE;
}
*/
}
sectionstart = 0;
last_line = 0;
last_line_ret = 1;
return TRUE;
}
void INI_Close ()
{
//if (ini)
// fclose(ini);
}
void INI_InsertSpace(int space)
{
// Since there is no good way to normally insert to or delete from a certain location in
// a file, this function was added. It will insert (or delete) space bytes at the
// current location.
// note: negative count means delete
char chunk[2048];
int len, file, start_pos, cur_pos;
#ifdef _WIN32
file = _fileno(ini);
#else // _WIN32
file = fileno(ini);
#endif // _WIN32
start_pos = ftell(ini);
fseek(ini,0,SEEK_END);
// if adding, extend the file
if (space > 0)
#ifdef _WIN32
_chsize (file, _filelength(file)+space);
#else // _WIN32
{
int t1 = ftell(ini);
fseek(ini, 0L, SEEK_END);
int t2 = ftell(ini);
fseek(ini, t1, SEEK_SET);
ftruncate(file, t2+space);
}
#endif // _WIN32
while (1) {
cur_pos = ftell(ini);
len = cur_pos - start_pos;
if (len == 0) break;
if (len > 2048) len = 2048;
fseek (ini,-len,SEEK_CUR);
fread (chunk,1,len,ini);
fseek (ini,-len+space,SEEK_CUR);
fwrite (chunk,1,len,ini);
fseek (ini,-len-space,SEEK_CUR);
}
// if deleted, make the file shorter
if (space < 0)
#ifdef _WIN32
_chsize (file, _filelength(file)+space);
#else // _WIN32
{
int t1 = ftell(ini);
fseek(ini, 0L, SEEK_END);
int t2 = ftell(ini);
fseek(ini, t1, SEEK_SET);
ftruncate(file, t2+space);
}
#endif // _WIN32
}
BOOL INI_FindSection (const char *sectionname, BOOL create)
{
if (ini == NULL)
return FALSE;
char line[256], section[64];
char *p;
int i, sectionfound, ret;
rewind (ini);
last_line = 0;
sectionfound = 0;
while(!feof(ini)) {
ret = 0;
*line=0;
fgets(line,255,ini);
// remove enter
i=strlen(line);
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
// with just EOL), it would write into line[-1]
if(i>=1 && line[i-1]==0xa) {
ret=1;
line[i-1]=0;
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
}
// remove comments
p=line;
while(*p)
{
if (p[0]=='/' && p[1]=='/')
{
p[0]=0;
break;
}
p++;
}
// skip starting space
p=line;
while(*p<=' ' && *p) p++;
// empty line
if(!*p) continue;
last_line=ftell(ini); // where to add if not found
last_line_ret = ret;
if(*p!='[') continue;
p++;
for (i=0;i<63;i++)
{
if(*p==']' || !*p) break;
section[i]=*p++;
}
section[i]=0;
#ifdef _WIN32
if(!stricmp(section,sectionname))
#else // _WIN32
if (!strcasecmp(section,sectionname))
#endif // _WIN32
{
sectionstart=ftell(ini);
sectionfound=1;
return TRUE;
}
}
if (!sectionfound && create)
{
// create the section
fseek(ini,last_line,SEEK_SET);
INI_InsertSpace ((!last_line_ret) * 2 + 6 + strlen(sectionname));
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
fwrite (&cr, 1, 2, ini);
sprintf (section, "[%s]", sectionname);
fwrite (section, 1, strlen(section), ini);
fwrite (&cr, 1, 2, ini);
sectionstart = ftell(ini);
last_line = sectionstart;
last_line_ret = 1;
return TRUE;
}
return FALSE;
}
// Reads the value of item 'itemname' as a string.
const char *INI_ReadString (const char *itemname, char *value, const char *def_value, BOOL create)
{
char line[256], name[64];
char *p, *n;
int ret, i;
*value = 0;
fseek(ini,sectionstart,SEEK_SET);
while(!feof(ini)) {
ret = 0;
*line=0;
fgets(line,255,ini);
// remove enter
i=strlen(line);
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
// with just EOL), it would write into line[-1]
// OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0;
if(i>=1 && line[i-1]==0xa) {
ret=1;
line[i-1]=0;
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
}
// remove comments
p=line;
while(*p)
{
if (p[0]==';')
{
p[0]=0;
break;
}
p++;
}
// skip starting space
p=line;
while(*p<=' ' && *p) p++;
// empty line
if(!*p) continue;
// new section
if(*p=='[') break;
last_line=ftell(ini); // where to add if not found
last_line_ret = ret;
// read name
n = name;
while(*p && *p!='=' && *p>' ') *n++ = *p++;
*n = 0;
#ifdef _WIN32
if(!stricmp(name,itemname))
#else // _WIN32
if(!strcasecmp(name,itemname))
#endif // _WIN32
{
// skip spaces/equal sign
while(*p<=' ' || *p=='=') p++;
// read value
n = value;
while(*p) *n++ = *p++;
// remove trailing spaces
while (*(n-1) == ' ') n--;
*n=0;
return value;
}
}
// uh-oh, not found. we need to create
if (create)
{
fseek(ini,last_line,SEEK_SET);
INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(def_value) + 5);
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
sprintf (line, "%s = %s", itemname, def_value);
fwrite (line, 1, strlen(line), ini);
fwrite (&cr, 1, 2, ini);
last_line = ftell(ini);
last_line_ret = 1;
}
strcpy (value, def_value);
return value;
}
// Reads the value of item 'itemname' as a string.
void INI_WriteString (const char *itemname, const char *value)
{
char line[256], name[64];
char *p, *n;
int ret, i;
fseek(ini,sectionstart,SEEK_SET);
while(!feof(ini)) {
ret = 0;
*line=0;
fgets(line,255,ini);
// remove enter
i=strlen(line);
// ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line
// with just EOL), it would write into line[-1]
// OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0;
if(i>=1 && line[i-1]==0xa) {
ret=1;
line[i-1]=0;
if (i>=2 && line[i-2]==0xd) line[i-2]=0;
}
// remove comments
p=line;
while(*p)
{
if (p[0]=='/' && p[1]=='/')
{
p[0]=0;
break;
}
p++;
}
// skip starting space
p=line;
while(*p<=' ' && *p) p++;
// empty line
if(!*p) continue;
// new section
if(*p=='[') break;
last_line=ftell(ini); // where to add if not found
last_line_ret = ret;
// read name
n = name;
while(*p && *p!='=' && *p>' ') *n++ = *p++;
*n = 0;
#ifdef _WIN32
if(!stricmp(name,itemname))
#else // _WIN32
if(!strcasecmp(name,itemname))
#endif // _WIN32
{
INI_InsertSpace (-i + (strlen(itemname) + strlen(value) + 5));
sprintf (line, "%s = %s", itemname, value);
fseek (ini, -i, SEEK_CUR);
fwrite (line, 1, strlen(line), ini);
fwrite (&cr, 1, 2, ini);
last_line = ftell(ini);
last_line_ret = 1;
return;
}
}
// uh-oh, not found. we need to create
fseek(ini,last_line,SEEK_SET);
INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(value) + 5);
if (!last_line_ret) fwrite (&cr, 1, 2, ini);
sprintf (line, "%s = %s", itemname, value);
fwrite (line, 1, strlen(line), ini);
fwrite (&cr, 1, 2, ini);
last_line = ftell(ini);
last_line_ret = 1;
return;
}
int INI_ReadInt (const char *itemname, int def_value, BOOL create)
{
if (ini == NULL)
return def_value;
char value[64], def[64];
#ifdef _WIN32
_itoa (def_value, def, 10);
#else // _WIN32
sprintf(def, "%d", def_value);
#endif // _WIN32
INI_ReadString (itemname, value, def, create);
return atoi (value);
}
void INI_WriteInt (const char *itemname, int value)
{
char valstr[64];
#ifdef _WIN32
_itoa (value, valstr, 10);
#else // _WIN32
sprintf(valstr, "%d", value);
#endif // _WIN32
INI_WriteString (itemname, valstr);
}
void SetConfigDir( const char *configDir )
{
strncpy(configdir, configDir, PATH_MAX);
}

View File

@ -0,0 +1,49 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#include <stdio.h>
#include "winlnxdefs.h"
BOOL INI_Open ();
void INI_Close ();
void INI_InsertSpace(int space);
BOOL INI_FindSection (const char *sectionname, BOOL create=TRUE);
const char *INI_ReadString (const char *itemname, const char *value, const char *def_value, BOOL create=TRUE);
void INI_WriteString (const char *itemname, const char *value);
int INI_ReadInt (const char *itemname, int def_value, BOOL create=TRUE);
void INI_WriteInt (const char *itemname, int value);
void SetConfigDir( const char *configDir );

View File

@ -0,0 +1,27 @@
The included data files:
cursor.tex
font.tex
are Copyright (C) 2002 by Dave2001. These files are licensed under the GNU
General Public License, version 2 or later. Please see the gpl.txt file for
full license details.
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,298 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//****************************************************************
// 16-bit Horizontal Mirror
void Mirror16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
{
if (mask == 0) return;
DWORD mask_width = (1 << mask);
DWORD mask_mask = (mask_width-1) << 1;
if (mask_width >= max_width) return;
int count = max_width - mask_width;
if (count <= 0) return;
int line_full = real_width;
int line = line_full - count;
if (line < 0) return;
unsigned short * start = (unsigned short *)(tex) + mask_width;
unsigned short * edi = start;
for(unsigned int ecx = height; ecx; --ecx)
{
for (int edx = 0; edx != count; ++edx)
{
unsigned short * esi = (unsigned short *)(tex);
if ((mask_width + edx) & mask_width)
{
esi += (mask_mask - ((edx >> 1) & mask_mask)) / 2;
}
else
{
esi += ((edx >> 1) & mask_mask) / 2;
}
*edi = *esi;
++edi;
}
edi += line;
tex += line_full * 2;
}
}
//****************************************************************
// 16-bit Vertical Mirror
void Mirror16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
{
if (mask == 0) return;
DWORD mask_height = (1 << mask);
DWORD mask_mask = mask_height-1;
if (max_height <= mask_height) return;
int line_full = real_width << 1;
unsigned char * dst = tex + mask_height * line_full;
for (DWORD y=mask_height; y<max_height; y++)
{
if (y & mask_height)
{
// mirrored
memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
}
else
{
// not mirrored
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
}
dst += line_full;
}
}
//****************************************************************
// 16-bit Horizontal Wrap (like mirror)
void Wrap16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
{
if (mask == 0) return;
DWORD mask_width = (1 << mask);
DWORD mask_mask = (mask_width-1) >> 1;
if (mask_width >= max_width) return;
int count = (max_width - mask_width) >> 1;
if (count <= 0) return;
int line_full = real_width << 1;
int line = line_full - (count << 2);
if (line < 0) return;
unsigned char * start = tex + (mask_width << 1);
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov edi,dword ptr [start]
mov ecx,dword ptr [height]
loop_y:
xor edx,edx
loop_x:
mov esi,dword ptr [tex]
mov eax,edx
and eax,dword ptr [mask_mask]
shl eax,2
add esi,eax
mov eax,dword ptr [esi]
mov dword ptr [edi],eax
add edi,4
inc edx
cmp edx,dword ptr [count]
jne loop_x
add edi,dword ptr [line]
mov eax,dword ptr [tex]
add eax,dword ptr [line_full]
mov dword ptr [tex],eax
dec ecx
jnz loop_y
}
#elif !defined(NO_ASM)
//printf("wrap16bS\n");
intptr_t fake_esi, fake_eax;
asm volatile (
"0: \n"
"xor %%edx, %%edx \n"
"1: \n"
"mov %[tex], %[S] \n"
"mov %%edx, %%eax \n"
"and %[mask_mask], %%eax \n"
"shl $2, %%eax \n"
"add %[a], %[S] \n"
"mov (%[S]), %%eax \n"
"mov %%eax, (%[start]) \n"
"add $4, %[start] \n"
"inc %%edx \n"
"cmp %[count], %%edx \n"
"jne 1b \n"
"add %[line], %[start] \n"
"add %[line_full], %[tex] \n"
"dec %%ecx \n"
"jnz 0b \n"
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r"(tex)
: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
: "memory", "cc", "edx"
);
#endif // _WIN32
}
//****************************************************************
// 16-bit Vertical Wrap
void Wrap16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
{
if (mask == 0) return;
DWORD mask_height = (1 << mask);
DWORD mask_mask = mask_height-1;
if (max_height <= mask_height) return;
int line_full = real_width << 1;
unsigned char * dst = tex + mask_height * line_full;
for (DWORD y=mask_height; y<max_height; y++)
{
// not mirrored
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
dst += line_full;
}
}
//****************************************************************
// 16-bit Horizontal Clamp
void Clamp16bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)
{
if (real_width <= width) return;
unsigned char * dest = tex + (width << 1);
unsigned char * constant = dest-2;
int count = clamp_to - width;
int line_full = real_width << 1;
int line = width << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [constant]
mov edi,dword ptr [dest]
mov ecx,real_height
y_loop:
mov ax,word ptr [esi]
mov edx,dword ptr [count]
x_loop:
mov word ptr [edi],ax // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
add edi,2
dec edx
jnz x_loop
add esi,dword ptr [line_full]
add edi,dword ptr [line]
dec ecx
jnz y_loop
}
#elif !defined(NO_ASM)
//printf("clamp16bS\n");
asm volatile (
//"y_loop10: \n"
"0: \n"
"mov (%[constant]), %%ax \n"
"mov %[count], %%edx \n"
//"x_loop10: \n"
"1: \n"
"mov %%ax, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
"add $2, %[dest] \n"
"dec %%edx \n"
//"jnz x_loop10 \n"
"jnz 1b \n"
"add %[line_full], %[constant] \n"
"add %[line], %[dest] \n"
"dec %%ecx \n"
//"jnz y_loop10 \n"
"jnz 0b \n"
: "+c"(real_height), [constant]"+S"(constant), [dest]"+D"(dest)
: [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
: "memory", "cc", "eax", "edx"
);
#endif
}
//****************************************************************
// 16-bit Vertical Clamp
void Clamp16bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)
{
int line_full = real_width << 1;
unsigned char * dst = tex + height * line_full;
unsigned char * const_line = dst - line_full;
for (DWORD y=height; y<clamp_to; y++)
{
memcpy ((void*)dst, (void*)const_line, line_full);
dst += line_full;
}
}

View File

@ -0,0 +1,361 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//****************************************************************
// 8-bit Horizontal Mirror
void Mirror8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
{
if (mask == 0) return;
DWORD mask_width = (1 << mask);
DWORD mask_mask = (mask_width-1);
if (mask_width >= max_width) return;
int count = max_width - mask_width;
if (count <= 0) return;
int line_full = real_width;
int line = line_full - (count);
if (line < 0) return;
unsigned char * start = tex + (mask_width);
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov edi,dword ptr [start]
mov ecx,dword ptr [height]
loop_y:
xor edx,edx
loop_x:
mov esi,dword ptr [tex]
mov ebx,dword ptr [mask_width]
add ebx,edx
and ebx,dword ptr [mask_width]
jnz is_mirrored
mov eax,edx
and eax,dword ptr [mask_mask]
add esi,eax
mov al,byte ptr [esi]
mov byte ptr [edi],al
inc edi
jmp end_mirror_check
is_mirrored:
add esi,dword ptr [mask_mask]
mov eax,edx
and eax,dword ptr [mask_mask]
sub esi,eax
mov al,byte ptr [esi]
mov byte ptr [edi],al
inc edi
end_mirror_check:
inc edx
cmp edx,dword ptr [count]
jne loop_x
add edi,dword ptr [line]
mov eax,dword ptr [tex]
add eax,dword ptr [line_full]
mov dword ptr [tex],eax
dec ecx
jnz loop_y
}
#elif !defined(NO_ASM)
//printf("Mirror8bS\n");
intptr_t fake_esi,fake_eax;
asm volatile (
"1: \n" // loop_y3
"xor %%edx, %%edx \n"
"2: \n" // loop_x3
"mov %[tex], %[S] \n"
"mov %[mask_width], %%eax \n"
"add %%edx, %%eax \n"
"and %[mask_width], %%eax \n"
"jnz 3f \n" // is_mirrored2
"mov %%edx, %%eax \n"
"and %[mask_mask], %[a] \n"
"add %[a], %[S] \n"
"mov (%[S]), %%al \n"
"mov %%al, (%[start]) \n"
"inc %[start] \n"
"jmp 4f \n" // end_mirror_check2
"3: \n" // is_mirrored2
"add %[mask_mask], %[S] \n"
"mov %%edx, %%eax \n"
"and %[mask_mask], %[a] \n"
"sub %[a], %[S] \n"
"mov (%[S]), %%al \n"
"mov %%al, (%[start]) \n"
"inc %[start] \n"
"4: \n" // end_mirror_check2
"inc %%edx \n"
"cmp %[count], %%edx \n"
"jne 2b \n" // loop_x3
"add %[line], %[start] \n"
"add %[line_full], %[tex] \n"
"dec %%ecx \n"
"jnz 1b \n" // loop_y3
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r" (tex)
: [mask_width] "g" (mask_width), [mask_mask] "g" ((intptr_t)mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
: "memory", "cc", "edx"
);
#endif // _WIN32
}
//****************************************************************
// 8-bit Vertical Mirror
void Mirror8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
{
if (mask == 0) return;
DWORD mask_height = (1 << mask);
DWORD mask_mask = mask_height-1;
if (max_height <= mask_height) return;
int line_full = real_width;
unsigned char * dst = tex + mask_height * line_full;
for (DWORD y=mask_height; y<max_height; y++)
{
if (y & mask_height)
{
// mirrored
memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
}
else
{
// not mirrored
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
}
dst += line_full;
}
}
//****************************************************************
// 8-bit Horizontal Wrap (like mirror) ** UNTESTED **
void Wrap8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
{
if (mask == 0) return;
DWORD mask_width = (1 << mask);
DWORD mask_mask = (mask_width-1) >> 2;
if (mask_width >= max_width) return;
int count = (max_width - mask_width) >> 2;
if (count <= 0) return;
int line_full = real_width;
int line = line_full - (count << 2);
if (line < 0) return;
unsigned char * start = tex + (mask_width);
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov edi,dword ptr [start]
mov ecx,dword ptr [height]
loop_y:
xor edx,edx
loop_x:
mov esi,dword ptr [tex]
mov eax,edx
and eax,dword ptr [mask_mask]
shl eax,2
add esi,eax
mov eax,dword ptr [esi]
mov dword ptr [edi],eax
add edi,4
inc edx
cmp edx,dword ptr [count]
jne loop_x
add edi,dword ptr [line]
mov eax,dword ptr [tex]
add eax,dword ptr [line_full]
mov dword ptr [tex],eax
dec ecx
jnz loop_y
}
#elif !defined(NO_ASM)
//printf("wrap8bS\n");
intptr_t fake_esi,fake_eax;
asm volatile (
"1: \n" // loop_y4
"xor %%edx, %%edx \n"
"2: \n" // loop_x4
"mov %[tex], %[S] \n"
"mov %%edx, %%eax \n"
"and %[mask_mask], %%eax \n"
"shl $2, %%eax \n"
"add %[a], %[S] \n"
"mov (%[S]), %%eax \n"
"mov %%eax, (%[start]) \n"
"add $4, %[start] \n"
"inc %%edx \n"
"cmp %[count], %%edx \n"
"jne 2b \n" // loop_x4
"add %[line], %[start] \n"
"add %[line_full], %[tex] \n"
"dec %%ecx \n"
"jnz 1b \n" // loop_y4
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), [tex] "+r" (tex), "+c"(height)
: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
: "memory", "cc", "edx"
);
#endif
}
//****************************************************************
// 8-bit Vertical Wrap
void Wrap8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
{
if (mask == 0) return;
DWORD mask_height = (1 << mask);
DWORD mask_mask = mask_height-1;
if (max_height <= mask_height) return;
int line_full = real_width;
unsigned char * dst = tex + mask_height * line_full;
for (DWORD y=mask_height; y<max_height; y++)
{
// not mirrored
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
dst += line_full;
}
}
//****************************************************************
// 8-bit Horizontal Clamp
void Clamp8bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)
{
if (real_width <= width) return;
unsigned char * dest = tex + (width);
unsigned char * constant = dest-1;
int count = clamp_to - width;
int line_full = real_width;
int line = width;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [constant]
mov edi,dword ptr [dest]
mov ecx,real_height
y_loop:
mov al,byte ptr [esi]
mov edx,dword ptr [count]
x_loop:
mov byte ptr [edi],al // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
inc edi
dec edx
jnz x_loop
add esi,dword ptr [line_full]
add edi,dword ptr [line]
dec ecx
jnz y_loop
}
#elif !defined(NO_ASM)
//printf("clamp8bs\n");
asm volatile (
"0: \n"
"mov (%[constant]), %%al \n"
"mov %[count], %%edx \n"
"1: \n"
"mov %%al, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
"inc %[dest] \n"
"dec %%edx \n"
"jnz 1b \n"
"add %[line_full], %[constant] \n"
"add %[line], %[dest] \n"
"dec %%ecx \n"
"jnz 0b \n"
: [constant]"+S"(constant), [dest]"+D"(dest), "+c"(real_height)
: [count] "g" (count), [line] "g" ((uintptr_t)line), [line_full] "g" ((intptr_t)line_full)
: "memory", "cc", "eax", "edx"
);
#endif
}
//****************************************************************
// 8-bit Vertical Clamp
void Clamp8bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)
{
int line_full = real_width;
unsigned char * dst = tex + height * line_full;
unsigned char * const_line = dst - line_full;
for (DWORD y=height; y<clamp_to; y++)
{
memcpy ((void*)dst, (void*)const_line, line_full);
dst += line_full;
}
}

View File

@ -0,0 +1,635 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
//****************************************************************
//
// Dec 2003 created by Gonetz
//
//****************************************************************
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_types.h"
#include "m64p_plugin.h"
#include "m64p_config.h"
#include "m64p_vidext.h"
#include "rdp.h"
#include "TexBuffer.h"
#include "Gfx1.3.h"
#ifndef _WIN32
#include <string.h>
#endif // _WIN32
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
static HIRES_COLOR_IMAGE * AllocateTextureBuffer(COLOR_IMAGE & cimage)
{
HIRES_COLOR_IMAGE texbuf;
texbuf.addr = cimage.addr;
texbuf.end_addr = cimage.addr + cimage.width*cimage.height*cimage.size;
texbuf.width = cimage.width;
texbuf.height = cimage.height;
texbuf.format = (WORD)cimage.format;
texbuf.scr_width = min(cimage.width * rdp.scale_x, settings.scr_res_x);
float height = min(rdp.vi_height,cimage.height);
if (cimage.status == ci_copy_self || (cimage.status == ci_copy && cimage.width == rdp.frame_buffers[rdp.main_ci_index].width))
height = rdp.vi_height;
texbuf.scr_height = height * rdp.scale_y;
WORD max_size = max((WORD)texbuf.scr_width, (WORD)texbuf.scr_height);
if (max_size > max_tex_size) //texture size is too large
return 0;
DWORD tex_size;
//calculate LOD
switch ((max_size-1) >> 6)
{
case 0:
// ZIGGY : fixed (was GR_LOD_LOG2_128)
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_64;
tex_size = 64;
break;
case 1:
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_128;
tex_size = 128;
break;
case 2:
case 3:
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_256;
tex_size = 256;
break;
case 4:
case 5:
case 6:
case 7:
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_512;
tex_size = 512;
break;
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_1024;
tex_size = 1024;
break;
default:
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_2048;
tex_size = 2048;
}
//calculate aspect
if (texbuf.scr_width >= texbuf.scr_height)
{
if ((texbuf.scr_width/texbuf.scr_height) >= 2)
{
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
texbuf.tex_width = tex_size;
texbuf.tex_height = tex_size >> 1;
}
else
{
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
texbuf.tex_width = texbuf.tex_height = tex_size;
}
}
else
{
if ((texbuf.scr_height/texbuf.scr_width) >= 2)
{
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x2;
texbuf.tex_width = tex_size >> 1;
texbuf.tex_height = tex_size;
}
else
{
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
texbuf.tex_width = texbuf.tex_height = tex_size;
}
}
if ((cimage.format != 0))// && (cimage.width <= 64))
texbuf.info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
else
texbuf.info.format = GR_TEXFMT_RGB_565;
float lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f;
float lr_v = 256.0f * texbuf.scr_height / (float)tex_size;// + 1.0f;
texbuf.tile = 0;
texbuf.tile_uls = 0;
texbuf.tile_ult = 0;
texbuf.u_shift = 0;
texbuf.v_shift = 0;
texbuf.drawn = FALSE;
texbuf.clear = FALSE;
texbuf.info.data = NULL;
texbuf.u_scale = lr_u / (float)(texbuf.width);
texbuf.v_scale = lr_v / (float)(texbuf.height);
FRDP("\nAllocateTextureBuffer. width: %d, height: %d, scr_width: %f, scr_height: %f, vi_width: %f, vi_height:%f, scale_x: %f, scale_y: %f, lr_u: %f, lr_v: %f, u_scale: %f, v_scale: %f\n", texbuf.width, texbuf.height, texbuf.scr_width, texbuf.scr_height, rdp.vi_width, rdp.vi_height, rdp.scale_x, rdp.scale_y, lr_u, lr_v, texbuf.u_scale, texbuf.v_scale);
DWORD required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2,
texbuf.info.aspectRatioLog2, texbuf.info.format);
//find free space
for (int i = 0; i < num_tmu; i++)
{
DWORD available = 0;
DWORD top = 0;
if (rdp.texbufs[i].count)
{
HIRES_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1];
if (rdp.read_whole_frame)
{
if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i))
{
top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * (int)(t.scr_height+1) * 2;
if (rdp.texbufs[i].end - top < required)
return 0;
}
else
top = rdp.texbufs[i].end;
}
else
top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * t.tex_height * 2;
available = rdp.texbufs[i].end - top;
}
else
{
available = rdp.texbufs[i].end - rdp.texbufs[i].begin;
top = rdp.texbufs[i].begin;
}
//printf("i %d count %d end %gMb avail %gMb req %gMb\n", i, rdp.texbufs[i].count, rdp.texbufs[i].end/1024.0f/1024, available/1024.0f/1024, required/1024.0f/1024);
if (available >= required)
{
rdp.texbufs[i].count++;
rdp.texbufs[i].clear_allowed = FALSE;
texbuf.tex_addr = top;
rdp.cur_tex_buf = i;
// ZIGGY strange fix
texbuf.tmu = rdp.texbufs[i].tmu;
rdp.texbufs[i].images[rdp.texbufs[i].count - 1] = texbuf;
return &(rdp.texbufs[i].images[rdp.texbufs[i].count - 1]);
}
}
//not found. keep recently accessed bank, clear second one
if (!rdp.texbufs[rdp.cur_tex_buf^1].clear_allowed) { //can't clear => can't allocate
WriteLog(M64MSG_WARNING, "Can't allocate texture buffer\n");
return 0;
}
rdp.cur_tex_buf ^= 1;
rdp.texbufs[rdp.cur_tex_buf].count = 1;
rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE;
// ZIGGY strange fix
texbuf.tmu = rdp.texbufs[rdp.cur_tex_buf].tmu;
texbuf.tex_addr = rdp.texbufs[rdp.cur_tex_buf].begin;
rdp.texbufs[rdp.cur_tex_buf].images[0] = texbuf;
return &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
}
BOOL OpenTextureBuffer(COLOR_IMAGE & cimage)
{
FRDP("OpenTextureBuffer. cur_tex_buf: %d, addr: %08lx, width: %d, height: %d", rdp.cur_tex_buf, cimage.addr, cimage.width, cimage.height);
if (!fullscreen) return FALSE;
BOOL found = FALSE, search = TRUE;
HIRES_COLOR_IMAGE *texbuf = 0;
DWORD addr = cimage.addr;
DWORD end_addr = addr + cimage.width*cimage.height*cimage.size;
if (rdp.motionblur)
{
if (cimage.format != 0)
return FALSE;
search = FALSE;
}
if (rdp.read_whole_frame)
{
if (settings.PM) //motion blur effects in Paper Mario
{
rdp.cur_tex_buf = rdp.acc_tex_buf;
FRDP("read_whole_frame. last allocated bank: %d\n", rdp.acc_tex_buf);
}
else
{
if (!rdp.texbufs[0].clear_allowed || !rdp.texbufs[1].clear_allowed)
{
if (cimage.status == ci_main)
{
texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
found = TRUE;
}
else
{
for (int t = 0; (t < rdp.texbufs[rdp.cur_tex_buf].count) && !found; t++)
{
texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[t]);
if (addr == texbuf->addr && cimage.width == texbuf->width)
{
texbuf->drawn = FALSE;
found = TRUE;
}
}
}
}
search = FALSE;
}
}
if (search)
{
for (int i = 0; (i < num_tmu) && !found; i++)
{
for (int j = 0; (j < rdp.texbufs[i].count) && !found; j++)
{
texbuf = &(rdp.texbufs[i].images[j]);
if (addr == texbuf->addr && cimage.width == texbuf->width)
{
//texbuf->height = cimage.height;
//texbuf->end_addr = end_addr;
texbuf->drawn = FALSE;
texbuf->format = (WORD)cimage.format;
if ((cimage.format != 0))
texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
else
texbuf->info.format = GR_TEXFMT_RGB_565;
found = TRUE;
rdp.cur_tex_buf = i;
rdp.texbufs[i].clear_allowed = FALSE;
}
else //check intersection
{
if (!((end_addr <= texbuf->addr) || (addr >= texbuf->end_addr))) //intersected, remove
{
grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,
texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
grDepthMask (FXFALSE);
grBufferClear (0, 0, 0xFFFF);
grDepthMask (FXTRUE);
grRenderBuffer( GR_BUFFER_BACKBUFFER );
rdp.texbufs[i].count--;
if (j < rdp.texbufs[i].count)
memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[i].count-j));
}
}
}
}
}
if (!found)
{
RDP (" not found");
texbuf = AllocateTextureBuffer(cimage);
}
else
{
RDP (" found");
}
if (!texbuf)
{
RDP(" KO\n");
return FALSE;
}
rdp.acc_tex_buf = rdp.cur_tex_buf;
rdp.cur_image = texbuf;
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
//printf("texadr %gMb\n", rdp.cur_image->tex_addr/1024.0f/1024);
grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
///*
if (rdp.cur_image->clear && settings.fb_hires_buf_clear && cimage.changed)
{
rdp.cur_image->clear = FALSE;
grDepthMask (FXFALSE);
grBufferClear (0, 0, 0xFFFF);
grDepthMask (FXTRUE);
}
//*/
// memset(gfx.RDRAM+cimage.addr, 0, cimage.width*cimage.height*cimage.size);
FRDP(" texaddr: %08lx, tex_width: %d, tex_height: %d, cur_tex_buf: %d, texformat: %d, motionblur: %d\n", rdp.cur_image->tex_addr, rdp.cur_image->tex_width, rdp.cur_image->tex_height, rdp.cur_tex_buf, rdp.cur_image->info.format, rdp.motionblur);
return TRUE;
}
static GrTextureFormat_t TexBufSetupCombiner(BOOL force_rgb = FALSE)
{
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE,
GR_COMBINE_OTHER_TEXTURE,
FXFALSE);
grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_LOCAL_NONE,
GR_COMBINE_OTHER_TEXTURE,
FXFALSE);
grAlphaBlendFunction (GR_BLEND_ONE, // use alpha compare, but not T0 alpha
GR_BLEND_ZERO,
GR_BLEND_ONE,
GR_BLEND_ZERO);
grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);
grDepthBufferFunction (GR_CMP_ALWAYS);
grDepthMask (FXFALSE);
grCullMode (GR_CULL_DISABLE);
grFogMode (GR_FOG_DISABLE);
GrTextureFormat_t buf_format = (rdp.hires_tex) ? rdp.hires_tex->info.format : GR_TEXFMT_RGB_565;
GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL;
if (!force_rgb && rdp.black_ci_index > 0 && rdp.black_ci_index <= rdp.copy_ci_index)
{
color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA;
buf_format = GR_TEXFMT_ALPHA_INTENSITY_88;
}
if (rdp.hires_tex->tmu == GR_TMU0)
{
grTexCombine( GR_TMU1,
GR_COMBINE_FUNCTION_NONE,
GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_NONE,
GR_COMBINE_FACTOR_NONE,
FXFALSE,
FXFALSE );
grTexCombine( GR_TMU0,
color_source,
GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_ZERO,
GR_COMBINE_FACTOR_NONE,
FXFALSE,
FXTRUE );
}
else
{
grTexCombine( GR_TMU1,
color_source,
GR_COMBINE_FACTOR_NONE,
GR_COMBINE_FUNCTION_ZERO,
GR_COMBINE_FACTOR_NONE,
FXFALSE,
FXTRUE );
grTexCombine( GR_TMU0,
GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
GR_COMBINE_FUNCTION_SCALE_OTHER,
GR_COMBINE_FACTOR_ONE,
FXFALSE,
FXFALSE );
}
return buf_format;
}
BOOL CloseTextureBuffer(BOOL draw)
{
if (!fullscreen || !rdp.cur_image)
{
RDP("CloseTextureBuffer KO\n");
return FALSE;
}
grRenderBuffer( GR_BUFFER_BACKBUFFER );
if (!draw)
{
RDP("CloseTextureBuffer no draw, OK\n");
rdp.cur_image = 0;
return TRUE;
}
rdp.hires_tex = rdp.cur_image;
rdp.cur_image = 0;
GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
rdp.hires_tex->info.format = TexBufSetupCombiner();
float ul_x = 0.0f;
float ul_y = 0.0f;
float ul_u = 0.0f;
float ul_v = 0.0f;
float lr_x = (float)rdp.hires_tex->scr_width;
float lr_y = (float)rdp.hires_tex->scr_height;
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
FRDP("lr_x: %f, lr_y: %f, lr_u: %f, lr_v: %f\n", lr_x, lr_y, lr_u, lr_v);
// Make the vertices
VERTEX v[4] = {
{ ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v },
{ lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v },
{ ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v },
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v } };
ConvertCoordsConvert (v, 4);
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
grDrawTriangle (&v[0], &v[2], &v[1]);
grDrawTriangle (&v[2], &v[3], &v[1]);
rdp.hires_tex->info.format = buf_format;
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
if (settings.fog && (rdp.flags & FOG_ENABLED))
{
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
}
RDP("CloseTextureBuffer draw, OK\n");
rdp.hires_tex = 0;
return TRUE;
}
BOOL CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to)
{
if (!fullscreen)
return FALSE;
RDP("CopyTextureBuffer. ");
if (rdp.cur_image)
{
if (rdp.cur_image->addr == fb_to.addr)
return CloseTextureBuffer(TRUE);
rdp.hires_tex = rdp.cur_image;
}
else if (!FindTextureBuffer(fb_from.addr, (WORD)fb_from.width))
{
RDP("Can't find 'from' buffer.\n");
return FALSE;
}
if (!OpenTextureBuffer(fb_to))
{
RDP("Can't open new buffer.\n");
return CloseTextureBuffer(TRUE);
}
GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
TexBufSetupCombiner(TRUE);
float ul_x = 0.0f;
float ul_y = 0.0f;
float lr_x = (float)rdp.hires_tex->scr_width;
float lr_y = (float)rdp.hires_tex->scr_height;
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);
// Make the vertices
VERTEX v[4] = {
{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
ConvertCoordsConvert (v, 4);
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
grDrawTriangle (&v[0], &v[2], &v[1]);
grDrawTriangle (&v[2], &v[3], &v[1]);
grRenderBuffer( GR_BUFFER_BACKBUFFER );
grDrawTriangle (&v[0], &v[2], &v[1]);
grDrawTriangle (&v[2], &v[3], &v[1]);
rdp.hires_tex->info.format = buf_format;
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
if (settings.fog && (rdp.flags & FOG_ENABLED))
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
RDP("CopyTextureBuffer draw, OK\n");
rdp.hires_tex = 0;
rdp.cur_image = 0;
return TRUE;
}
BOOL SwapTextureBuffer()
{
if (!fullscreen || !rdp.hires_tex)
return FALSE;
RDP("SwapTextureBuffer.");
HIRES_COLOR_IMAGE * texbuf = AllocateTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]);
if (!texbuf)
{
RDP(" failed!\n");
return FALSE;
}
TexBufSetupCombiner();
float ul_x = 0.0f;
float ul_y = 0.0f;
float lr_x = (float)rdp.hires_tex->scr_width;
float lr_y = (float)rdp.hires_tex->scr_height;
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
// Make the vertices
VERTEX v[4] = {
{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
int tex = rdp.tex;
rdp.tex = 1;
ConvertCoordsConvert (v, 4);
rdp.tex = tex;
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
texbuf->tile_uls = rdp.hires_tex->tile_uls;
texbuf->tile_ult = rdp.hires_tex->tile_ult;
texbuf->v_shift = rdp.hires_tex->v_shift;
rdp.cur_image = texbuf;
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
grSstOrigin(GR_ORIGIN_UPPER_LEFT);
grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
grDrawTriangle (&v[0], &v[2], &v[1]);
grDrawTriangle (&v[2], &v[3], &v[1]);
rdp.texbufs[rdp.hires_tex->tmu].clear_allowed = TRUE;
rdp.texbufs[rdp.hires_tex->tmu].count = 0;
rdp.hires_tex = rdp.cur_image;
rdp.cur_image = 0;
grRenderBuffer( GR_BUFFER_BACKBUFFER );
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
if (settings.fog && (rdp.flags & FOG_ENABLED))
{
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
}
RDP("SwapTextureBuffer draw, OK\n");
return TRUE;
}
BOOL FindTextureBuffer(DWORD addr, WORD width)
{
if (rdp.skip_drawing)
return FALSE;
FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x);
BOOL found = FALSE;
DWORD shift = 0;
for (int i = 0; i < num_tmu && !found; i++)
{
BYTE index = rdp.cur_tex_buf^i;
for (int j = 0; j < rdp.texbufs[index].count && !found; j++)
{
rdp.hires_tex = &(rdp.texbufs[index].images[j]);
if(addr >= rdp.hires_tex->addr && addr < rdp.hires_tex->end_addr)// && rdp.timg.format == 0)
{
if (width == 1 || rdp.hires_tex->width == width)
{
shift = addr - rdp.hires_tex->addr;
if (!rdp.motionblur)
rdp.cur_tex_buf = index;
found = TRUE;
// FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.hires_tex->tmu, j);
}
else //new texture is loaded into this place, texture buffer is not valid anymore
{
rdp.texbufs[index].count--;
if (j < rdp.texbufs[index].count)
memcpy(&(rdp.texbufs[index].images[j]), &(rdp.texbufs[index].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[index].count-j));
}
}
}
}
if (found)
{
rdp.hires_tex->tile_uls = 0;
rdp.hires_tex->tile_ult = 0;
if (shift > 0)
{
shift >>= 1;
rdp.hires_tex->v_shift = shift / rdp.hires_tex->width;
rdp.hires_tex->u_shift = shift % rdp.hires_tex->width;
}
else
{
rdp.hires_tex->v_shift = 0;
rdp.hires_tex->u_shift = 0;
}
/*
if (rdp.timg.format == 0) //RGB
rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
else //IA
rdp.hires_tex->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
*/
FRDP("FindTextureBuffer, found, v_shift: %d, format: %d\n", rdp.hires_tex->v_shift, rdp.hires_tex->info.format);
return TRUE;
}
rdp.hires_tex = 0;
RDP("FindTextureBuffer, not found\n");
return FALSE;
}

View File

@ -0,0 +1,54 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
//****************************************************************
//
// Dec 2003 created by Gonetz
//
//****************************************************************
#ifndef TEXBUFFER_H
#define TEXBUFFER_H
#include "winlnxdefs.h"
#include "rdp.h"
BOOL OpenTextureBuffer(COLOR_IMAGE & cimage);
BOOL CloseTextureBuffer(BOOL draw = FALSE);
BOOL CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to);
BOOL SwapTextureBuffer();
BOOL FindTextureBuffer(DWORD addr, WORD width);
#endif // ifndef TEXBUFFER

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#ifndef TEXCACHE_H
#define TEXCACHE_H
void TexCacheInit ();
void TexCache ();
void ClearCache ();
#endif //TEXCACHE_H

View File

@ -0,0 +1,459 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
void TexConv_ARGB1555_ARGB4444 (unsigned char * _src, unsigned char * _dst, int width, int height)
{
int _size = (width * height) << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [_src]
mov edi,dword ptr [_dst]
mov ecx,dword ptr [_size]
tc1_loop:
mov eax,dword ptr [esi]
add esi,4
// arrr rrgg gggb bbbb
// aaaa rrrr gggg bbbb
mov edx,eax
and eax,0x80008000
mov ebx,eax // ebx = 0xa000000000000000
shr eax,1
or ebx,eax // ebx = 0xaa00000000000000
shr eax,1
or ebx,eax // ebx = 0xaaa0000000000000
shr eax,1
or ebx,eax // ebx = 0xaaaa000000000000
mov eax,edx
and eax,0x78007800 // eax = 0x0rrrr00000000000
shr eax,3 // eax = 0x0000rrrr00000000
or ebx,eax // ebx = 0xaaaarrrr00000000
mov eax,edx
and eax,0x03c003c0 // eax = 0x000000gggg000000
shr eax,2 // eax = 0x00000000gggg0000
or ebx,eax // ebx = 0xaaaarrrrgggg0000
and edx,0x001e001e // edx = 0x00000000000bbbb0
shr edx,1 // edx = 0x000000000000bbbb
or ebx,edx // ebx = 0xaaaarrrrggggbbbb
mov dword ptr [edi],ebx
add edi,4
dec ecx
jnz tc1_loop
}
#elif !defined(NO_ASM)
//printf("TexConv_ARGB1555_ARGB4444\n");
asm volatile (
//"tc1_loop2: \n"
"0: \n"
"mov (%[_src]), %%eax \n"
"add $4, %[_src] \n"
// arrr rrgg gggb bbbb
// aaaa rrrr gggg bbbb
"mov %%eax, %%edx \n"
"and $0x80008000, %%eax \n"
"mov %%eax, %%ecx \n" // ecx = 0xa000000000000000
"shr $1, %%eax \n"
"or %%eax, %%ecx \n" // ecx = 0xaa00000000000000
"shr $1, %%eax \n"
"or %%eax, %%ecx \n" // ecx = 0xaaa0000000000000
"shr $1, %%eax \n"
"or %%eax, %%ecx \n" // ecx = 0xaaaa000000000000
"mov %%edx, %%eax \n"
"and $0x78007800, %%eax \n" // eax = 0x0rrrr00000000000
"shr $3, %%eax \n" // eax = 0x0000rrrr00000000
"or %%eax, %%ecx \n" // ecx = 0xaaaarrrr00000000
"mov %%edx, %%eax \n"
"and $0x03c003c0, %%eax \n" // eax = 0x000000gggg000000
"shr $2, %%eax \n" // eax = 0x00000000gggg0000
"or %%eax, %%ecx \n" // ecx = 0xaaaarrrrgggg0000
"and $0x001e001e, %%edx \n" // edx = 0x00000000000bbbb0
"shr $1, %%edx \n" // edx = 0x000000000000bbbb
"or %%edx, %%ecx \n" // ecx = 0xaaaarrrrggggbbbb
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"decl %[_size] \n"
"jnz 0b \n"
: [_src]"+S"(_src), [_dst]"+D"(_dst), [_size]"+g"(_size)
:
: "memory", "cc", "eax", "edx", "ecx"
);
#endif
}
void TexConv_AI88_ARGB4444 (unsigned char * _src, unsigned char * _dst, int width, int height)
{
int _size = (width * height) << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [_src]
mov edi,dword ptr [_dst]
mov ecx,dword ptr [_size]
tc1_loop:
mov eax,dword ptr [esi]
add esi,4
// aaaa aaaa iiii iiii
// aaaa rrrr gggg bbbb
mov edx,eax
and eax,0xF000F000 // eax = 0xaaaa000000000000
mov ebx,eax // ebx = 0xaaaa000000000000
and edx,0x00F000F0 // edx = 0x00000000iiii0000
shl edx,4 // edx = 0x0000iiii00000000
or ebx,edx // ebx = 0xaaaaiiii00000000
shr edx,4 // edx = 0x00000000iiii0000
or ebx,edx // ebx = 0xaaaaiiiiiiii0000
shr edx,4 // edx = 0x000000000000iiii
or ebx,edx // ebx = 0xaaaaiiiiiiiiiiii
mov dword ptr [edi],ebx
add edi,4
dec ecx
jnz tc1_loop
}
#elif !defined(NO_ASM)
//printf("TexConv_AI88_ARGB4444\n");
asm volatile (
//"tc1_loop3: \n"
"0: \n"
"mov (%[_src]), %%eax \n"
"add $4, %[_src] \n"
// aaaa aaaa iiii iiii
// aaaa rrrr gggg bbbb
"mov %%eax, %%edx \n"
"and $0xF000F000, %%eax \n" // eax = 0xaaaa000000000000
"mov %%eax, %%ecx \n" // ecx = 0xaaaa000000000000
"and $0x00F000F0, %%edx \n" // edx = 0x00000000iiii0000
"shl $4, %%edx \n" // edx = 0x0000iiii00000000
"or %%edx, %%ecx \n" // ecx = 0xaaaaiiii00000000
"shr $4, %%edx \n" // edx = 0x00000000iiii0000
"or %%edx, %%ecx \n" // ecx = 0xaaaaiiiiiiii0000
"shr $4, %%edx \n" // edx = 0x000000000000iiii
"or %%edx, %%ecx \n" // ecx = 0xaaaaiiiiiiiiiiii
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"decl %[_size] \n"
"jnz 0b \n"
: [_src]"+S"(_src), [_dst]"+D"(_dst), [_size]"+g"(_size)
:
: "memory", "cc", "eax", "edx", "ecx"
);
#endif
}
void TexConv_AI44_ARGB4444 (unsigned char * _src, unsigned char * _dst, int width, int height)
{
int _size = width * height;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [_src]
mov edi,dword ptr [_dst]
mov ecx,dword ptr [_size]
tc1_loop:
mov eax,dword ptr [esi]
add esi,4
// aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
// aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0
// aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2
mov edx,eax // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
shl eax,16 // eax = aaaa1 iiii1 aaaa0 iiii0 0000 0000 0000 0000
and eax,0xFF000000 // eax = aaaa1 iiii1 0000 0000 0000 0000 0000 0000
mov ebx,eax // ebx = aaaa1 iiii1 0000 0000 0000 0000 0000 0000
and eax,0x0F000000 // eax = 0000 iiii1 0000 0000 0000 0000 0000 0000
shr eax,4 // eax = 0000 0000 iiii1 0000 0000 0000 0000 0000
or ebx,eax // ebx = aaaa1 iiii1 iiii1 0000 0000 0000 0000 0000
shr eax,4 // eax = 0000 0000 0000 iiii1 0000 0000 0000 0000
or ebx,eax // ebx = aaaa1 iiii1 iiii1 iiii1 0000 0000 0000 0000
mov eax,edx // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
shl eax,8 // eax = aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 0000 0000
and eax,0x0000FF00 // eax = 0000 0000 0000 0000 aaaa0 iiii0 0000 0000
or ebx,eax // ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 0000 0000
and eax,0x00000F00 // eax = 0000 0000 0000 0000 0000 iiii0 0000 0000
shr eax,4 // eax = 0000 0000 0000 0000 0000 0000 iiii0 0000
or ebx,eax // ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 0000
shr eax,4 // eax = 0000 0000 0000 0000 0000 0000 0000 iiii0
or ebx,eax // ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 iiii0
mov dword ptr [edi],ebx
add edi,4
mov eax,edx // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
and eax,0xFF000000 // eax = aaaa3 iiii3 0000 0000 0000 0000 0000 0000
mov ebx,eax // ebx = aaaa3 iiii3 0000 0000 0000 0000 0000 0000
and eax,0x0F000000 // eax = 0000 iiii3 0000 0000 0000 0000 0000 0000
shr eax,4 // eax = 0000 0000 iiii3 0000 0000 0000 0000 0000
or ebx,eax // ebx = aaaa3 iiii3 iiii3 0000 0000 0000 0000 0000
shr eax,4 // eax = 0000 0000 0000 iiii3 0000 0000 0000 0000
or ebx,eax // ebx = aaaa3 iiii3 iiii3 iiii3 0000 0000 0000 0000
// edx = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
shr edx,8 // edx = 0000 0000 aaaa3 aaaa3 aaaa2 iiii2 aaaa1 iiii1
and edx,0x0000FF00 // edx = 0000 0000 0000 0000 aaaa2 iiii2 0000 0000
or ebx,edx // ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 0000 0000
and edx,0x00000F00 // edx = 0000 0000 0000 0000 0000 iiii2 0000 0000
shr edx,4 // edx = 0000 0000 0000 0000 0000 0000 iiii2 0000
or ebx,edx // ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 0000
shr edx,4 // edx = 0000 0000 0000 0000 0000 0000 0000 iiii2
or ebx,edx // ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 iiii2
mov dword ptr [edi],ebx
add edi,4
dec ecx
jnz tc1_loop
}
#elif !defined(NO_ASM)
//printf("TexConv_AI44_ARGB4444\n");
asm volatile (
//"tc1_loop4: \n"
"0: \n"
"mov (%[_src]), %%eax \n"
"add $4, %[_src] \n"
// aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
// aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0
// aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2
"mov %%eax, %%edx \n" // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
"shl $16, %%eax \n" // eax = aaaa1 iiii1 aaaa0 iiii0 0000 0000 0000 0000
"and $0xFF000000, %%eax \n" // eax = aaaa1 iiii1 0000 0000 0000 0000 0000 0000
"mov %%eax, %%ecx \n" // ecx = aaaa1 iiii1 0000 0000 0000 0000 0000 0000
"and $0x0F000000, %%eax \n" // eax = 0000 iiii1 0000 0000 0000 0000 0000 0000
"shr $4, %%eax \n" // eax = 0000 0000 iiii1 0000 0000 0000 0000 0000
"or %%eax, %%ecx \n" // ecx = aaaa1 iiii1 iiii1 0000 0000 0000 0000 0000
"shr $4, %%eax \n" // eax = 0000 0000 0000 iiii1 0000 0000 0000 0000
"or %%eax, %%ecx \n" // ecx = aaaa1 iiii1 iiii1 iiii1 0000 0000 0000 0000
"mov %%edx, %%eax \n" // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
"shl $8, %%eax \n" // eax = aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 0000 0000
"and $0x0000FF00, %%eax \n" // eax = 0000 0000 0000 0000 aaaa0 iiii0 0000 0000
"or %%eax, %%ecx \n" // ecx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 0000 0000
"and $0x00000F00, %%eax \n" // eax = 0000 0000 0000 0000 0000 iiii0 0000 0000
"shr $4, %%eax \n" // eax = 0000 0000 0000 0000 0000 0000 iiii0 0000
"or %%eax, %%ecx \n" // ecx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 0000
"shr $4, %%eax \n" // eax = 0000 0000 0000 0000 0000 0000 0000 iiii0
"or %%eax, %%ecx \n" // ecx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 iiii0
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"mov %%edx, %%eax \n" // eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
"and $0xFF000000, %%eax \n" // eax = aaaa3 iiii3 0000 0000 0000 0000 0000 0000
"mov %%eax, %%ecx \n" // ecx = aaaa3 iiii3 0000 0000 0000 0000 0000 0000
"and $0x0F000000, %%eax \n" // eax = 0000 iiii3 0000 0000 0000 0000 0000 0000
"shr $4, %%eax \n" // eax = 0000 0000 iiii3 0000 0000 0000 0000 0000
"or %%eax, %%ecx \n" // ecx = aaaa3 iiii3 iiii3 0000 0000 0000 0000 0000
"shr $4, %%eax \n" // eax = 0000 0000 0000 iiii3 0000 0000 0000 0000
"or %%eax, %%ecx \n" // ecx = aaaa3 iiii3 iiii3 iiii3 0000 0000 0000 0000
// edx = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0
"shr $8, %%edx \n" // edx = 0000 0000 aaaa3 aaaa3 aaaa2 iiii2 aaaa1 iiii1
"and $0x0000FF00, %%edx \n" // edx = 0000 0000 0000 0000 aaaa2 iiii2 0000 0000
"or %%edx, %%ecx \n" // ecx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 0000 0000
"and $0x00000F00, %%edx \n" // edx = 0000 0000 0000 0000 0000 iiii2 0000 0000
"shr $4, %%edx \n" // edx = 0000 0000 0000 0000 0000 0000 iiii2 0000
"or %%edx, %%ecx \n" // ecx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 0000
"shr $4, %%edx \n" // edx = 0000 0000 0000 0000 0000 0000 0000 iiii2
"or %%edx, %%ecx \n" // ecx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 iiii2
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"decl %[_size] \n"
"jnz 0b \n"
: [_src]"+S"(_src), [_dst]"+D"(_dst), [_size]"+g"(_size)
:
: "memory", "cc", "eax", "edx", "ecx"
);
#endif
}
void TexConv_A8_ARGB4444 (unsigned char * _src, unsigned char * _dst, int width, int height)
{
int _size = (width * height) << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [_src]
mov edi,dword ptr [_dst]
mov ecx,dword ptr [_size]
tc1_loop:
mov eax,dword ptr [esi]
add esi,4
// aaaa3 aaaa3 aaaa2 aaaa2 aaaa1 aaaa1 aaaa0 aaaa0
// aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0
// aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2
mov edx,eax
and eax,0x0000F000 // eax = 00 00 00 00 a1 00 00 00
shl eax,16 // eax = a1 00 00 00 00 00 00 00
mov ebx,eax // ebx = a1 00 00 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a1 a1 00 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a1 a1 a1 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a1 a1 a1 a1 00 00 00 00
mov eax,edx
and eax,0x000000F0 // eax = 00 00 00 00 00 00 a0 00
shl eax,8 // eax = 00 00 00 00 a0 00 00 00
or ebx,eax
shr eax,4
or ebx,eax
shr eax,4
or ebx,eax
shr eax,4
or ebx,eax // ebx = a1 a1 a1 a1 a0 a0 a0 a0
mov dword ptr [edi],ebx
add edi,4
mov eax,edx // eax = a3 a3 a2 a2 a1 a1 a0 a0
and eax,0xF0000000 // eax = a3 00 00 00 00 00 00 00
mov ebx,eax // ebx = a3 00 00 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a3 a3 00 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a3 a3 a3 00 00 00 00 00
shr eax,4
or ebx,eax // ebx = a3 a3 a3 a3 00 00 00 00
and edx,0x00F00000 // eax = 00 00 a2 00 00 00 00 00
shr edx,8 // eax = 00 00 00 00 a2 00 00 00
or ebx,edx
shr edx,4
or ebx,edx
shr edx,4
or ebx,edx
shr edx,4
or ebx,edx // ebx = a3 a3 a3 a3 a2 a2 a2 a2
mov dword ptr [edi],ebx
add edi,4
dec ecx
jnz tc1_loop
}
#elif !defined(NO_ASM)
//printf("TexConv_A8_ARGB4444\n");
asm volatile (
//"tc1_loop: \n"
"0: \n"
"mov (%[src]), %%eax \n"
"add $4, %[src] \n"
// aaaa3 aaaa3 aaaa2 aaaa2 aaaa1 aaaa1 aaaa0 aaaa0
// aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0
// aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2
"mov %%eax, %%edx \n"
"and $0x0000F000, %%eax \n" // eax = 00 00 00 00 a1 00 00 00
"shl $16, %%eax \n" // eax = a1 00 00 00 00 00 00 00
"mov %%eax, %%ecx \n" // ecx = a1 00 00 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a1 a1 00 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a1 a1 a1 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a1 a1 a1 a1 00 00 00 00
"mov %%edx, %%eax \n"
"and $0x000000F0, %%eax \n" // eax = 00 00 00 00 00 00 a0 00
"shl $8, %%eax \n" // eax = 00 00 00 00 a0 00 00 00
"or %%eax, %%ecx \n"
"shr $4, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a1 a1 a1 a1 a0 a0 a0 a0
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"mov %%edx, %%eax \n" // eax = a3 a3 a2 a2 a1 a1 a0 a0
"and $0xF0000000, %%eax \n" // eax = a3 00 00 00 00 00 00 00
"mov %%eax, %%ecx \n" // ecx = a3 00 00 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a3 a3 00 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a3 a3 a3 00 00 00 00 00
"shr $4, %%eax \n"
"or %%eax, %%ecx \n" // ecx = a3 a3 a3 a3 00 00 00 00
"and $0x00F00000, %%edx \n" // eax = 00 00 a2 00 00 00 00 00
"shr $8, %%edx \n" // eax = 00 00 00 00 a2 00 00 00
"or %%edx, %%ecx \n"
"shr $4, %%edx \n"
"or %%edx, %%ecx \n"
"shr $4, %%edx \n"
"or %%edx, %%ecx \n"
"shr $4, %%edx \n"
"or %%edx, %%ecx \n" // ecx = a3 a3 a3 a3 a2 a2 a2 a2
"mov %%ecx, (%[_dst]) \n"
"add $4, %[_dst] \n"
"decl %[_size] \n"
"jnz 0b \n"
: [src]"+S"(_src), [_dst]"+D"(_dst), [_size]"+g"(_size)
:
: "memory", "cc", "eax", "ecx", "edx"
);
#endif
}

View File

@ -0,0 +1,59 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#include "TexLoad4b.h"
#include "TexLoad8b.h"
#include "TexLoad16b.h"
#include "TexLoad32b.h"
#ifndef _WIN32
#include <string.h>
#endif // _WIN32
DWORD LoadNone (unsigned char * dst, unsigned char * src, int wid_64, int height, int line, int real_width, int tile)
{
memset (texture, 0xFF, sizeof(texture));
return GR_TEXFMT_ARGB_1555;
}
typedef DWORD (*texfunc)(unsigned char *, unsigned char *, int, int, int, int, int);
texfunc load_table [4][5] = { // [size][format]
{ Load4bSelect, LoadNone, Load4bCI, Load4bIA, Load4bI},
{ Load8bCI, LoadNone, Load8bCI, Load8bIA, Load8bI},
{ Load16bRGBA, LoadNone, LoadNone, Load16bIA, LoadNone},
{ Load32bRGBA, LoadNone, LoadNone, LoadNone, LoadNone}
};

View File

@ -0,0 +1,357 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//****************************************************************
// Size: 2, Format: 0
DWORD Load16bRGBA (unsigned char * dst, unsigned char * src, int wid_64, int height, int line, int real_width, int tile)
{
if (wid_64 < 1) wid_64 = 1;
if (height < 1) height = 1;
int ext = (real_width - (wid_64 << 2)) << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [src]
mov edi,dword ptr [dst]
mov ecx,dword ptr [height]
y_loop:
push ecx
mov ecx,dword ptr [wid_64]
x_loop:
mov eax,dword ptr [esi] // read both pixels
add esi,4
bswap eax
mov edx,eax
ror ax,1
ror eax,16
ror ax,1
mov dword ptr [edi],eax
add edi,4
// * copy
mov eax,dword ptr [esi] // read both pixels
add esi,4
bswap eax
mov edx,eax
ror ax,1
ror eax,16
ror ax,1
mov dword ptr [edi],eax
add edi,4
// *
dec ecx
jnz x_loop
pop ecx
dec ecx
jz end_y_loop
push ecx
add esi,dword ptr [line]
add edi,dword ptr [ext]
mov ecx,dword ptr [wid_64]
x_loop_2:
mov eax,dword ptr [esi+4] // read both pixels
bswap eax
mov edx,eax
ror ax,1
ror eax,16
ror ax,1
mov dword ptr [edi],eax
add edi,4
// * copy
mov eax,dword ptr [esi] // read both pixels
add esi,8
bswap eax
mov edx,eax
ror ax,1
ror eax,16
ror ax,1
mov dword ptr [edi],eax
add edi,4
// *
dec ecx
jnz x_loop_2
add esi,dword ptr [line]
add edi,dword ptr [ext]
pop ecx
dec ecx
jnz y_loop
end_y_loop:
}
#elif !defined(NO_ASM)
//printf("Load16bRGBA\n");
long lTemp, lHeight = (long) height;
asm volatile (
"y_loop7: \n"
"mov %[c], %[temp] \n"
"mov %[wid_64], %%ecx \n"
"x_loop7: \n"
"mov (%[src]), %%eax \n" // read both pixels
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"ror $1, %%ax \n"
"ror $16, %%eax \n"
"ror $1, %%ax \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read both pixels
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"ror $1, %%ax \n"
"ror $16, %%eax \n"
"ror $1, %%ax \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"dec %%ecx \n"
"jnz x_loop7 \n"
"mov %[temp], %[c] \n"
"dec %%ecx \n"
"jz end_y_loop7 \n"
"mov %[c], %[temp] \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"mov %[wid_64], %%ecx \n"
"x_loop_27: \n"
"mov 4(%[src]), %%eax \n" // read both pixels
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"ror $1, %%ax \n"
"ror $16, %%eax \n"
"ror $1, %%ax \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read both pixels
"add $8, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"ror $1, %%ax \n"
"ror $16, %%eax \n"
"ror $1, %%ax \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"dec %%ecx \n"
"jnz x_loop_27 \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"mov %[temp], %[c] \n"
"dec %%ecx \n"
"jnz y_loop7 \n"
"end_y_loop7: \n"
: [temp]"=m"(lTemp), [src]"+S"(src), [dst]"+D"(dst), [c]"+c"(lHeight)
: [wid_64] "g" (wid_64), [line] "g" ((uintptr_t)line), [ext] "g" ((uintptr_t)ext)
: "memory", "cc", "eax", "edx"
);
#endif
return (1 << 16) | GR_TEXFMT_ARGB_1555;
}
//****************************************************************
// Size: 2, Format: 3
//
// ** by Gugaman/Dave2001 **
DWORD Load16bIA (unsigned char * dst, unsigned char * src, int wid_64, int height, int line, int real_width, int tile)
{
if (wid_64 < 1) wid_64 = 1;
if (height < 1) height = 1;
int ext = (real_width - (wid_64 << 2)) << 1;
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [src]
mov edi,dword ptr [dst]
mov ecx,dword ptr [height]
y_loop:
push ecx
mov ecx,dword ptr [wid_64]
x_loop:
mov eax,dword ptr [esi] // read both pixels
add esi,4
mov dword ptr [edi],eax
add edi,4
// * copy
mov eax,dword ptr [esi] // read both pixels
add esi,4
mov dword ptr [edi],eax
add edi,4
// *
dec ecx
jnz x_loop
pop ecx
dec ecx
jz end_y_loop
push ecx
add esi,dword ptr [line]
add edi,dword ptr [ext]
mov ecx,dword ptr [wid_64]
x_loop_2:
mov eax,dword ptr [esi+4] // read both pixels
mov dword ptr [edi],eax
add edi,4
// * copy
mov eax,dword ptr [esi] // read both pixels
add esi,8
mov dword ptr [edi],eax
add edi,4
// *
dec ecx
jnz x_loop_2
add esi,dword ptr [line]
add edi,dword ptr [ext]
pop ecx
dec ecx
jnz y_loop
end_y_loop:
}
#elif !defined(NO_ASM)
//printf("Load16bIA\n");
long lTemp, lHeight = (long) height;
asm volatile (
"y_loop8: \n"
"mov %[c], %[temp] \n"
"mov %[wid_64], %%ecx \n"
"x_loop8: \n"
"mov (%[src]), %%eax \n" // read both pixels
"add $4, %[src] \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read both pixels
"add $4, %[src] \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"dec %%ecx \n"
"jnz x_loop8 \n"
"mov %[temp], %[c] \n"
"dec %%ecx \n"
"jz end_y_loop8 \n"
"mov %[c], %[temp] \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"mov %[wid_64], %%ecx \n"
"x_loop_28: \n"
"mov 4(%[src]), %%eax \n" // read both pixels
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read both pixels
"add $8, %[src] \n"
"mov %%eax, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"dec %%ecx \n"
"jnz x_loop_28 \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"mov %[temp], %[c] \n"
"dec %%ecx \n"
"jnz y_loop8 \n"
"end_y_loop8: \n"
: [temp]"=m"(lTemp), [src]"+S"(src), [dst]"+D"(dst), [c]"+c"(lHeight)
: [wid_64] "g" (wid_64), [line] "g" ((uintptr_t)line), [ext] "g" ((uintptr_t)ext)
: "memory", "cc", "eax"
);
#endif
return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88;
}

View File

@ -0,0 +1,472 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//****************************************************************
// Size: 2, Format: 0
DWORD Load32bRGBA (unsigned char * dst, unsigned char * src, int wid_64, int height, int line, int real_width, int tile)
{
if (wid_64 < 1) wid_64 = 1;
if (height < 1) height = 1;
int ext = (real_width - (wid_64 << 1)) << 1;
wid_64 >>= 1; // re-shift it, load twice as many quadwords
#if !defined(__GNUC__) && !defined(NO_ASM)
__asm {
mov esi,dword ptr [src]
mov edi,dword ptr [dst]
mov ecx,dword ptr [height]
y_loop:
push ecx
mov ecx,dword ptr [wid_64]
x_loop:
mov eax,dword ptr [esi] // read first pixel
add esi,4
bswap eax
mov edx,eax
xor ebx,ebx
shl eax,8 // 0x000000F0 -> 0x0000F000 (a)
and eax,0x0000F000
or ebx,eax
shr edx,12 // 0x0000F000 -> 0x0000000F (b)
mov eax,edx
and eax,0x0000000F
or ebx,eax
shr edx,4 // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
mov eax,edx
and eax,0x000000F0
or ebx,eax
shr edx,4 // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
and edx,0x00000F00
or ebx,edx
mov eax,dword ptr [esi] // read second pixel
add esi,4
bswap eax
mov edx,eax
shl eax,24 // 0x000000F0 -> 0xF0000000 (a)
and eax,0xF0000000
or ebx,eax
// 0x00F00000 -> 0x00F00000 (g)
mov eax,edx
and eax,0x00F00000
or ebx,eax
rol edx,4 // 0x0000F000 (did not shift) -> 0x000F0000 (b)
mov eax,edx
and eax,0x000F0000
or ebx,eax
shl edx,24 // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
and edx,0x0F000000
or ebx,edx
mov dword ptr [edi],ebx
add edi,4
// * copy
mov eax,dword ptr [esi] // read first pixel
add esi,4
bswap eax
mov edx,eax
xor ebx,ebx
shl eax,8 // 0x000000F0 -> 0x0000F000 (a)
and eax,0x0000F000
or ebx,eax
shr edx,12 // 0x0000F000 -> 0x0000000F (b)
mov eax,edx
and eax,0x0000000F
or ebx,eax
shr edx,4 // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
mov eax,edx
and eax,0x000000F0
or ebx,eax
shr edx,4 // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
and edx,0x00000F00
or ebx,edx
mov eax,dword ptr [esi] // read second pixel
add esi,4
bswap eax
mov edx,eax
shl eax,24 // 0x000000F0 -> 0xF0000000 (a)
and eax,0xF0000000
or ebx,eax
// 0x00F00000 -> 0x00F00000 (g)
mov eax,edx
and eax,0x00F00000
or ebx,eax
rol edx,4 // 0x0000F000 (did not shift) -> 0x000F0000 (b)
mov eax,edx
and eax,0x000F0000
or ebx,eax
shl edx,24 // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
and edx,0x0F000000
or ebx,edx
mov dword ptr [edi],ebx
add edi,4
// *
dec ecx
jnz x_loop
pop ecx
dec ecx
jz end_y_loop
push ecx
add esi,dword ptr [line]
add edi,dword ptr [ext]
mov ecx,dword ptr [wid_64]
x_loop_2:
mov eax,dword ptr [esi+8] // read first pixel
bswap eax
mov edx,eax
xor ebx,ebx
shl eax,8 // 0x000000F0 -> 0x0000F000 (a)
and eax,0x0000F000
or ebx,eax
shr edx,12 // 0x0000F000 -> 0x0000000F (b)
mov eax,edx
and eax,0x0000000F
or ebx,eax
shr edx,4 // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
mov eax,edx
and eax,0x000000F0
or ebx,eax
shr edx,4 // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
and edx,0x00000F00
or ebx,edx
mov eax,dword ptr [esi+12] // read second pixel
bswap eax
mov edx,eax
shl eax,24 // 0x000000F0 -> 0xF0000000 (a)
and eax,0xF0000000
or ebx,eax
// 0x00F00000 -> 0x00F00000 (g)
mov eax,edx
and eax,0x00F00000
or ebx,eax
rol edx,4 // 0x0000F000 (did not shift) -> 0x000F0000 (b)
mov eax,edx
and eax,0x000F0000
or ebx,eax
shl edx,24 // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
and edx,0x0F000000
or ebx,edx
mov dword ptr [edi],ebx
add edi,4
// * copy
mov eax,dword ptr [esi+0] // read first pixel
bswap eax
mov edx,eax
xor ebx,ebx
shl eax,8 // 0x000000F0 -> 0x0000F000 (a)
and eax,0x0000F000
or ebx,eax
shr edx,12 // 0x0000F000 -> 0x0000000F (b)
mov eax,edx
and eax,0x0000000F
or ebx,eax
shr edx,4 // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
mov eax,edx
and eax,0x000000F0
or ebx,eax
shr edx,4 // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
and edx,0x00000F00
or ebx,edx
mov eax,dword ptr [esi+4] // read second pixel
add esi,16
bswap eax
mov edx,eax
shl eax,24 // 0x000000F0 -> 0xF0000000 (a)
and eax,0xF0000000
or ebx,eax
// 0x00F00000 -> 0x00F00000 (g)
mov eax,edx
and eax,0x00F00000
or ebx,eax
rol edx,4 // 0x0000F000 (did not shift) -> 0x000F0000 (b)
mov eax,edx
and eax,0x000F0000
or ebx,eax
shl edx,24 // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
and edx,0x0F000000
or ebx,edx
mov dword ptr [edi],ebx
add edi,4
// *
dec ecx
jnz x_loop_2
add esi,dword ptr [line]
add edi,dword ptr [ext]
pop ecx
dec ecx
jnz y_loop
end_y_loop:
}
#elif !defined(NO_ASM)
//printf("Load32bRGBA\n");
int lTemp, lHeight = (int) height;
asm volatile (
"y_loop9: \n"
"mov %[wid_64], %%eax \n"
"mov %%eax, %[temp] \n"
"x_loop9: \n"
"mov (%[src]), %%eax \n" // read first pixel
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"xor %%ecx, %%ecx \n"
"shl $8, %%eax \n" // 0x000000F0 -> 0x0000F000 (a)
"and $0x0000F000, %%eax \n"
"or %%eax, %%ecx \n"
"shr $12, %%edx \n" // 0x0000F000 -> 0x0000000F (b)
"mov %%edx, %%eax \n"
"and $0x0000000F, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
"mov %%edx, %%eax \n"
"and $0x000000F0, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
"and $0x00000F00, %%edx \n"
"or %%edx, %%ecx \n"
"mov (%[src]), %%eax \n" // read second pixel
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"shl $24, %%eax \n" // 0x000000F0 -> 0xF0000000 (a)
"and $0xF0000000, %%eax \n"
"or %%eax, %%ecx \n" // 0x00F00000 -> 0x00F00000 (g)
"mov %%edx, %%eax \n"
"and $0x00F00000, %%eax \n"
"or %%eax, %%ecx \n"
"rol $4, %%edx \n" // 0x0000F000 (did not shift) -> 0x000F0000 (b)
"mov %%edx, %%eax \n"
"and $0x000F0000, %%eax \n"
"or %%eax, %%ecx \n"
"shl $24, %%edx \n" // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
"and $0x0F000000, %%edx \n"
"or %%edx, %%ecx \n"
"mov %%ecx, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read first pixel
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"xor %%ecx, %%ecx \n"
"shl $8, %%eax \n" // 0x000000F0 -> 0x0000F000 (a)
"and $0x0000F000, %%eax \n"
"or %%eax, %%ecx \n"
"shr $12, %%edx \n" // 0x0000F000 -> 0x0000000F (b)
"mov %%edx, %%eax \n"
"and $0x0000000F, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
"mov %%edx, %%eax \n"
"and $0x000000F0, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
"and $0x00000F00, %%edx \n"
"or %%edx, %%ecx \n"
"mov (%[src]), %%eax \n" // read second pixel
"add $4, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"shl $24, %%eax \n" // 0x000000F0 -> 0xF0000000 (a)
"and $0xF0000000, %%eax \n"
"or %%eax, %%ecx \n" // 0x00F00000 -> 0x00F00000 (g)
"mov %%edx, %%eax \n"
"and $0x00F00000, %%eax \n"
"or %%eax, %%ecx \n"
"rol $4, %%edx \n" // 0x0000F000 (did not shift) -> 0x000F0000 (b)
"mov %%edx, %%eax \n"
"and $0x000F0000, %%eax \n"
"or %%eax, %%ecx \n"
"shl $24, %%edx \n" // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
"and $0x0F000000, %%edx \n"
"or %%edx, %%ecx \n"
"mov %%ecx, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"decl %[temp] \n"
"jnz x_loop9 \n"
"decl %[height] \n"
"jz end_y_loop9 \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"mov %[wid_64], %%eax \n"
"mov %%eax, %[temp] \n"
"x_loop_29: \n"
"mov 8(%[src]), %%eax \n" // read first pixel
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"xor %%ecx, %%ecx \n"
"shl $8, %%eax \n" // 0x000000F0 -> 0x0000F000 (a)
"and $0x0000F000, %%eax \n"
"or %%eax, %%ecx \n"
"shr $12, %%edx \n" // 0x0000F000 -> 0x0000000F (b)
"mov %%edx, %%eax \n"
"and $0x0000000F, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
"mov %%edx, %%eax \n"
"and $0x000000F0, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
"and $0x00000F00, %%edx \n"
"or %%edx, %%ecx \n"
"mov 12(%[src]), %%eax \n" // read second pixel
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"shl $24, %%eax \n" // 0x000000F0 -> 0xF0000000 (a)
"and $0xF0000000, %%eax \n"
"or %%eax, %%ecx \n" // 0x00F00000 -> 0x00F00000 (g)
"mov %%edx, %%eax \n"
"and $0x00F00000, %%eax \n"
"or %%eax, %%ecx \n"
"rol $4, %%edx \n" // 0x0000F000 (did not shift) -> 0x000F0000 (b)
"mov %%edx, %%eax \n"
"and $0x000F0000, %%eax \n"
"or %%eax, %%ecx \n"
"shl $24, %%edx \n" // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
"and $0x0F000000, %%edx \n"
"or %%edx, %%ecx \n"
"mov %%ecx, (%[dst]) \n"
"add $4, %[dst] \n"
// * copy
"mov (%[src]), %%eax \n" // read first pixel
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"xor %%ecx, %%ecx \n"
"shl $8, %%eax \n" // 0x000000F0 -> 0x0000F000 (a)
"and $0x0000F000, %%eax \n"
"or %%eax, %%ecx \n"
"shr $12, %%edx \n" // 0x0000F000 -> 0x0000000F (b)
"mov %%edx, %%eax \n"
"and $0x0000000F, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0x00F00000 went to 0x00000F00 -> 0x000000F0 (g)
"mov %%edx, %%eax \n"
"and $0x000000F0, %%eax \n"
"or %%eax, %%ecx \n"
"shr $4, %%edx \n" // 0xF0000000 went to 0x000F0000 went to 0x0000F000 -> 0x00000F00 (r)
"and $0x00000F00, %%edx \n"
"or %%edx, %%ecx \n"
"mov 4(%[src]), %%eax \n" // read second pixel
"add $16, %[src] \n"
"bswap %%eax \n"
"mov %%eax, %%edx \n"
"shl $24, %%eax \n" // 0x000000F0 -> 0xF0000000 (a)
"and $0xF0000000, %%eax \n"
"or %%eax, %%ecx \n" // 0x00F00000 -> 0x00F00000 (g)
"mov %%edx, %%eax \n"
"and $0x00F00000, %%eax \n"
"or %%eax, %%ecx \n"
"rol $4, %%edx \n" // 0x0000F000 (did not shift) -> 0x000F0000 (b)
"mov %%edx, %%eax \n"
"and $0x000F0000, %%eax \n"
"or %%eax, %%ecx \n"
"shl $24, %%edx \n" // 0xF0000000 went to 0x0000000F -> 0x0F000000 (r)
"and $0x0F000000, %%edx \n"
"or %%edx, %%ecx \n"
"mov %%ecx, (%[dst]) \n"
"add $4, %[dst] \n"
// *
"decl %[temp] \n"
"jnz x_loop_29 \n"
"add %[line], %[src] \n"
"add %[ext], %[dst] \n"
"decl %[height] \n"
"jnz y_loop9 \n"
"end_y_loop9: \n"
: [temp]"=m"(lTemp), [src]"+S"(src), [dst]"+D"(dst), [height]"+g"(lHeight)
: [wid_64] "g" (wid_64), [line] "g" ((uintptr_t)line), [ext] "g" ((uintptr_t)ext)
: "memory", "cc", "ecx", "eax", "edx"
);
#endif
return (1 << 16) | GR_TEXFMT_ARGB_4444;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,571 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#ifndef _WIN32
#include <stdlib.h>
#endif
static void mod_tex_inter_color_using_factor (WORD *dst, int size, DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
float percent_i = 1 - percent;
DWORD cr, cg, cb;
WORD col, a;
BYTE r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
r = (BYTE)(percent_i * ((col >> 8) & 0xF) + percent * cr);
g = (BYTE)(percent_i * ((col >> 4) & 0xF) + percent * cg);
b = (BYTE)(percent_i * (col & 0xF) + percent * cb);
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_inter_col_using_col1 (WORD *dst, int size, DWORD color0, DWORD color1)
{
DWORD cr, cg, cb;
WORD col, a;
BYTE r, g, b;
float percent_r = ((color1 >> 12) & 0xF) / 15.0f;
float percent_g = ((color1 >> 8) & 0xF) / 15.0f;
float percent_b = ((color1 >> 4) & 0xF) / 15.0f;
float percent_r_i = 1.0f - percent_r;
float percent_g_i = 1.0f - percent_g;
float percent_b_i = 1.0f - percent_b;
cr = (color0 >> 12) & 0xF;
cg = (color0 >> 8) & 0xF;
cb = (color0 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
r = (BYTE)(percent_r_i * ((col >> 8) & 0xF) + percent_r * cr);
g = (BYTE)(percent_g_i * ((col >> 4) & 0xF) + percent_g * cg);
b = (BYTE)(percent_b_i * (col & 0xF) + percent_b * cb);
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_full_color_sub_tex (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb, ca;
WORD col;
BYTE a, r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
ca = color & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)(ca - ((col >> 12) & 0xF));
r = (BYTE)(cr - ((col >> 8) & 0xF));
g = (BYTE)(cg - ((col >> 4) & 0xF));
b = (BYTE)(cb - (col & 0xF));
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
}
}
static void mod_col_inter_col1_using_tex (WORD *dst, int size, DWORD color0, DWORD color1)
{
DWORD cr0, cg0, cb0, cr1, cg1, cb1;
WORD col;
BYTE r, g, b;
WORD a;
float percent_r, percent_g, percent_b;
cr0 = (color0 >> 12) & 0xF;
cg0 = (color0 >> 8) & 0xF;
cb0 = (color0 >> 4) & 0xF;
cr1 = (color1 >> 12) & 0xF;
cg1 = (color1 >> 8) & 0xF;
cb1 = (color1 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent_r = ((col >> 8) & 0xF) / 15.0f;
percent_g = ((col >> 4) & 0xF) / 15.0f;
percent_b = (col & 0xF) / 15.0f;
r = min(15, (BYTE)((1.0f-percent_r) * cr0 + percent_r * cr1));
g = min(15, (BYTE)((1.0f-percent_g) * cg0 + percent_g * cg1));
b = min(15, (BYTE)((1.0f-percent_b) * cb0 + percent_b * cb1));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_col_inter_col1_using_texa (WORD *dst, int size, DWORD color0, DWORD color1)
{
DWORD cr0, cg0, cb0, cr1, cg1, cb1;
WORD col;
BYTE r, g, b;
WORD a;
float percent, percent_i;
cr0 = (color0 >> 12) & 0xF;
cg0 = (color0 >> 8) & 0xF;
cb0 = (color0 >> 4) & 0xF;
cr1 = (color1 >> 12) & 0xF;
cg1 = (color1 >> 8) & 0xF;
cb1 = (color1 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent = (a >> 12) / 15.0f;
percent_i = 1.0f - percent;
r = (BYTE)(percent_i * cr0 + percent * cr1);
g = (BYTE)(percent_i * cg0 + percent * cg1);
b = (BYTE)(percent_i * cb0 + percent * cb1);
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_col_inter_col1_using_texa__mul_tex (WORD *dst, int size, DWORD color0, DWORD color1)
{
DWORD cr0, cg0, cb0, cr1, cg1, cb1;
WORD col;
BYTE r, g, b;
WORD a;
float percent, percent_i;
cr0 = (color0 >> 12) & 0xF;
cg0 = (color0 >> 8) & 0xF;
cb0 = (color0 >> 4) & 0xF;
cr1 = (color1 >> 12) & 0xF;
cg1 = (color1 >> 8) & 0xF;
cb1 = (color1 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent = (a >> 12) / 15.0f;
percent_i = 1.0f - percent;
r = (BYTE)(((percent_i * cr0 + percent * cr1) / 15.0f) * (((col & 0x0F00) >> 8) / 15.0f) * 15.0f);
g = (BYTE)(((percent_i * cg0 + percent * cg1) / 15.0f) * (((col & 0x00F0) >> 4) / 15.0f) * 15.0f);
b = (BYTE)(((percent_i * cb0 + percent * cb1) / 15.0f) * ((col & 0x000F) / 15.0f) * 15.0f);
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_col_inter_tex_using_tex (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb;
WORD col;
BYTE r, g, b;
WORD a;
float percent_r, percent_g, percent_b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent_r = ((col >> 8) & 0xF) / 15.0f;
percent_g = ((col >> 4) & 0xF) / 15.0f;
percent_b = (col & 0xF) / 15.0f;
r = (BYTE)((1.0f-percent_r) * cr + percent_r * ((col & 0x0F00) >> 8));
g = (BYTE)((1.0f-percent_g) * cg + percent_g * ((col & 0x00F0) >> 4));
b = (BYTE)((1.0f-percent_b) * cb + percent_b * (col & 0x000F));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_col_inter_tex_using_texa (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb;
WORD col;
BYTE r, g, b;
WORD a;
float percent, percent_i;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent = (a >> 12) / 15.0f;
percent_i = 1.0f - percent;
r = (BYTE)(percent_i * cr + percent * ((col & 0x0F00) >> 8));
g = (BYTE)(percent_i * cg + percent * ((col & 0x00F0) >> 4));
b = (BYTE)(percent_i * cb + percent * (col & 0x000F));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_col2_inter__col_inter_col1_using_tex__using_texa (WORD *dst, int size,
DWORD color0, DWORD color1,
DWORD color2)
{
DWORD cr0, cg0, cb0, cr1, cg1, cb1, cr2, cg2, cb2;
WORD col;
BYTE r, g, b;
WORD a;
float percent_r, percent_g, percent_b, percent_a;
cr0 = (color0 >> 12) & 0xF;
cg0 = (color0 >> 8) & 0xF;
cb0 = (color0 >> 4) & 0xF;
cr1 = (color1 >> 12) & 0xF;
cg1 = (color1 >> 8) & 0xF;
cb1 = (color1 >> 4) & 0xF;
cr2 = (color2 >> 12) & 0xF;
cg2 = (color2 >> 8) & 0xF;
cb2 = (color2 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent_a = (a >> 12) / 15.0f;
percent_r = ((col >> 8) & 0xF) / 15.0f;
percent_g = ((col >> 4) & 0xF) / 15.0f;
percent_b = (col & 0xF) / 15.0f;
r = (BYTE)(((1.0f-percent_r) * cr0 + percent_r * cr1) * percent_a + cr2 * (1.0f-percent_a));
g = (BYTE)(((1.0f-percent_g) * cg0 + percent_g * cg1) * percent_a + cg2 * (1.0f-percent_a));
b = (BYTE)(((1.0f-percent_b) * cb0 + percent_b * cb1) * percent_a + cb2 * (1.0f-percent_a));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_scale_fac_add_fac (WORD *dst, int size, DWORD factor)
{
float percent = factor / 255.0f;
WORD col;
BYTE a;
float base_a = (1.0f - percent) * 15.0f;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)(base_a + percent * (col>>12));
*(dst++) = (a<<12) | (col & 0x0FFF);
}
}
static void mod_tex_sub_col_mul_fac_add_tex (WORD *dst, int size, DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
DWORD cr, cg, cb;
WORD col, a;
float r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
r = (float)((col >> 8) & 0xF);
r = /*max(*/(r - cr) * percent/*, 0.0f)*/ + r;
if (r > 15.0f) r = 15.0f;
if (r < 0.0f) r = 0.0f;
g = (float)((col >> 4) & 0xF);
g = /*max(*/(g - cg) * percent/*, 0.0f)*/ + g;
if (g > 15.0f) g = 15.0f;
if (g < 0.0f) g = 0.0f;
b = (float)(col & 0xF);
b = /*max(*/(b - cb) * percent/*, 0.0f)*/ + b;
if (b > 15.0f) b = 15.0f;
if (b < 0.0f) b = 0.0f;
*(dst++) = a | ((WORD)r << 8) | ((WORD)g << 4) | (WORD)b;
}
}
static void mod_tex_scale_col_add_col (WORD *dst, int size, DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
float percent_r = (1.0f - ((color>>12)&0xF) / 15.0f) * percent;
float percent_g = (1.0f - ((color>>8)&0xF) / 15.0f) * percent;
float percent_b = (1.0f - ((color>>4)&0xF) / 15.0f) * percent;
WORD col;
float base = (1.0f - percent) * 15.0f;
float r, g, b;
for (int i=0; i<size; i++)
{
col = *dst;
r = base + percent_r * (float)((col>>8)&0xF);
g = base + percent_g * (float)((col>>4)&0xF);
b = base + percent_b * (float)(col&0xF);
*(dst++) = (col&0xF000) | ((BYTE)r << 8) | ((BYTE)g << 4) | (BYTE)b;
}
}
static void mod_tex_add_col (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb;
WORD col;
BYTE a, r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)((col >> 12) & 0xF);
// a = col & 0xF000;
r = (BYTE)(cr + ((col >> 8) & 0xF))&0xF;
g = (BYTE)(cg + ((col >> 4) & 0xF))&0xF;
b = (BYTE)(cb + (col & 0xF))&0xF;
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
}
}
static void mod_col_mul_texa_add_tex (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb;
WORD col;
BYTE r, g, b;
WORD a;
float factor;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
factor = (a >> 12) / 15.0f;
r = (BYTE)(cr*factor + ((col >> 8) & 0xF))&0xF;
g = (BYTE)(cg*factor + ((col >> 4) & 0xF))&0xF;
b = (BYTE)(cb*factor + (col & 0xF))&0xF;
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_sub_col (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb, ca;
WORD col;
BYTE a, r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
ca = color & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)(((col >> 12) & 0xF) - ca);
r = (BYTE)(((col >> 8) & 0xF) - cr);
g = (BYTE)(((col >> 4) & 0xF) - cg);
b = (BYTE)((col & 0xF) - cb);
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_sub_col_mul_fac (WORD *dst, int size, DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
DWORD cr, cg, cb;
WORD col, a;
float r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)((col >> 12) & 0xF);
r = (float)((col >> 8) & 0xF);
r = (r - cr) * percent;
if (r > 15.0f) r = 15.0f;
if (r < 0.0f) r = 0.0f;
g = (float)((col >> 4) & 0xF);
g = (g - cg) * percent;
if (g > 15.0f) g = 15.0f;
if (g < 0.0f) g = 0.0f;
b = (float)(col & 0xF);
b = (b - cb) * percent;
if (b > 15.0f) b = 15.0f;
if (b < 0.0f) b = 0.0f;
*(dst++) = (a << 12) | ((WORD)r << 8) | ((WORD)g << 4) | (WORD)b;
}
}
static void mod_col_inter_tex_using_col1 (WORD *dst, int size, DWORD color0, DWORD color1)
{
DWORD cr, cg, cb;
WORD col, a;
BYTE r, g, b;
float percent_r = ((color1 >> 12) & 0xF) / 15.0f;
float percent_g = ((color1 >> 8) & 0xF) / 15.0f;
float percent_b = ((color1 >> 4) & 0xF) / 15.0f;
float percent_r_i = 1.0f - percent_r;
float percent_g_i = 1.0f - percent_g;
float percent_b_i = 1.0f - percent_b;
cr = (color0 >> 12) & 0xF;
cg = (color0 >> 8) & 0xF;
cb = (color0 >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = (BYTE)((col >> 12) & 0xF);
r = (BYTE)(percent_r * ((col >> 8) & 0xF) + percent_r_i * cr);
g = (BYTE)(percent_g * ((col >> 4) & 0xF) + percent_g_i * cg);
b = (BYTE)(percent_b * (col & 0xF) + percent_b_i * cb);
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_inter_noise_using_col (WORD *dst, int size, DWORD color)
{
WORD col, a;
BYTE r, g, b, noise;
float percent_r = ((color >> 12) & 0xF) / 15.0f;
float percent_g = ((color >> 8) & 0xF) / 15.0f;
float percent_b = ((color >> 4) & 0xF) / 15.0f;
float percent_r_i = 1.0f - percent_r;
float percent_g_i = 1.0f - percent_g;
float percent_b_i = 1.0f - percent_b;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
noise = rand()%16;
r = (BYTE)(percent_r_i * ((col >> 8) & 0xF) + percent_r * noise);
g = (BYTE)(percent_g_i * ((col >> 4) & 0xF) + percent_g * noise);
b = (BYTE)(percent_b_i * (col & 0xF) + percent_b * noise);
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_inter_col_using_texa (WORD *dst, int size, DWORD color)
{
DWORD cr, cg, cb;
WORD col;
BYTE r, g, b;
WORD a;
float percent, percent_i;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
percent = (a >> 12) / 15.0f;
percent_i = 1.0f - percent;
r = (BYTE)(percent * cr + percent_i * ((col & 0x0F00) >> 8));
g = (BYTE)(percent * cg + percent_i * ((col & 0x00F0) >> 4));
b = (BYTE)(percent * cb + percent_i * (col & 0x000F));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_mul_col (WORD *dst, int size, DWORD color)
{
float cr, cg, cb;
WORD col;
BYTE r, g, b;
WORD a;
cr = (float)((color >> 12) & 0xF)/16.0f;
cg = (float)((color >> 8) & 0xF)/16.0f;
cb = (float)((color >> 4) & 0xF)/16.0f;
for (int i=0; i<size; i++)
{
col = *dst;
a = col & 0xF000;
r = (BYTE)(cr * ((col & 0x0F00) >> 8));
g = (BYTE)(cg * ((col & 0x00F0) >> 4));
b = (BYTE)(cb * (col & 0x000F));
*(dst++) = a | (r << 8) | (g << 4) | b;
}
}
static void mod_tex_scale_fac_add_col (WORD *dst, int size, DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
DWORD cr, cg, cb;
WORD col;
float r, g, b;
cr = (color >> 12) & 0xF;
cg = (color >> 8) & 0xF;
cb = (color >> 4) & 0xF;
for (int i=0; i<size; i++)
{
col = *dst;
r = cr + percent * (float)((col>>8)&0xF);
g = cg + percent * (float)((col>>4)&0xF);
b = cb + percent * (float)(col&0xF);
*(dst++) = (col&0xF000) | ((BYTE)r << 8) | ((BYTE)g << 4) | (BYTE)b;
}
}

View File

@ -0,0 +1,438 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#ifndef _WIN32
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif // _WIN32
static void mod_tex_inter_color_using_factor_CI (DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
float percent_i = 1 - percent;
BYTE cr, cg, cb;
WORD col;
BYTE a, r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = (BYTE)(min(255, percent_i * r + percent * cr));
g = (BYTE)(min(255, percent_i * g + percent * cg));
b = (BYTE)(min(255, percent_i * b + percent * cb));
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_tex_inter_col_using_col1_CI (DWORD color0, DWORD color1)
{
BYTE cr, cg, cb;
WORD col;
BYTE a, r, g, b;
float percent_r = ((color1 >> 24) & 0xFF) / 255.0f;
float percent_g = ((color1 >> 16) & 0xFF) / 255.0f;
float percent_b = ((color1 >> 8) & 0xFF) / 255.0f;
float percent_r_i = 1.0f - percent_r;
float percent_g_i = 1.0f - percent_g;
float percent_b_i = 1.0f - percent_b;
cr = (BYTE)((color0 >> 24) & 0xFF);
cg = (BYTE)((color0 >> 16) & 0xFF);
cb = (BYTE)((color0 >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = (BYTE)(min(255, percent_r_i * r + percent_r * cr));
g = (BYTE)(min(255, percent_g_i * g + percent_g * cg));
b = (BYTE)(min(255, percent_b_i * b + percent_b * cb));
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_full_color_sub_tex_CI (DWORD color)
{
BYTE cr, cg, cb, ca;
WORD col;
BYTE a, r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
ca = (BYTE)(color & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
a = max(0, ca - a);
r = max(0, cr - r);
g = max(0, cg - g);
b = max(0, cb - b);
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_col_inter_col1_using_tex_CI (DWORD color0, DWORD color1)
{
DWORD cr0, cg0, cb0, cr1, cg1, cb1;
WORD col;
BYTE a, r, g, b;
float percent_r, percent_g, percent_b;
cr0 = (BYTE)((color0 >> 24) & 0xFF);
cg0 = (BYTE)((color0 >> 16) & 0xFF);
cb0 = (BYTE)((color0 >> 8) & 0xFF);
cr1 = (BYTE)((color1 >> 24) & 0xFF);
cg1 = (BYTE)((color1 >> 16) & 0xFF);
cb1 = (BYTE)((color1 >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
percent_r = ((col&0xF800) >> 11) / 31.0f;
percent_g = ((col&0x07C0) >> 6) / 31.0f;
percent_b = ((col&0x003E) >> 1) / 31.0f;
r = (BYTE)(min((1.0f-percent_r) * cr0 + percent_r * cr1, 255));
g = (BYTE)(min((1.0f-percent_g) * cg0 + percent_g * cg1, 255));
b = (BYTE)(min((1.0f-percent_b) * cb0 + percent_b * cb1, 255));
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_tex_sub_col_mul_fac_add_tex_CI (DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
BYTE cr, cg, cb, a;
WORD col;
float r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = (r - cr) * percent + r;
if (r > 255.0f) r = 255.0f;
if (r < 0.0f) r = 0.0f;
g = (g - cg) * percent + g;
if (g > 255.0f) g = 255.0f;
if (g < 0.0f) g = 0.0f;
b = (b - cb) * percent + b;
if (b > 255.0f) g = 255.0f;
if (b < 0.0f) b = 0.0f;
rdp.pal_8[i] = (WORD)(((WORD)((BYTE)(r) >> 3) << 11) |
((WORD)((BYTE)(g) >> 3) << 6) |
((WORD)((BYTE)(b) >> 3) << 1) |
(WORD)(a) );
}
}
static void mod_tex_scale_col_add_col_CI (DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
float percent_r = (1.0f - ((color >> 24) & 0xFF) / 255.0f) * percent;
float percent_g = (1.0f - ((color >> 16) & 0xFF) / 255.0f) * percent;
float percent_b = (1.0f - ((color >> 8) & 0xFF) / 255.0f) * percent;
WORD col;
float base = (1.0f - percent) * 255.0f;
BYTE a, r, g, b;
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = (BYTE)(min(base + percent_r * r, 255));
g = (BYTE)(min(base + percent_g * g, 255));
b = (BYTE)(min(base + percent_b * b, 255));
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
(WORD)(a) );
}
}
static void mod_tex_add_col_CI (DWORD color)
{
BYTE cr, cg, cb;
WORD col;
BYTE a, r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = min(cr + r, 255);
g = min(cg + g, 255);
b = min(cb + b, 255);
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_tex_sub_col_CI (DWORD color)
{
BYTE cr, cg, cb;
WORD col;
BYTE a, r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = max(r - cr, 0);
g = max(g - cg, 0);
b = max(b - cb, 0);
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_tex_sub_col_mul_fac_CI (DWORD color, DWORD factor)
{
float percent = factor / 255.0f;
BYTE cr, cg, cb;
WORD col;
BYTE a;
float r, g, b;
cr = (BYTE)((color >> 24) & 0xFF);
cg = (BYTE)((color >> 16) & 0xFF);
cb = (BYTE)((color >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);
r = (float)((col&0xF800) >> 11) / 31.0f * 255.0f;
g = (float)((col&0x07C0) >> 6) / 31.0f * 255.0f;
b = (float)((col&0x003E) >> 1) / 31.0f * 255.0f;
r = (r - cr) * percent;
if (r > 255.0f) r = 255.0f;
if (r < 0.0f) r = 0.0f;
g = (g - cg) * percent;
if (g > 255.0f) g = 255.0f;
if (g < 0.0f) g = 0.0f;
b = (b - cb) * percent;
if (b > 255.0f) g = 255.0f;
if (b < 0.0f) b = 0.0f;
rdp.pal_8[i] = (WORD)(((WORD)((BYTE)(r) >> 3) << 11) |
((WORD)((BYTE)(g) >> 3) << 6) |
((WORD)((BYTE)(b) >> 3) << 1) |
(WORD)(a) );
}
}
static void mod_col_inter_tex_using_col1_CI (DWORD color0, DWORD color1)
{
BYTE cr, cg, cb;
WORD col;
BYTE a, r, g, b;
float percent_r = ((color1 >> 24) & 0xFF) / 255.0f;
float percent_g = ((color1 >> 16) & 0xFF) / 255.0f;
float percent_b = ((color1 >> 8) & 0xFF) / 255.0f;
float percent_r_i = 1.0f - percent_r;
float percent_g_i = 1.0f - percent_g;
float percent_b_i = 1.0f - percent_b;
cr = (BYTE)((color0 >> 24) & 0xFF);
cg = (BYTE)((color0 >> 16) & 0xFF);
cb = (BYTE)((color0 >> 8) & 0xFF);
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
g = (BYTE)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
b = (BYTE)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
r = (BYTE)(min(255, percent_r * r + percent_r_i * cr));
g = (BYTE)(min(255, percent_g * g + percent_g_i * cg));
b = (BYTE)(min(255, percent_b * b + percent_b_i * cb));
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void mod_tex_inter_col_using_texa_CI (DWORD color)
{
BYTE a, r, g, b;
r = (BYTE)((float)((color >> 24) & 0xFF) / 255.0f * 31.0f);
g = (BYTE)((float)((color >> 16) & 0xFF) / 255.0f * 31.0f);
b = (BYTE)((float)((color >> 8) & 0xFF) / 255.0f * 31.0f);
a = (color&0xFF) ? 1 : 0;
WORD col16 = (WORD)((r<<11)|(g<<6)|(b<<1)|a);
for (int i=0; i<256; i++)
{
if (rdp.pal_8[i]&1)
rdp.pal_8[i] = col16;
}
}
static void mod_tex_mul_col_CI (DWORD color)
{
BYTE a, r, g, b;
WORD col;
float cr, cg, cb;
cr = (float)((color >> 24) & 0xFF) / 255.0f;
cg = (float)((color >> 16) & 0xFF) / 255.0f;
cb = (float)((color >> 8) & 0xFF) / 255.0f;
for (int i=0; i<256; i++)
{
col = rdp.pal_8[i];
a = (BYTE)(col&0x0001);;
r = (BYTE)((float)((col&0xF800) >> 11) * cr);
g = (BYTE)((float)((col&0x07C0) >> 6) * cg);
b = (BYTE)((float)((col&0x003E) >> 1) * cb);
rdp.pal_8[i] = (WORD)(((WORD)(r >> 3) << 11) |
((WORD)(g >> 3) << 6) |
((WORD)(b >> 3) << 1) |
((WORD)(a ) << 0));
}
}
static void ModifyPalette(DWORD mod, DWORD modcolor, DWORD modcolor1, DWORD modfactor)
{
switch (mod)
{
case TMOD_TEX_INTER_COLOR_USING_FACTOR:
mod_tex_inter_color_using_factor_CI (modcolor, modfactor);
break;
case TMOD_TEX_INTER_COL_USING_COL1:
mod_tex_inter_col_using_col1_CI (modcolor, modcolor1);
break;
case TMOD_FULL_COLOR_SUB_TEX:
mod_full_color_sub_tex_CI (modcolor);
break;
case TMOD_COL_INTER_COL1_USING_TEX:
mod_col_inter_col1_using_tex_CI (modcolor, modcolor1);
break;
case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX:
mod_tex_sub_col_mul_fac_add_tex_CI (modcolor, modfactor);
break;
case TMOD_TEX_SCALE_COL_ADD_COL:
mod_tex_scale_col_add_col_CI (modcolor, modfactor);
break;
case TMOD_TEX_ADD_COL:
mod_tex_add_col_CI (modcolor);
break;
case TMOD_TEX_SUB_COL:
mod_tex_sub_col_CI (modcolor);
break;
case TMOD_TEX_SUB_COL_MUL_FAC:
mod_tex_sub_col_mul_fac_CI (modcolor, modfactor);
break;
case TMOD_COL_INTER_TEX_USING_COL1:
mod_col_inter_tex_using_col1_CI (modcolor, modcolor1);
break;
case TMOD_TEX_INTER_COL_USING_TEXA:
mod_tex_inter_col_using_texa_CI (modcolor);
break;
case TMOD_TEX_MUL_COL:
mod_tex_mul_col_CI (modcolor);
break;
default:
;
}
}

View File

@ -0,0 +1,44 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#if !defined(WIN32) && defined(GCC)
#define SwapBlock32 _SwapBlock32
#define SwapBlock64 _SwapBlock64
#endif
extern "C" void CopyBlock ();
extern "C" void SwapBlock32 ();
extern "C" void SwapBlock64 ();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
#ifndef Util_H
#define Util_H
#include "winlnxdefs.h"
#include "rdp.h"
#define NOT_TMU0 0x00
#define NOT_TMU1 0x01
#define NOT_TMU2 0x02
void util_init ();
void clip_z ();
void clip_tri (WORD linew = 0);
BOOL cull_tri (VERTEX **v);
void DrawTri (VERTEX **v, WORD linew = 0);
void do_triangle_stuff (WORD linew = 0);
void do_triangle_stuff_2 (WORD linew = 0);
void add_tri (VERTEX *v, int n, int type);
void apply_shade_mods (VERTEX *v);
void update ();
void update_scissor ();
void set_message_combiner ();
void fix_tex_coord (VERTEX **v);
// positional and texel coordinate clipping
#define CCLIP(ux,lx,ut,lt,uc,lc) \
if (ux > lx || lx < uc || ux > lc) { rdp.tri_n += 2; return; } \
if (ux < uc) { \
float p = (uc-ux)/(lx-ux); \
ut = p*(lt-ut)+ut; \
ux = uc; \
} \
if (lx > lc) { \
float p = (lc-ux)/(lx-ux); \
lt = p*(lt-ut)+ut; \
lx = lc; \
}
#define CCLIP2(ux,lx,ut,lt,un,ln,uc,lc) \
if (ux > lx || lx < uc || ux > lc) { rdp.tri_n += 2; return; } \
if (ux < uc) { \
float p = (uc-ux)/(lx-ux); \
ut = p*(lt-ut)+ut; \
un = p*(ln-un)+un; \
ux = uc; \
} \
if (lx > lc) { \
float p = (lc-ux)/(lx-ux); \
lt = p*(lt-ut)+ut; \
ln = p*(ln-un)+un; \
lx = lc; \
}
#endif // ifndef Util_H

View File

@ -0,0 +1,43 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
#include <stdio.h>
int main(int argc, char **argv)
{
FILE *src, *dest;
unsigned char a;
src = fopen(argv[1], "rb");
dest = fopen(argv[2], "wb");
fprintf(dest, "unsigned char %s[] = {", argv[3]);
while(fread(&a, 1, 1, src))
{
fprintf(dest, "%d,\n", a);
}
fprintf(dest, "0};\n");
fclose(src);
fclose(dest);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,87 @@
/******************************************************************************
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* http://bitbucket.org/wahrhaft/mupen64plus-video-glide64/
*
* Copyright (C) 2010 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
#define M64P_PLUGIN_PROTOTYPES 1
#include "m64p_types.h"
#include "m64p_common.h"
#include "m64p_plugin.h"
#include "m64p_config.h"
#include "m64p_vidext.h"
#include <stdio.h>
#define PLUGIN_NAME "Glide64 Video Plugin"
#define PLUGIN_VERSION 0x016305
#define VIDEO_PLUGIN_API_VERSION 0x020100
#define CONFIG_API_VERSION 0x020000
#define VIDEXT_API_VERSION 0x020000
#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
void WriteLog(m64p_msg_level level, const char *msg, ...);
//The Glide API originally used an integer to pick an enumerated resolution.
//To accomodate arbitrary resolutions, pack it into a 32-bit struct
//so we don't have to change function signatures
union PackedScreenResolution
{
struct
{
int width : 16;
int height : 15;
int fullscreen : 1;
};
int resolution;
};
/* 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;
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_GL_GetProcAddress CoreVideo_GL_GetProcAddress;
extern ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute;
extern ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers;
#endif

View File

@ -0,0 +1,38 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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
#ifdef __cplusplus
extern "C" {
#endif
#include "m64p_types.h"
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
#ifdef __cplusplus
}
#endif
#endif /* #define OSAL_DYNAMICLIB_H */

View File

@ -0,0 +1,37 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-core - osal/dynamiclib_unix.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2009 Richard Goedeken *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include "m64p_types.h"
#include "osal_dynamiclib.h"
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
{
if (pccProcedureName == NULL)
return NULL;
return dlsym(LibHandle, pccProcedureName);
}

View File

@ -0,0 +1,74 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus-ui-console - osal_dynamiclib_win32.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 <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "m64p_types.h"
#include "osal_dynamiclib.h"
m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
{
if (pLibHandle == NULL || pccLibraryPath == NULL)
return M64ERR_INPUT_ASSERT;
*pLibHandle = LoadLibrary(pccLibraryPath);
if (*pLibHandle == NULL)
{
char *pchErrMsg;
DWORD dwErr = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
LocalFree(pchErrMsg);
return M64ERR_INPUT_NOT_FOUND;
}
return M64ERR_SUCCESS;
}
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
{
if (pccProcedureName == NULL)
return NULL;
return 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,768 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
* Copyright (c) 2008 Günther <guenther.emu@freenet.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
// Call this macro to automatically switch out of fullscreen, then break. :)
// useful for debugging fullscreen areas that can't otherwise be accessed
#ifndef RDP_H
#define RDP_H
#ifdef _WIN32
#include <windows.h>
#else // _WIN32
#include "winlnxdefs.h"
#endif // _WIN32
#include "glide.h"
//#ifdef GCC
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
//#endif
extern char out_buf[2048];
extern BOOL capture_screen;
extern char capture_path[256];
extern DWORD frame_count; // frame counter
#define MAX_CACHE 1024
#define MAX_TRI_CACHE 768 // this is actually # of vertices, not triangles
#define MAX_VTX 256
#define MAX_TMU 2
#define TEXMEM_2MB_EDGE 2097152
// Supported flags
#define SUP_TEXMIRROR 0x00000001
// Clipping flags
#define CLIP_XMAX 0x00000001
#define CLIP_XMIN 0x00000002
#define CLIP_YMAX 0x00000004
#define CLIP_YMIN 0x00000008
#define CLIP_ZMIN 0x00000010
// Flags
#define ZBUF_ENABLED 0x00000001
#define ZBUF_DECAL 0x00000002
#define ZBUF_COMPARE 0x00000004
#define ZBUF_UPDATE 0x00000008
#define ALPHA_COMPARE 0x00000010
#define FORCE_BL 0x00000020
#define CULL_FRONT 0x00001000 // * must be here
#define CULL_BACK 0x00002000 // * must be here
#define FOG_ENABLED 0x00010000
#define CULLMASK 0x00003000
#define CULLSHIFT 12
// Update flags
#define UPDATE_ZBUF_ENABLED 0x00000001
#define UPDATE_TEXTURE 0x00000002 // \ Same thing!
#define UPDATE_COMBINE 0x00000002 // /
#define UPDATE_CULL_MODE 0x00000004
#define UPDATE_LIGHTS 0x00000010
#define UPDATE_BIASLEVEL 0x00000020
#define UPDATE_ALPHA_COMPARE 0x00000040
#define UPDATE_VIEWPORT 0x00000080
#define UPDATE_MULT_MAT 0x00000100
#define UPDATE_SCISSOR 0x00000200
#define UPDATE_FOG_ENABLED 0x00010000
#define CMB_MULT 0x00000001
#define CMB_SET 0x00000002
#define CMB_SUB 0x00000004
#define CMB_ADD 0x00000008
#define CMB_A_MULT 0x00000010
#define CMB_A_SET 0x00000020
#define CMB_A_SUB 0x00000040
#define CMB_A_ADD 0x00000080
#define CMB_SETSHADE_SHADEALPHA 0x00000100
#define CMB_INTER 0x00000200
#define CMB_MULT_OWN_ALPHA 0x00000400
#define CMB_COL_SUB_OWN 0x00000800
#define uc(x) coord[x<<1]
#define vc(x) coord[(x<<1)+1]
// Vertex structure
typedef struct
{
float x, y, z, q;
float u0, v0, u1, v1;
float coord[4];
float w;
WORD flags;
BYTE b; // These values are arranged like this so that *(DWORD*)(VERTEX+?) is
BYTE g; // ARGB format that glide can use.
BYTE r;
BYTE a;
float f; //fog
float vec[3]; // normal vector
float sx, sy, sz;
float x_w, y_w, z_w, u0_w, v0_w, u1_w, v1_w, oow;
BYTE not_zclipped;
BYTE screen_translated;
BYTE shade_mods_allowed;
BYTE uv_fixed;
DWORD uv_calculated; // like crc
float ou, ov;
int number; // way to identify it
int scr_off, z_off; // off the screen?
} VERTEX;
// Clipping (scissors)
typedef struct {
DWORD ul_x;
DWORD ul_y;
DWORD lr_x;
DWORD lr_y;
} SCISSOR;
typedef struct {
BYTE card_id;
DWORD res_x, scr_res_x;
DWORD res_y, scr_res_y;
DWORD res_data, res_data_org;
BOOL autodetect_ucode;
DWORD ucode;
BOOL wireframe;
int wfmode;
int lodmode;
BYTE filtering;
BOOL fog;
BOOL buff_clear;
// BOOL clear_8;
BOOL vsync;
BOOL fast_crc;
BYTE swapmode;
BOOL logging;
BOOL elogging;
BOOL log_clear;
BOOL filter_cache;
BOOL unk_as_red;
BOOL log_unk;
BOOL unk_clear;
BYTE show_fps;
BOOL clock;
BOOL clock_24_hr;
DWORD full_res;
DWORD tex_filter;
BOOL noditheredalpha;
BOOL noglsl;
BOOL FBO;
BOOL disable_auxbuf;
//Frame buffer emulation options
BOOL fb_read_always;
BOOL fb_read_alpha;
BOOL fb_smart;
BOOL fb_motionblur;
BOOL fb_hires;
BOOL fb_hires_buf_clear;
BOOL fb_depth_clear;
BOOL fb_depth_render;
BOOL fb_optimize_texrect;
BOOL fb_optimize_write;
BOOL fb_ignore_aux_copy;
BOOL fb_ignore_previous;
BOOL fb_get_info;
// Special fixes
int offset_x, offset_y;
int scale_x, scale_y;
BOOL alt_tex_size;
BOOL use_sts1_only;
BOOL wrap_big_tex;
BOOL flame_corona; //hack for zeldas flame's corona
int fix_tex_coord;
int depth_bias;
BOOL soft_depth_compare; // use GR_CMP_LEQUAL instead of GR_CMP_LESS
BOOL increase_texrect_edge; // add 1 to lower right corner coordinates of texrect
BOOL decrease_fillrect_edge; // sub 1 from lower right corner coordinates of fillrect
int stipple_mode; //used for dithered alpha emulation
DWORD stipple_pattern; //used for dithered alpha emulation
BOOL force_microcheck; //check microcode each frame, for mixed F3DEX-S2DEX games
BOOL custom_ini;
BOOL hotkeys;
//Special game hacks
BOOL force_depth_compare; //NFL Quarterback Club 99 and All-Star Baseball 2000
BOOL fillcolor_fix; //use first part of fillcolor in fillrects
BOOL cpu_write_hack; //show images writed directly by CPU
BOOL increase_primdepth; //increase prim_depth value for texrects
BOOL zelda; //zeldas hacks
BOOL bomberman64; //bomberman64 hacks
BOOL diddy; //diddy kong racing
BOOL tonic; //tonic trouble
BOOL PPL; //pokemon puzzle league requires many special fixes
BOOL ASB; //All-Star Baseball games
BOOL doraemon2;//Doraemon 2
BOOL invaders; //Space Invaders
BOOL BAR; //Beetle Adventure Racing
BOOL ISS64; //International Superstar Soccer 64
BOOL RE2; //Resident Evil 2
BOOL nitro; //WCW Nitro
BOOL chopper; //Chopper Attack
BOOL yoshi; // Yoshi Story
BOOL fzero; // F-Zero
BOOL PM; //Paper Mario
BOOL TGR; //Top Gear Rally
BOOL TGR2; //Top Gear Rally 2
BOOL KI; //Killer Instinct
BOOL lego; //LEGO Racers
} SETTINGS;
typedef struct
{
BYTE fb_always;
BYTE fb_motionblur;
BYTE filtering;
BYTE corona;
} HOTKEY_INFO;
// This structure is what is passed in by rdp:settextureimage
typedef struct {
BYTE format; // format: ARGB, IA, ...
BYTE size; // size: 4,8,16, or 32 bit
WORD width; // used in settextureimage
DWORD addr; // address in RDRAM to load the texture from
BOOL set_by; // 0-loadblock 1-loadtile
} TEXTURE_IMAGE;
// This structure is a tile descriptor (as used by rdp:settile and rdp:settilesize)
typedef struct
{
// rdp:settile
BYTE format; // format: ARGB, IA, ...
BYTE size; // size: 4,8,16, or 32 bit
WORD line; // size of one row (x axis) in 64 bit words
WORD t_mem; // location in texture memory (in 64 bit words, max 512 (4MB))
BYTE palette; // palette # to use
BYTE clamp_t; // clamp or wrap (y axis)?
BYTE mirror_t; // mirroring on (y axis)?
BYTE mask_t; // mask to wrap around (ex: 5 would wrap around 32) (y axis)
BYTE shift_t; // ??? (scaling)
BYTE clamp_s; // clamp or wrap (x axis)?
BYTE mirror_s; // mirroring on (x axis)?
BYTE mask_s; // mask to wrap around (x axis)
BYTE shift_s; // ??? (scaling)
DWORD hack; // any hacks needed
// rdp:settilesize
WORD ul_s; // upper left s coordinate
WORD ul_t; // upper left t coordinate
WORD lr_s; // lower right s coordinate
WORD lr_t; // lower right t coordinate
float f_ul_s;
float f_ul_t;
// these are set by loadtile
WORD t_ul_s; // upper left s coordinate
WORD t_ul_t; // upper left t coordinate
WORD t_lr_s; // lower right s coordinate
WORD t_lr_t; // lower right t coordinate
DWORD width;
DWORD height;
// uc0:texture
BYTE on;
float s_scale;
float t_scale;
WORD org_s_scale;
WORD org_t_scale;
} TILE;
// This structure forms the lookup table for cached textures
typedef struct {
DWORD addr; // address in RDRAM
DWORD crc; // CRC check
DWORD palette; // Palette #
DWORD width; // width
DWORD height; // height
DWORD format; // format
DWORD size; // size
DWORD last_used; // what frame # was this texture last used (used for replacing)
DWORD line;
DWORD flags; // clamp/wrap/mirror flags
DWORD realwidth; // width of actual texture
DWORD realheight; // height of actual texture
DWORD lod;
DWORD aspect;
BOOL set_by;
DWORD texrecting;
float scale_x; // texture scaling
float scale_y;
float scale; // general scale to 256
GrTexInfo t_info; // texture info (glide)
DWORD tmem_addr; // addres in texture memory (glide)
int uses; // 1 triangle that uses this texture
int splits; // number of splits
int splitheight;
float c_off; // ul center texel offset (both x and y)
float c_scl_x; // scale to lower-right center-texel x
float c_scl_y; // scale to lower-right center-texel y
DWORD mod, mod_color, mod_color1, mod_color2, mod_factor;
} CACHE_LUT;
// Lights
typedef struct {
float r, g, b, a; // color
float dir_x, dir_y, dir_z; // direction towards the light source
float x, y, z, w; // light position
float ca, la, qa;
DWORD nonblack;
DWORD nonzero;
} LIGHT;
typedef enum {
noise_none,
noise_combine,
noise_texture
} NOISE_MODE;
typedef enum {
ci_main, //0, main color image
ci_zimg, //1, depth image
ci_unknown, //2, status is unknown
ci_useless, //3, status is unclear
ci_old_copy, //4, auxilary color image, copy of last color image from previous frame
ci_copy, //5, auxilary color image, copy of previous color image
ci_copy_self, //6, main color image, it's content will be used to draw into itself
ci_zcopy, //7, auxilary color image, copy of depth image
ci_aux, //8, auxilary color image
ci_aux_copy //9, auxilary color image, partial copy of previous color image
} CI_STATUS;
// Frame buffers
typedef struct
{
DWORD addr; //color image address
DWORD format;
DWORD size;
DWORD width;
DWORD height;
CI_STATUS status;
int changed;
} COLOR_IMAGE;
typedef struct
{
GrChipID_t tmu;
DWORD addr; //address of color image
DWORD end_addr;
DWORD tex_addr; //address in video memory
DWORD width; //width of color image
DWORD height; //height of color image
WORD format; //format of color image
BOOL clear; //flag. texture buffer must be cleared
BOOL drawn; //flag. if equal to 1, this image was already drawn in current frame
float scr_width; //width of rendered image
float scr_height; //height of rendered image
DWORD tex_width; //width of texture buffer
DWORD tex_height; //height of texture buffer
int tile; //
WORD tile_uls; //shift from left bound of the texture
WORD tile_ult; //shift from top of the texture
DWORD v_shift; //shift from top of the texture
DWORD u_shift; //shift from left of the texture
float u_scale; //used to map vertex u,v coordinates into hires texture
float v_scale; //used to map vertex u,v coordinates into hires texture
GrTexInfo info;
} HIRES_COLOR_IMAGE;
typedef struct
{
GrChipID_t tmu;
DWORD begin; //start of the block in video memory
DWORD end; //end of the block in video memory
BYTE count; //number of allocated texture buffers
BOOL clear_allowed; //stack of buffers can be cleared
HIRES_COLOR_IMAGE images[256];
} TEXTURE_BUFFER;
#define NUMTEXBUF 92
typedef struct
{
float vi_width;
float vi_height;
BOOL window_changed;
float offset_x, offset_y;
float scale_x, scale_1024, scale_x_bak;
float scale_y, scale_768, scale_y_bak;
DWORD res_scale_x;
DWORD res_scale_y;
float view_scale[3];
float view_trans[3];
BOOL updatescreen;
DWORD tri_n; // triangle counter
DWORD debug_n;
// Program counter
DWORD pc[10]; // DList PC stack
DWORD pc_i; // current PC index in the stack
int dl_count; // number of instructions before returning
// Segments
DWORD segment[16]; // Segment pointer
// Marks the end of DList execution (done in uc?:enddl)
int halt;
// Next command
DWORD cmd0;
DWORD cmd1;
DWORD cmd2;
DWORD cmd3;
// Clipping
SCISSOR scissor_o;
SCISSOR scissor;
// Colors
DWORD fog_color;
DWORD fill_color;
DWORD prim_color;
DWORD blend_color;
DWORD env_color;
DWORD prim_lodmin, prim_lodfrac;
WORD prim_depth;
BYTE K5;
NOISE_MODE noise;
float col[4]; // color multiplier
float coladd[4]; // color add/subtract
float shade_factor;
float col_2[4];
DWORD cmb_flags, cmb_flags_2;
// othermode_l flags
int acmp; // 0 = none, 1 = threshold, 2 = dither
int zsrc; // 0 = pixel, 1 = prim
// Clipping
int clip; // clipping flags
VERTEX vtx1[256]; // copy vertex buffer #1 (used for clipping)
VERTEX vtx2[256]; // copy vertex buffer #2
VERTEX *vtxbuf; // current vertex buffer (reset to vtx, used to determine current
// vertex buffer)
VERTEX *vtxbuf2;
int n_global; // Used to pass the number of vertices from clip_z to clip_tri
int vtx_buffer;
// Matrices
__declspec( align(16) ) float model[4][4];
__declspec( align(16) ) float proj[4][4];
__declspec( align(16) ) float combined[4][4];
__declspec( align(16) ) float dkrproj[3][4][4];
__declspec( align(16) ) float model_stack[32][4][4]; // 32 deep, will warn if overflow
int model_i; // index in the model matrix stack
int model_stack_size;
// Textures
TEXTURE_IMAGE timg; // 1 for each tmem address
TILE tiles[8]; // 8 tile descriptors
BYTE tmem[4096]; // 4k tmem
DWORD addr[512]; // 512 addresses (used to determine address loaded from)
int cur_tile; // current tile
int mipmap_level;
int last_tile; // last tile set
int last_tile_size; // last tile size set
CACHE_LUT cache[MAX_TMU][MAX_CACHE];
CACHE_LUT *cur_cache[2];
DWORD cur_cache_n[2];
int n_cached[MAX_TMU];
DWORD tmem_ptr[MAX_TMU];
int t0, t1;
int best_tex; // if no 2-tmus, which texture? (0 or 1)
int tex;
int filter_mode;
// Texture palette
WORD pal_8[256];
DWORD pal_8_crc[16];
DWORD pal_256_crc;
BYTE tlut_mode;
BOOL LOD_en;
// Lighting
DWORD num_lights;
LIGHT light[12];
float light_vector[12][3];
float lookat[2][3];
BOOL use_lookat;
// Combine modes
DWORD cycle1, cycle2, cycle_mode;
BYTE c_a0, c_b0, c_c0, c_d0, c_Aa0, c_Ab0, c_Ac0, c_Ad0;
BYTE c_a1, c_b1, c_c1, c_d1, c_Aa1, c_Ab1, c_Ac1, c_Ad1;
BYTE fbl_a0, fbl_b0, fbl_c0, fbl_d0;
BYTE fbl_a1, fbl_b1, fbl_c1, fbl_d1;
BYTE uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both
// float YUV_C0, YUV_C1, YUV_C2, YUV_C3, YUV_C4; //YUV textures conversion coefficients
BOOL yuv_image;
float yuv_ul_x, yuv_ul_y, yuv_lr_x, yuv_lr_y;
DWORD yuv_im_begin;
// What needs updating
DWORD update;
DWORD flags;
BOOL first;
// Vertices
VERTEX vtx[MAX_VTX];
int v0, vn;
DWORD tex_ctr; // same as above, incremented every time textures are updated
BOOL allow_combine; // allow combine updating?
BOOL s2dex_tex_loaded;
// Debug stuff
DWORD rm; // use othermode_l instead, this just as a check for changes
DWORD render_mode_changed;
DWORD geom_mode;
DWORD othermode_h;
DWORD othermode_l;
// used to check if in texrect while loading texture
DWORD texrecting;
//frame buffer related slots. Added by Gonetz
COLOR_IMAGE frame_buffers[NUMTEXBUF+2];
DWORD cimg, ocimg, zimg, tmpzimg, vi_org_reg;
COLOR_IMAGE maincimg[2];
DWORD last_drawn_ci_addr;
DWORD main_ci, main_ci_end, main_ci_bg, main_ci_last_tex_addr, zimg_end, last_bg;
DWORD ci_width, ci_height, ci_size, ci_end;
DWORD zi_width;
int zi_lrx, zi_lry;
BYTE ci_count, num_of_ci, main_ci_index, copy_ci_index;
int swap_ci_index, black_ci_index;
DWORD ci_upper_bound, ci_lower_bound;
BOOL motionblur, fb_drawn, fb_drawn_front, read_previous_ci, read_whole_frame;
CI_STATUS ci_status;
TEXTURE_BUFFER texbufs[2];
HIRES_COLOR_IMAGE * cur_image; //image currently being drawn
HIRES_COLOR_IMAGE * hires_tex; //image, which corresponds to currently selected texture
BYTE cur_tex_buf;
BYTE acc_tex_buf;
BOOL skip_drawing; //rendering is not required. used for frame buffer emulation
//fog related slots. Added by Gonetz
float fog_multiplier, fog_offset;
BOOL fog_coord_enabled;
} RDP;
void SetWireframeCol ();
void ChangeSize ();
extern RDP rdp;
extern SETTINGS settings;
extern HOTKEY_INFO hotkey_info;
extern GrTexInfo fontTex;
extern GrTexInfo cursorTex;
extern DWORD offset_font;
extern DWORD offset_cursor;
extern DWORD offset_textures;
extern DWORD offset_texbuf1;
extern BOOL ucode_error_report;
// RDP functions
void rdp_reset ();
// global strings
extern const char *ACmp[4];
extern const char *Mode0[16];
extern const char *Mode1[16];
extern const char *Mode2[32];
extern const char *Mode3[8];
extern const char *Alpha0[8];
extern const char *Alpha2[8];
extern const char *str_zs[2];
extern const char *str_yn[2];
extern const char *str_offon[2];
extern const char *str_cull[4];
extern const char *str_format[8];
extern const char *str_size[4];
extern const char *str_cm[4];
extern const char *str_filter[3];
extern const char *str_tlut[4];
extern const char *CIStatus[10];
#define Alpha1 Alpha0
#define Alpha3 Alpha0
#define FBL_D_1 2
#define FBL_D_0 3
// Convert from u0/v0/u1/v1 to the real coordinates without regard to tmu
__inline void ConvertCoordsKeep (VERTEX *v, int n)
{
for (int i=0; i<n; i++)
{
v[i].uc(0) = v[i].u0;
v[i].vc(0) = v[i].v0;
v[i].uc(1) = v[i].u1;
v[i].vc(1) = v[i].v1;
}
}
// Convert from u0/v0/u1/v1 to the real coordinates based on the tmu they are on
__inline void ConvertCoordsConvert (VERTEX *v, int n)
{
if (rdp.hires_tex && rdp.tex != 3)
{
for (int i=0; i<n; i++)
{
v[i].u1 = v[i].u0;
v[i].v1 = v[i].v0;
}
}
// float z;
for (int i=0; i<n; i++)
{
v[i].uc(rdp.t0) = v[i].u0;
v[i].vc(rdp.t0) = v[i].v0;
v[i].uc(rdp.t1) = v[i].u1;
v[i].vc(rdp.t1) = v[i].v1;
}
}
__inline void AllowShadeMods (VERTEX *v, int n)
{
for (int i=0; i<n; i++)
{
v[i].shade_mods_allowed = 1;
}
}
__inline float ScaleZ(float z)
{
// z *= 2.0f;
// if (z > 65535.0f) return 65535.0f;
// return (z / 65535.0f) * z;
// if (z < 4096.0f) return z * 0.25f;
// z = (z / 16384.0f) * z;
z *= 1.9f;
if (z > 65534.0f) return 65534.0f;
return z;
}
__inline void CalculateFog (VERTEX *v)
{
if (rdp.flags & FOG_ENABLED)
{
v->f = min(255.0f, max(0.0f, v->z_w * rdp.fog_multiplier + rdp.fog_offset));
v->a = (BYTE)v->f;
}
else
{
v->f = 1.0f;
}
}
void newSwapBuffers();
extern BOOL SwapOK;
// ** utility functions
void load_palette (DWORD addr, WORD start, WORD count);
#endif // ifndef RDP_H

View File

@ -0,0 +1,714 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
typedef void (*rdp_instr)();
// RDP graphic instructions pointer table
static rdp_instr gfx_instruction[9][256] =
{
{
// uCode 0 - RSP SW 2.0X
// 00-3f
// games: Super Mario 64, Tetrisphere, Demos
spnoop, uc0_matrix, rsp_reserved0, uc0_movemem,
uc0_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2,
rsp_reserved3, uc6_sprite2d, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: Unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, uc0_tri4, uc0_rdphalf_cont, uc0_rdphalf_2,
uc0_rdphalf_1, uc0_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1,
// c0-ff: RDP commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 1 - F3DEX 1.XX
// 00-3f
// games: Mario Kart, Star Fox
{
spnoop, uc0_matrix, rsp_reserved0, uc0_movemem,
uc1_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2,
rsp_reserved3, uc6_sprite2d, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, uc6_loaducode,
uc1_branch_z, uc1_tri2, uc2_modifyvtx, uc0_rdphalf_2,
uc1_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1,
// c0-ff: RDP commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 2 - F3DEX 2.XX
// games: Zelda 64
{
// 00-3f
spnoop, uc2_vertex, uc2_modifyvtx, uc2_culldl,
uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad,
uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/,
undef, undef, undef, undef,
uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4,
uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4,
uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4,
uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// c0-ff: RDP commands mixed with uc2 commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, uc2_special3,
uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture,
uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc2_moveword,
uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl,
spnoop, uc1_rdphalf_1, uc0_setothermode_l,uc0_setothermode_h,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 3 - "RSP SW 2.0D", but not really
// 00-3f
// games: Wave Race
// ** Added by Gonetz **
{
spnoop, uc0_matrix, rsp_reserved0, uc0_movemem,
uc3_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2,
rsp_reserved3, uc6_sprite2d, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, uc3_tri2, uc0_rdphalf_cont, uc0_rdphalf_2,
uc0_rdphalf_1, uc3_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc0_culldl, uc3_tri1,
// c0-ff: RDP commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
{
// uCode 4 - RSP SW 2.0D EXT
// 00-3f
// games: Star Wars: Shadows of the Empire
spnoop, uc0_matrix, rsp_reserved0, uc0_movemem,
uc4_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2,
rsp_reserved3, uc6_sprite2d, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: Unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, uc0_tri4, uc0_rdphalf_cont, uc0_rdphalf_2,
uc0_rdphalf_1, uc4_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc0_culldl, uc4_tri1,
// c0-ff: RDP commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
{
// uCode 5 - RSP SW 2.0 Diddy
// 00-3f
// games: Diddy Kong Racing
spnoop, uc5_matrix, rsp_reserved0, uc0_movemem,
uc5_vertex, uc5_tridma, uc0_displaylist, uc5_dl_in_mem,
rsp_reserved3, uc6_sprite2d, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: Unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, uc0_tri4, uc0_rdphalf_cont, uc0_rdphalf_2,
uc0_rdphalf_1, uc0_quad3d, uc5_cleargeometrymode, uc5_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc5_moveword, uc0_popmatrix, uc0_culldl, uc5_dma_offsets,
// c0-ff: RDP commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 6 - S2DEX 1.XX
// games: Yoshi's Story
{
spnoop, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rectangle,
uc6_obj_sprite, uc6_obj_movemem, uc0_displaylist, rsp_reserved2,
rsp_reserved3, undef/*uc6_sprite2d*/, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: Immediate commands
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, uc6_loaducode,
uc6_select_dl, uc6_obj_rendermode, uc6_obj_rectangle_r, uc0_rdphalf_2,
uc6_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1,
// c0-ff: RDP commands
rdp_noop, uc6_obj_loadtxtr, uc6_obj_ldtx_sprite, uc6_obj_ldtx_rect,
uc6_ldtx_rect_r, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 7 - unknown
// games: Perfect Dark
{
// 00-3f
spnoop, uc0_matrix, rsp_reserved0, uc0_movemem,
uc7_vertex, rsp_reserved1, uc0_displaylist, uc7_colorbase,
rsp_reserved3, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, uc0_tri4, uc0_rdphalf_cont, uc0_rdphalf_2,
uc0_rdphalf_1, uc1_tri2, uc0_cleargeometrymode, uc0_setgeometrymode,
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1,
// c0-ff: RDP commands mixed with uc2 commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, uc0_rdphalf_2, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
// uCode 8 - unknown
// games: Conker's Bad Fur Day
{
// 00-3f
spnoop, uc8_vertex, uc2_modifyvtx, uc2_culldl,
uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad,
uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/,
undef, undef, undef, undef,
uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4,
uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4,
uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4,
uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 40-7f: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// 80-bf: unused
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
undef, undef, undef, undef,
// c0-ff: RDP commands mixed with uc2 commands
rdp_noop, undef, undef, undef,
undef, undef, undef, undef,
rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz,
rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz,
undef, undef, undef, uc2_special3,
uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture,
uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc8_moveword,
uc8_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl,
spnoop, uc1_rdphalf_1, uc0_setothermode_l, uc0_setothermode_h,
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode,
rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock,
rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor,
rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor,
rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage
},
};

View File

@ -0,0 +1,299 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// vertex - loads vertices
//
static void uc1_vertex()
{
DWORD addr = segoffset(rdp.cmd1) & 0x00FFFFFF;
int v0, i, n;
float x, y, z;
rdp.v0 = v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex
rdp.vn = n = (WORD)(rdp.cmd0 >> 10) & 0x3F; // Number to copy
// This is special, not handled in update(), but here
// * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
// *
// This is special, not handled in update()
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
}
}
FRDP ("uc1:vertex v0:%d, n:%d, from: %08lx\n", v0, n, addr);
for (i=0; i < (n<<4); i+=16)
{
VERTEX *v = &rdp.vtx[v0 + (i>>4)];
x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
CalculateFog (v);
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->uv_fixed = 0;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
if (rdp.geom_mode & 0x00020000)
{
v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
if (rdp.geom_mode & 0x80000)
calc_linear (v);
else if (rdp.geom_mode & 0x40000)
calc_sphere (v);
NormalizeVector (v->vec);
calc_light (v);
}
else
{
v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
}
#ifdef EXTREME_LOGGING
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov);
#endif
}
}
//
// tri1 - renders a triangle
//
static void uc1_tri1()
{
if (rdp.skip_drawing)
{
RDP("uc1:tri1. skipped\n");
return;
}
FRDP("uc1:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n,
((rdp.cmd1 >> 17) & 0x7F),
((rdp.cmd1 >> 9) & 0x7F),
((rdp.cmd1 >> 1) & 0x7F), rdp.cmd0, rdp.cmd1);
VERTEX *v[3] = {
&rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 1) & 0x7F]
};
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v);
rdp.tri_n ++;
}
}
static void uc1_tri2 ()
{
if (rdp.skip_drawing)
{
RDP("uc1:tri2. skipped\n");
return;
}
RDP ("uc1:tri2");
FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1,
((rdp.cmd0 >> 17) & 0x7F),
((rdp.cmd0 >> 9) & 0x7F),
((rdp.cmd0 >> 1) & 0x7F),
((rdp.cmd1 >> 17) & 0x7F),
((rdp.cmd1 >> 9) & 0x7F),
((rdp.cmd1 >> 1) & 0x7F));
VERTEX *v[6] = {
&rdp.vtx[(rdp.cmd0 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 1) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 1) & 0x7F]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}
static void uc1_line3d()
{
if (((rdp.cmd1&0xFF000000) == 0) && ((rdp.cmd0&0x00FFFFFF) == 0))
{
WORD width = (WORD)(rdp.cmd1&0xFF) + 1;
FRDP("uc1:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n+1,
(rdp.cmd1 >> 17) & 0x7F,
(rdp.cmd1 >> 9) & 0x7F);
VERTEX *v[3] = {
&rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F]
};
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v, width);
rdp.tri_n ++;
}
}
else
{
FRDP("uc1:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
VERTEX *v[6] = {
&rdp.vtx[(rdp.cmd1 >> 25) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 1) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 25) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}
}
DWORD branch_dl = 0;
static void uc1_rdphalf_1()
{
RDP ("uc1:rdphalf_1\n");
branch_dl = rdp.cmd1;
}
static void uc1_branch_z()
{
DWORD addr = segoffset(branch_dl);
FRDP ("uc1:branch_less_z, addr: %08lx\n", addr);
DWORD vtx = (rdp.cmd0 & 0xFFF) >> 1;
if( fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/) )
{
rdp.pc[rdp.pc_i] = addr;
}
}

View File

@ -0,0 +1,852 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
static void calc_point_light (VERTEX *v, float * vpos)
{
float light_intensity = 0.0f;
register float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b};
for (DWORD l=0; l<rdp.num_lights; l++)
{
if (rdp.light[l].nonblack)
{
float lvec[3] = {rdp.light[l].x, rdp.light[l].y, rdp.light[l].z};
lvec[0] -= vpos[0];
lvec[1] -= vpos[1];
lvec[2] -= vpos[2];
float light_len2 = lvec[0]*lvec[0] + lvec[1]*lvec[1] + lvec[2]*lvec[2];
float light_len = sqrtf(light_len2);
#ifdef EXTREME_LOGGING
FRDP ("calc_point_light: len: %f, len2: %f\n", light_len, light_len2);
#endif
float at = rdp.light[l].ca + light_len/65535.0f*rdp.light[l].la + light_len2/65535.0f*rdp.light[l].qa;
if (at > 0.0f)
light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at);
else
light_intensity = 0.0f;
}
else
{
light_intensity = 0.0f;
}
if (light_intensity > 0.0f)
{
color[0] += rdp.light[l].r * light_intensity;
color[1] += rdp.light[l].g * light_intensity;
color[2] += rdp.light[l].b * light_intensity;
}
}
if (color[0] > 1.0f) color[0] = 1.0f;
if (color[1] > 1.0f) color[1] = 1.0f;
if (color[2] > 1.0f) color[2] = 1.0f;
v->r = (BYTE)(color[0]*255.0f);
v->g = (BYTE)(color[1]*255.0f);
v->b = (BYTE)(color[2]*255.0f);
}
static void uc2_vertex ()
{
// This is special, not handled in update(), but here
// * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
}
}
DWORD addr = segoffset(rdp.cmd1);
int v0, i, n;
float x, y, z;
rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF;
rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n;
FRDP ("uc2:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr);
if (v0 < 0)
{
RDP_E ("** ERROR: uc2:vertex v0 < 0\n");
RDP ("** ERROR: uc2:vertex v0 < 0\n");
return;
}
DWORD geom_mode = rdp.geom_mode;
if (settings.fzero && (rdp.geom_mode & 0x40000))
{
if (((short*)gfx.RDRAM)[(((addr) >> 1) + 4)^1] || ((short*)gfx.RDRAM)[(((addr) >> 1) + 5)^1])
rdp.geom_mode ^= 0x40000;
}
for (i=0; i < (n<<4); i+=16)
{
VERTEX *v = &rdp.vtx[v0 + (i>>4)];
x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
#ifdef EXTREME_LOGGING
FRDP ("before: v%d - x: %f, y: %f, z: %f, flags: %04lx, ou: %f, ov: %f\n", i>>4, x, y, z, v->flags, v->ou, v->ov);
#endif
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
CalculateFog (v);
#ifdef EXTREME_LOGGING
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, a: 0x%02lx\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov, v->f, v->z_w, v->a);
#endif
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->uv_fixed = 0;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
if (rdp.geom_mode & 0x00020000)
{
v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
// FRDP("Calc light. x: %f, y: %f z: %f\n", v->vec[0], v->vec[1], v->vec[2]);
// if (!(rdp.geom_mode & 0x800000))
{
if (rdp.geom_mode & 0x80000)
{
calc_linear (v);
#ifdef EXTREME_LOGGING
FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
else if (rdp.geom_mode & 0x40000)
{
calc_sphere (v);
#ifdef EXTREME_LOGGING
FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
}
if (rdp.geom_mode & 0x00400000)
{
float tmpvec[3] = {x, y, z};
calc_point_light (v, tmpvec);
}
else
{
NormalizeVector (v->vec);
calc_light (v);
}
}
else
{
v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
}
}
rdp.geom_mode = geom_mode;
}
static void uc2_modifyvtx ()
{
BYTE where = (BYTE)((rdp.cmd0 >> 16) & 0xFF);
WORD vtx = (WORD)((rdp.cmd0 >> 1) & 0xFFFF);
FRDP ("uc2:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1);
uc0_modifyvtx(where, vtx, rdp.cmd1);
}
static void uc2_culldl ()
{
WORD vStart = (WORD)(rdp.cmd0 & 0xFFFF) >> 1;
WORD vEnd = (WORD)(rdp.cmd1 & 0xFFFF) >> 1;
DWORD cond = 0;
FRDP ("uc2:culldl start: %d, end: %d\n", vStart, vEnd);
if (vEnd < vStart) return;
for (WORD i=vStart; i<=vEnd; i++)
{
/*
VERTEX v = &rdp.vtx[i];
// Check if completely off the screen (quick frustrum clipping for 90 FOV)
if (v->x >= -v->w)
cond |= 0x01;
if (v->x <= v->w)
cond |= 0x02;
if (v->y >= -v->w)
cond |= 0x04;
if (v->y <= v->w)
cond |= 0x08;
if (v->w >= 0.1f)
cond |= 0x10;
if (cond == 0x1F)
return;
//*/
#ifdef EXTREME_LOGGING
FRDP (" v[%d] = (%02f, %02f, %02f, 0x%02lx)\n", i, rdp.vtx[i].x, rdp.vtx[i].y, rdp.vtx[i].w, rdp.vtx[i].scr_off);
#endif
cond |= (~rdp.vtx[i].scr_off) & 0x1F;
if (cond == 0x1F)
return;
}
RDP (" - "); // specify that the enddl is not a real command
uc0_enddl ();
}
void uc6_obj_loadtxtr ();
static void uc2_tri1()
{
if (rdp.skip_drawing)
{
RDP("uc2:tri1. skipped\n");
return;
}
if ((rdp.cmd0 & 0x00FFFFFF) == 0x17)
{
uc6_obj_loadtxtr ();
return;
}
FRDP("uc1:tri1 #%d - %d, %d, %d\n", rdp.tri_n,
((rdp.cmd0 >> 17) & 0x7F),
((rdp.cmd0 >> 9) & 0x7F),
((rdp.cmd0 >> 1) & 0x7F));
VERTEX *v[3] = {
&rdp.vtx[(rdp.cmd0 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 1) & 0x7F]
};
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v);
rdp.tri_n ++;
}
}
void uc6_obj_ldtx_sprite ();
void uc6_obj_ldtx_rect ();
static void uc2_quad ()
{
if (rdp.skip_drawing)
{
RDP("uc2_quad. skipped\n");
return;
}
if ((rdp.cmd0 & 0x00FFFFFF) == 0x2F)
{
DWORD command = rdp.cmd0>>24;
if (command == 0x6)
{
uc6_obj_ldtx_sprite ();
return;
}
if (command == 0x7)
{
uc6_obj_ldtx_rect ();
return;
}
}
RDP("uc2:quad");
FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1,
((rdp.cmd0 >> 17) & 0x7F),
((rdp.cmd0 >> 9) & 0x7F),
((rdp.cmd0 >> 1) & 0x7F),
((rdp.cmd1 >> 17) & 0x7F),
((rdp.cmd1 >> 9) & 0x7F),
((rdp.cmd1 >> 1) & 0x7F));
VERTEX *v[6] = {
&rdp.vtx[(rdp.cmd0 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 1) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd1 >> 1) & 0x7F]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}
static void uc6_ldtx_rect_r ();
static void uc2_line3d ()
{
if ( (rdp.cmd0&0xFF) == 0x2F )
uc6_ldtx_rect_r ();
else
{
FRDP("uc2:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n+1,
(rdp.cmd0 >> 17) & 0x7F,
(rdp.cmd0 >> 9) & 0x7F);
VERTEX *v[3] = {
&rdp.vtx[(rdp.cmd0 >> 17) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 9) & 0x7F],
&rdp.vtx[(rdp.cmd0 >> 9) & 0x7F]
};
WORD width = (WORD)(rdp.cmd0&0xFF) + 1;
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v, width);
rdp.tri_n ++;
}
}
}
static void uc2_special3 ()
{
RDP ("uc2:special3\n");
}
static void uc2_special2 ()
{
RDP ("uc2:special2\n");
}
#ifdef _WIN32
static void uc2_special1 ()
{
RDP ("uc2:special1\n");
}
#endif // _WIN32
static void uc2_dma_io ()
{
RDP ("uc2:dma_io\n");
}
static void uc2_pop_matrix ()
{
FRDP ("uc2:pop_matrix %08lx, %08lx\n", rdp.cmd0, rdp.cmd1);
// Just pop the modelview matrix
modelview_pop (rdp.cmd1 >> 6);
}
static void uc2_geom_mode ()
{
// Switch around some things
DWORD clr_mode = (rdp.cmd0 & 0x00DFC9FF) |
((rdp.cmd0 & 0x00000600) << 3) |
((rdp.cmd0 & 0x00200000) >> 12) | 0xFF000000;
DWORD set_mode = (rdp.cmd1 & 0xFFDFC9FF) |
((rdp.cmd1 & 0x00000600) << 3) |
((rdp.cmd1 & 0x00200000) >> 12);
FRDP("uc2:geom_mode c:%08lx, s:%08lx ", clr_mode, set_mode);
rdp.geom_mode &= clr_mode;
rdp.geom_mode |= set_mode;
FRDP ("result:%08lx\n", rdp.geom_mode);
if (rdp.geom_mode & 0x00000001) // Z-Buffer enable
{
if (!(rdp.flags & ZBUF_ENABLED))
{
rdp.flags |= ZBUF_ENABLED;
rdp.update |= UPDATE_ZBUF_ENABLED;
}
}
else
{
if ((rdp.flags & ZBUF_ENABLED))
{
if (!settings.flame_corona || (rdp.rm != 0x00504341)) //hack for flame's corona
rdp.flags ^= ZBUF_ENABLED;
rdp.update |= UPDATE_ZBUF_ENABLED;
}
}
if (rdp.geom_mode & 0x00001000) // Front culling
{
if (!(rdp.flags & CULL_FRONT))
{
rdp.flags |= CULL_FRONT;
rdp.update |= UPDATE_CULL_MODE;
}
}
else
{
if (rdp.flags & CULL_FRONT)
{
rdp.flags ^= CULL_FRONT;
rdp.update |= UPDATE_CULL_MODE;
}
}
if (rdp.geom_mode & 0x00002000) // Back culling
{
if (!(rdp.flags & CULL_BACK))
{
rdp.flags |= CULL_BACK;
rdp.update |= UPDATE_CULL_MODE;
}
}
else
{
if (rdp.flags & CULL_BACK)
{
rdp.flags ^= CULL_BACK;
rdp.update |= UPDATE_CULL_MODE;
}
}
//Added by Gonetz
if (rdp.geom_mode & 0x00010000) // Fog enable
{
if (!(rdp.flags & FOG_ENABLED))
{
rdp.flags |= FOG_ENABLED;
rdp.update |= UPDATE_FOG_ENABLED;
}
}
else
{
if (rdp.flags & FOG_ENABLED)
{
rdp.flags ^= FOG_ENABLED;
rdp.update |= UPDATE_FOG_ENABLED;
}
}
}
void uc6_obj_rectangle_r ();
static void uc2_matrix ()
{
if (!(rdp.cmd0 & 0x00FFFFFF))
{
uc6_obj_rectangle_r();
return;
}
RDP ("uc2:matrix\n");
DWORD addr = segoffset(rdp.cmd1);
BYTE command = (BYTE)((rdp.cmd0 ^ 1) & 0xFF);
__declspec( align(16) ) float m[4][4];
int x,y; // matrix index
addr >>= 1;
for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later
for (y=0; y<4; y++) {
m[x>>2][y] = (float)(
(((__int32)((WORD*)gfx.RDRAM)[(addr+x+y)^1]) << 16) |
((WORD*)gfx.RDRAM)[(addr+x+y+16)^1]
) / 65536.0f;
}
}
switch (command)
{
case 0: // modelview mul nopush
RDP ("modelview mul\n");
modelview_mul (m);
break;
case 1: // modelview mul push
RDP ("modelview mul push\n");
modelview_mul_push (m);
break;
case 2: // modelview load nopush
RDP ("modelview load\n");
modelview_load (m);
break;
case 3: // modelview load push
RDP ("modelview load push\n");
modelview_load_push (m);
break;
case 4: // projection mul nopush
case 5: // projection mul push, can't push projection
RDP ("projection mul\n");
projection_mul (m);
break;
case 6: // projection load nopush
case 7: // projection load push, can't push projection
RDP ("projection load\n");
projection_load (m);
break;
default:
FRDP_E ("Unknown matrix command, %02lx", command);
FRDP ("Unknown matrix command, %02lx", command);
}
#ifdef EXTREME_LOGGING
FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]);
FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]);
FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]);
FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]);
FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]);
FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]);
#endif
}
static void uc2_moveword ()
{
BYTE index = (BYTE)((rdp.cmd0 >> 16) & 0xFF);
WORD offset = (WORD)(rdp.cmd0 & 0xFFFF);
DWORD data = rdp.cmd1;
FRDP ("uc2:moveword ");
switch (index)
{
// NOTE: right now it's assuming that it sets the integer part first. This could
// be easily fixed, but only if i had something to test with.
case 0x00: // moveword matrix
{
// do matrix pre-mult so it's re-updated next time
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
if (rdp.cmd0 & 0x20) // fractional part
{
int index_x = (rdp.cmd0 & 0x1F) >> 1;
int index_y = index_x >> 2;
index_x &= 3;
float fpart = (rdp.cmd1>>16)/65536.0f;
rdp.combined[index_y][index_x] = (float)(int)rdp.combined[index_y][index_x];
rdp.combined[index_y][index_x] += fpart;
fpart = (rdp.cmd1&0xFFFF)/65536.0f;
rdp.combined[index_y][index_x+1] = (float)(int)rdp.combined[index_y][index_x+1];
rdp.combined[index_y][index_x+1] += fpart;
}
else
{
int index_x = (rdp.cmd0 & 0x1F) >> 1;
int index_y = index_x >> 2;
index_x &= 3;
rdp.combined[index_y][index_x] = (short)(rdp.cmd1>>16);
rdp.combined[index_y][index_x+1] = (short)(rdp.cmd1&0xFFFF);
}
RDP ("matrix\n");
}
break;
case 0x02:
rdp.num_lights = data / 24;
rdp.update |= UPDATE_LIGHTS;
FRDP ("numlights: %d\n", rdp.num_lights);
break;
case 0x04:
FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1);
break;
case 0x06: // moveword SEGMENT
{
FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2);
if ((data&BMASK)<BMASK)
rdp.segment[(offset >> 2) & 0xF] = data;
}
break;
case 0x08:
{
rdp.fog_multiplier = (short)(rdp.cmd1 >> 16);
rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF);
FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset);
}
break;
case 0x0a: // moveword LIGHTCOL
{
int n = offset / 24;
FRDP ("lightcol light:%d, %08lx\n", n, data);
rdp.light[n].r = (float)((data >> 24) & 0xFF) / 255.0f;
rdp.light[n].g = (float)((data >> 16) & 0xFF) / 255.0f;
rdp.light[n].b = (float)((data >> 8) & 0xFF) / 255.0f;
rdp.light[n].a = 255;
}
break;
case 0x0c:
RDP_E ("uc2:moveword forcemtx - IGNORED\n");
RDP ("forcemtx - IGNORED\n");
break;
case 0x0e:
RDP ("perspnorm - IGNORED\n");
break;
default:
FRDP_E("uc2:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset);
FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset);
}
}
void uc6_obj_movemem ();
static void uc2_movemem ()
{
int idx = rdp.cmd0 & 0xFF;
DWORD addr = segoffset(rdp.cmd1);
int ofs = (rdp.cmd0 >> 5) & 0x7F8;
FRDP ("uc2:movemem ofs:%d ", ofs);
switch (idx)
{
case 0:
case 2:
uc6_obj_movemem ();
break;
case 8: // VIEWPORT
{
DWORD a = addr >> 1;
short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2;
short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2;
short scale_z = ((short*)gfx.RDRAM)[(a+2)^1];
short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2;
short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2;
short trans_z = ((short*)gfx.RDRAM)[(a+6)^1];
rdp.view_scale[0] = scale_x * rdp.scale_x;
rdp.view_scale[1] = -scale_y * rdp.scale_y;
rdp.view_scale[2] = 32.0f * scale_z;
rdp.view_trans[0] = trans_x * rdp.scale_x;
rdp.view_trans[1] = trans_y * rdp.scale_y;
rdp.view_trans[2] = 32.0f * trans_z;
rdp.update |= UPDATE_VIEWPORT;
FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z,
trans_x, trans_y, trans_z, a);
}
break;
case 10: // LIGHT
{
int n = ofs / 24;
if (n < 2)
{
char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3];
rdp.lookat[n][0] = (float)(dir_x) / 127.0f;
char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3];
rdp.lookat[n][1] = (float)(dir_y) / 127.0f;
char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3];
rdp.lookat[n][2] = (float)(dir_z) / 127.0f;
rdp.use_lookat = TRUE;
if (n == 1)
{
if (!dir_x && !dir_y)
rdp.use_lookat = FALSE;
}
FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]);
return;
}
n -= 2;
if (n > 7) return;
// Get the data
BYTE col = gfx.RDRAM[(addr+0)^3];
rdp.light[n].r = (float)col / 255.0f;
rdp.light[n].nonblack = col;
col = gfx.RDRAM[(addr+1)^3];
rdp.light[n].g = (float)col / 255.0f;
rdp.light[n].nonblack += col;
col = gfx.RDRAM[(addr+2)^3];
rdp.light[n].b = (float)col / 255.0f;
rdp.light[n].nonblack += col;
rdp.light[n].a = 1.0f;
// ** Thanks to Icepir8 for pointing this out **
// Lighting must be signed byte instead of byte
rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f;
rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f;
rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f;
DWORD a = addr >> 1;
rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+4)^1]);
rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+5)^1]);
rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+6)^1]);
rdp.light[n].ca = (float)(gfx.RDRAM[(addr+3)^3]) / 16.0f;
rdp.light[n].la = (float)(gfx.RDRAM[(addr+7)^3]);
rdp.light[n].qa = (float)(gfx.RDRAM[(addr+14)^3]) / 8.0f;
#ifdef EXTREME_LOGGING
FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, ca: %f, la:%f, qa: %f\n",
n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].ca, rdp.light[n].la, rdp.light[n].qa);
#endif
FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f. dir: x: %.3f, y: %.3f, z: %.3f\n",
n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b,
rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z);
}
break;
case 14: // matrix
{
// do not update the combined matrix!
rdp.update &= ~UPDATE_MULT_MAT;
int addr = segoffset(rdp.cmd1);
FRDP ("matrix - addr: %08lx\n", addr);
addr >>= 1;
int x,y;
for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later
for (y=0; y<4; y++) {
rdp.combined[x>>2][y] = (float)(
(((__int32)((WORD*)gfx.RDRAM)[(addr+x+y)^1]) << 16) |
((WORD*)gfx.RDRAM)[(addr+x+y+16)^1]
) / 65536.0f;
}
}
#ifdef EXTREME_LOGGING
FRDP ("{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]);
#endif
}
break;
default:
FRDP ("uc2:matrix unknown (%d)\n", idx);
FRDP ("** UNKNOWN %d\n", idx);
}
}
static void uc2_load_ucode ()
{
RDP ("uc2:load_ucode\n");
}
static void uc2_rdphalf_2 ()
{
RDP ("uc2:rdphalf_2\n");
}
static void uc2_dlist_cnt ()
{
DWORD addr = segoffset(rdp.cmd1) & BMASK;
int count = rdp.cmd0 & 0x000000FF;
FRDP ("dl_count - addr: %08lx, count: %d\n", addr, count);
if (addr == 0)
return;
if (rdp.pc_i >= 9) {
RDP_E ("** DL stack overflow **\n");
RDP ("** DL stack overflow **\n");
return;
}
rdp.pc_i ++; // go to the next PC in the stack
rdp.pc[rdp.pc_i] = addr; // jump to the address
rdp.dl_count = count + 1;
}

View File

@ -0,0 +1,253 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// March 2002 Created by Gonetz (Gonetz@ngs.ru)
// Info about this ucode is taken from Daedalus source. Thanks to Daedalus team.
//
//****************************************************************
//
// vertex - loads vertices
//
static void uc3_vertex()
{
DWORD addr = segoffset(rdp.cmd1) & 0x00FFFFFF;
int v0, i, n;
float x, y, z;
rdp.v0 = v0 = ((rdp.cmd0 >> 16) & 0xFF)/5; // Current vertex
rdp.vn = n = (WORD)((rdp.cmd0&0xFFFF) + 1)/0x210; // Number to copy
FRDP ("uc3:vertex v0:%d, n:%d, from: %08lx\n", v0, n, addr);
if (v0 >= 32)
v0 = 31;
if ((v0 + n) > 32)
{
n = 32 - v0;
}
// This is special, not handled in update(), but here
// * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
// *
// This is special, not handled in update()
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
}
}
for (i=0; i < (n<<4); i+=16)
{
VERTEX *v = &rdp.vtx[v0 + (i>>4)];
x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
CalculateFog (v);
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
if (rdp.geom_mode & 0x00020000)
{
v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
if (rdp.geom_mode & 0x80000)
calc_linear (v);
else if (rdp.geom_mode & 0x40000)
calc_sphere (v);
NormalizeVector (v->vec);
calc_light (v);
}
else
{
v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
}
}
}
//
// tri1 - renders a triangle
//
static void uc3_tri1()
{
FRDP("uc3:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n,
((rdp.cmd1 >> 16) & 0xFF)/5,
((rdp.cmd1 >> 8) & 0xFF)/5,
((rdp.cmd1 ) & 0xFF)/5, rdp.cmd0, rdp.cmd1);
VERTEX *v[3] = {
&rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5],
&rdp.vtx[(rdp.cmd1 & 0xFF)/5]
};
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v);
rdp.tri_n ++;
}
}
static void uc3_tri2 ()
{
FRDP("uc3:tri2 #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1,
((rdp.cmd0 >> 16) & 0xFF)/5,
((rdp.cmd0 >> 8) & 0xFF)/5,
((rdp.cmd0 ) & 0xFF)/5,
((rdp.cmd1 >> 16) & 0xFF)/5,
((rdp.cmd1 >> 8) & 0xFF)/5,
((rdp.cmd1 ) & 0xFF)/5);
VERTEX *v[6] = {
&rdp.vtx[((rdp.cmd0 >> 16) & 0xFF)/5],
&rdp.vtx[((rdp.cmd0 >> 8) & 0xFF)/5],
&rdp.vtx[(rdp.cmd0 & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5],
&rdp.vtx[(rdp.cmd1 & 0xFF)/5]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}
static void uc3_quad3d()
{
FRDP("uc3:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
VERTEX *v[7] = {
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5],
&rdp.vtx[(rdp.cmd1 & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5],
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}

View File

@ -0,0 +1,192 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//****************************************************************
// uCode 4 - RSP SW 2.0D EXT
//****************************************************************
static void uc4_vertex()
{
DWORD addr = segoffset(rdp.cmd1) & 0x00FFFFFF;
int v0, i, n;
float x, y, z;
rdp.v0 = v0 = 0; // Current vertex
rdp.vn = n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy
FRDP("uc4:vertex: v0: %d, n: %d\n", v0, n);
// This is special, not handled in update(), but here
// * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
// *
// This is special, not handled in update()
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
}
}
for (i=0; i < (n<<4); i+=16)
{
VERTEX *v = &rdp.vtx[v0 + (i>>4)];
x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
CalculateFog (v);
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
if (rdp.geom_mode & 0x00020000)
{
v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
if (rdp.geom_mode & 0x80000)
calc_linear (v);
else if (rdp.geom_mode & 0x40000)
calc_sphere (v);
NormalizeVector (v->vec);
calc_light (v);
}
else
{
v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
}
}
}
static void uc4_tri1()
{
int v1 = ((rdp.cmd1 >> 16) & 0xFF) / 5;
int v2 = ((rdp.cmd1 >> 8) & 0xFF) / 5;
int v3 = (rdp.cmd1 & 0xFF) / 5;
FRDP("uc4:tri1 #%d - %d, %d, %d\n", rdp.tri_n,
v1, v2, v3);
VERTEX *v[3] = {
&rdp.vtx[v1],
&rdp.vtx[v2],
&rdp.vtx[v3]
};
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v);
rdp.tri_n ++;
}
}
static void uc4_quad3d()
{
FRDP("uc4:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
VERTEX *v[6] = {
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5],
&rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5],
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5],
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5],
&rdp.vtx[(rdp.cmd1 & 0xFF) / 5]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
update ();
DrawTri (v+3);
rdp.tri_n ++;
}
}

View File

@ -0,0 +1,389 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
int cur_mtx = 0;
BOOL billboarding = 0;
int vtx_last = 0;
DWORD dma_offset_mtx = 0;
DWORD dma_offset_vtx = 0;
static void uc5_dma_offsets ()
{
dma_offset_mtx = rdp.cmd0 & 0x00FFFFFF;
dma_offset_vtx = rdp.cmd1 & 0x00FFFFFF;
vtx_last = 0;
FRDP("uc5:dma_offsets - mtx: %08lx, vtx: %08lx\n", dma_offset_mtx, dma_offset_vtx);
}
static void uc5_matrix ()
{
// Use segment offset to get the address
DWORD addr = dma_offset_mtx + (segoffset(rdp.cmd1) & BMASK);
BYTE n = (BYTE)((rdp.cmd0 >> 16) & 0xF);
BYTE multiply;
if (n == 0) //DKR
{
n = (BYTE)((rdp.cmd0 >> 22) & 0x3);
multiply = 0;
}
else //JF
{
multiply = (BYTE)((rdp.cmd0 >> 23) & 0x1);
}
cur_mtx = n;
FRDP("uc5:matrix - #%d, addr: %08lx\n", n, addr);
addr >>= 1;
int x,y; // matrix index
if (multiply)
{
__declspec( align(16) ) float m[4][4];
for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later
for (y=0; y<4; y++) {
m[x>>2][y] = (float)(
(((__int32)((WORD*)gfx.RDRAM)[(addr+x+y)^1]) << 16) |
((WORD*)gfx.RDRAM)[(addr+x+y+16)^1]
) / 65536.0f;
}
}
__declspec( align(16) ) float m_src[4][4];
memcpy (m_src, rdp.dkrproj[0], 64);
MulMatrices(m, m_src, rdp.dkrproj[n]);
}
else
{
for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later
for (y=0; y<4; y++) {
rdp.dkrproj[n][x>>2][y] = (float)(
(((__int32)((WORD*)gfx.RDRAM)[(addr+x+y)^1]) << 16) |
((WORD*)gfx.RDRAM)[(addr+x+y+16)^1]
) / 65536.0f;
}
}
}
rdp.update |= UPDATE_MULT_MAT;
#ifdef EXTREME_LOGGING
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][0][0], rdp.dkrproj[n][0][1], rdp.dkrproj[n][0][2], rdp.dkrproj[n][0][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][1][0], rdp.dkrproj[n][1][1], rdp.dkrproj[n][1][2], rdp.dkrproj[n][1][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][2][0], rdp.dkrproj[n][2][1], rdp.dkrproj[n][2][2], rdp.dkrproj[n][2][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][3][0], rdp.dkrproj[n][3][1], rdp.dkrproj[n][3][2], rdp.dkrproj[n][3][3]);
for (int i=0; i<3; i++)
{
FRDP ("proj %d\n", i);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][0][0], rdp.dkrproj[i][0][1], rdp.dkrproj[i][0][2], rdp.dkrproj[i][0][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][1][0], rdp.dkrproj[i][1][1], rdp.dkrproj[i][1][2], rdp.dkrproj[i][1][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][2][0], rdp.dkrproj[i][2][1], rdp.dkrproj[i][2][2], rdp.dkrproj[i][2][3]);
FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][3][0], rdp.dkrproj[i][3][1], rdp.dkrproj[i][3][2], rdp.dkrproj[i][3][3]);
}
#endif
}
static void uc5_vertex ()
{
DWORD addr = dma_offset_vtx + (segoffset(rdp.cmd1) & BMASK);
// | cccc cccc 1111 1??? 0000 0002 2222 2222 | cmd1 = address |
// c = vtx command
// 1 = method #1 of getting count
// 2 = method #2 of getting count
// ? = unknown, but used
// 0 = unused
int n = ((rdp.cmd0 >> 19) & 0x1F);// + 1;
if (settings.diddy)
n++;
//int n = ((rdp.cmd0 & 0x1FF) - 8) / 18; // same thing!
if (rdp.cmd0 & 0x00010000)
{
if (billboarding)
vtx_last = 1;
}
else
vtx_last = 0;
int first = ((rdp.cmd0 >> 9) & 0x1F) + vtx_last;
FRDP ("uc5:vertex - addr: %08lx, first: %d, count: %d, matrix: %08lx\n", addr, first, n, cur_mtx);
int prj = cur_mtx;
int start = 0;
float x, y, z;
for (int i=first; i<first+n; i++)
{
start = (i-first) * 10;
VERTEX *v = &rdp.vtx[i];
x = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 2)^1];
v->x = x*rdp.dkrproj[prj][0][0] + y*rdp.dkrproj[prj][1][0] + z*rdp.dkrproj[prj][2][0] + rdp.dkrproj[prj][3][0];
v->y = x*rdp.dkrproj[prj][0][1] + y*rdp.dkrproj[prj][1][1] + z*rdp.dkrproj[prj][2][1] + rdp.dkrproj[prj][3][1];
v->z = x*rdp.dkrproj[prj][0][2] + y*rdp.dkrproj[prj][1][2] + z*rdp.dkrproj[prj][2][2] + rdp.dkrproj[prj][3][2];
v->w = x*rdp.dkrproj[prj][0][3] + y*rdp.dkrproj[prj][1][3] + z*rdp.dkrproj[prj][2][3] + rdp.dkrproj[prj][3][3];
if (billboarding)
{
v->x += rdp.vtx[0].x;
v->y += rdp.vtx[0].y;
v->z += rdp.vtx[0].z;
v->w += rdp.vtx[0].w;
}
#ifdef EXTREME_LOGGING
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f\n", i, v->x, v->y, v->z, v->w);
#endif
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
v->r = ((BYTE*)gfx.RDRAM)[(addr+start + 6)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+start + 7)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+start + 8)^3];
v->a = ((BYTE*)gfx.RDRAM)[(addr+start + 9)^3];
CalculateFog (v);
#ifdef EXTREME_LOGGING
FRDP ("vtx%d: x: %f, y: %f, z: %f, w: %f\n", i, v->x, v->y, v->z, v->w);
#endif
}
vtx_last += n;
}
static void uc5_tridma ()
{
vtx_last = 0; // we've drawn something, so the vertex index needs resetting
if (rdp.skip_drawing)
return;
// | cccc cccc 2222 0000 1111 1111 1111 0000 | cmd1 = address |
// c = tridma command
// 1 = method #1 of getting count
// 2 = method #2 of getting count
// 0 = unused
DWORD addr = segoffset(rdp.cmd1) & BMASK;
int num = (rdp.cmd0 & 0xFFF0) >> 4;
//int num = ((rdp.cmd0 & 0x00F00000) >> 20) + 1; // same thing!
FRDP("uc5:tridma #%d - addr: %08lx, count: %d\n", rdp.tri_n, addr, num);
int start, v0, v1, v2, flags;
for (int i=0; i<num; i++)
{
start = i << 4;
v0 = gfx.RDRAM[addr+start];
v1 = gfx.RDRAM[addr+start+1];
v2 = gfx.RDRAM[addr+start+2];
FRDP("tri #%d - %d, %d, %d\n", rdp.tri_n, v0, v1, v2);
VERTEX *v[3] = {
&rdp.vtx[v0],
&rdp.vtx[v1],
&rdp.vtx[v2]
};
flags = gfx.RDRAM[addr+start+3];
if (flags & 0x40) { // no cull
rdp.flags &= ~CULLMASK;
grCullMode (GR_CULL_DISABLE);
}
else { // front cull
rdp.flags &= ~CULLMASK;
if (rdp.view_scale[0] < 0) {
rdp.flags |= CULL_BACK; // agh, backwards culling
grCullMode (GR_CULL_POSITIVE);
}
else {
rdp.flags |= CULL_FRONT;
grCullMode (GR_CULL_NEGATIVE);
}
}
start += 4;
v[0]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 5] / 32.0f;
v[0]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 4] / 32.0f;
v[1]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 3] / 32.0f;
v[1]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 2] / 32.0f;
v[2]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 1] / 32.0f;
v[2]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 0] / 32.0f;
v[0]->uv_calculated = 0xFFFFFFFF;
v[1]->uv_calculated = 0xFFFFFFFF;
v[2]->uv_calculated = 0xFFFFFFFF;
if (cull_tri(v))
rdp.tri_n ++;
else
{
update ();
DrawTri (v);
rdp.tri_n ++;
}
}
}
static void uc5_dl_in_mem ()
{
DWORD addr = segoffset(rdp.cmd1) & BMASK;
int count = (rdp.cmd0 & 0x00FF0000) >> 16;
FRDP ("uc5:dl_in_mem - addr: %08lx, count: %d\n", addr, count);
if (rdp.pc_i >= 9) {
RDP_E ("** DL stack overflow **\n");
RDP ("** DL stack overflow **\n");
return;
}
rdp.pc_i ++; // go to the next PC in the stack
rdp.pc[rdp.pc_i] = addr; // jump to the address
rdp.dl_count = count + 1;
}
static void uc5_moveword()
{
RDP("uc5:moveword ");
// Find which command this is (lowest byte of cmd0)
switch (rdp.cmd0 & 0xFF)
{
case 0x02: // moveword matrix 2 billboard
billboarding = (rdp.cmd1 & 1);
FRDP ("matrix billboard - %s\n", str_offon[billboarding]);
break;
case 0x04: // clip (verified same)
FRDP ("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1);
break;
case 0x06: // segment (verified same)
FRDP ("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F);
rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1;
break;
case 0x08:
{
rdp.fog_multiplier = (short)(rdp.cmd1 >> 16);
rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF);
FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset);
// rdp.update |= UPDATE_FOG_ENABLED;
}
break;
case 0x0a: // moveword matrix select
cur_mtx = (rdp.cmd1 >> 6) & 3;
FRDP ("matrix select - mtx: %d\n", cur_mtx);
break;
default:
FRDP ("(unknown) %02lx - IGNORED\n", rdp.cmd0&0xFF);
}
}
static void uc5_setgeometrymode()
{
FRDP("uc0:setgeometrymode %08lx\n", rdp.cmd1);
rdp.geom_mode |= rdp.cmd1;
if (rdp.cmd1 & 0x00000001) // Z-Buffer enable
{
if (!(rdp.flags & ZBUF_ENABLED))
{
rdp.flags |= ZBUF_ENABLED;
rdp.update |= UPDATE_ZBUF_ENABLED;
}
}
//Added by Gonetz
if (rdp.cmd1 & 0x00010000) // Fog enable
{
if (!(rdp.flags & FOG_ENABLED))
{
rdp.flags |= FOG_ENABLED;
rdp.update |= UPDATE_FOG_ENABLED;
}
}
}
static void uc5_cleargeometrymode()
{
FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1);
rdp.geom_mode &= (~rdp.cmd1);
if (rdp.cmd1 & 0x00000001) // Z-Buffer enable
{
if (rdp.flags & ZBUF_ENABLED)
{
rdp.flags ^= ZBUF_ENABLED;
rdp.update |= UPDATE_ZBUF_ENABLED;
}
}
//Added by Gonetz
if (rdp.cmd1 & 0x00010000) // Fog enable
{
if (rdp.flags & FOG_ENABLED)
{
rdp.flags ^= FOG_ENABLED;
rdp.update |= UPDATE_FOG_ENABLED;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,174 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// Oct 2002 Created by Gonetz (Gonetz@ngs.ru)
// Info about this ucode is taken from TR64 OGL plugin. Thanks, Icepir8!
// Oct 2003 Modified by Gonetz (Gonetz@ngs.ru)
// Bugs fixed with help from glN64 sources. Thanks, Orkin!
//****************************************************************
DWORD pd_col_addr = 0;
static void uc7_colorbase ()
{
RDP("uc7_colorbase\n");
pd_col_addr = segoffset(rdp.cmd1);
}
typedef struct
{
short y;
short x;
WORD idx;
short z;
short t;
short s;
} vtx_uc7;
static void uc7_vertex ()
{
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
// This is special, not handled in update()
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
}
}
DWORD addr = segoffset(rdp.cmd1);
DWORD v0, i, n;
float x, y, z;
rdp.v0 = v0 = (rdp.cmd0 & 0x0F0000) >> 16;
rdp.vn = n = ((rdp.cmd0 & 0xF00000) >> 20) + 1;
FRDP ("uc7:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr);
vtx_uc7 *vertex = (vtx_uc7 *)&gfx.RDRAM[addr];
for(i = 0; i < n; i++)
{
VERTEX *v = &rdp.vtx[v0 + i];
x = (float)vertex->x;
y = (float)vertex->y;
z = (float)vertex->z;
v->flags = 0;
v->ou = (float)vertex->s * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)vertex->t * rdp.tiles[rdp.cur_tile].t_scale;
#ifdef EXTREME_LOGGING
// FRDP ("before: v%d - x: %f, y: %f, z: %f, flags: %04lx, ou: %f, ov: %f\n", i>>4, x, y, z, v->flags, v->ou, v->ov);
#endif
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
BYTE *color = &gfx.RDRAM[pd_col_addr + (vertex->idx & 0xff)];
v->a = color[0];
CalculateFog (v);
if (rdp.geom_mode & 0x00020000)
{
v->vec[0] = (char)color[3];
v->vec[1] = (char)color[2];
v->vec[2] = (char)color[1];
if (rdp.geom_mode & 0x80000)
{
calc_linear (v);
#ifdef EXTREME_LOGGING
FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
else if (rdp.geom_mode & 0x40000)
{
calc_sphere (v);
#ifdef EXTREME_LOGGING
FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
NormalizeVector (v->vec);
calc_light (v);
}
else
{
v->r = color[3];
v->g = color[2];
v->b = color[1];
}
#ifdef EXTREME_LOGGING
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov);
#endif
vertex++;
}
}

View File

@ -0,0 +1,537 @@
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators.
* Copyright (c) 2002 Dave2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
// Project started on December 29th, 2001
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
// Official Glide64 development channel: #Glide64 on EFnet
//
// Original author: Dave2001 (Dave2999@hotmail.com)
// Other authors: Gonetz, Gugaman
//
//****************************************************************
//
// January 2004 Created by Gonetz (Gonetz@ngs.ru)
//****************************************************************
DWORD uc8_normale_addr = 0;
float uc8_coord_mod[16];
static void uc8_vertex ()
{
if (rdp.update & UPDATE_MULT_MAT)
{
rdp.update ^= UPDATE_MULT_MAT;
MulMatrices(rdp.model, rdp.proj, rdp.combined);
}
DWORD addr = segoffset(rdp.cmd1);
int v0, i, n;
float x, y, z;
rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF;
rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n;
FRDP ("uc8:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr);
if (v0 < 0)
{
RDP_E ("** ERROR: uc2:vertex v0 < 0\n");
RDP ("** ERROR: uc2:vertex v0 < 0\n");
return;
}
//*
// This is special, not handled in update()
if (rdp.update & UPDATE_LIGHTS)
{
rdp.update ^= UPDATE_LIGHTS;
// Calculate light vectors
for (DWORD l=0; l<rdp.num_lights; l++)
{
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
NormalizeVector (rdp.light_vector[l]);
#ifdef EXTREME_LOGGING
FRDP("light_vector[%d] x: %f, y: %f, z: %f\n", l, rdp.light_vector[l][0], rdp.light_vector[l][1], rdp.light_vector[l][2]);
#endif
}
}
//*/
for (i=0; i < (n<<4); i+=16)
{
VERTEX *v = &rdp.vtx[v0 + (i>>4)];
x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
#ifdef EXTREME_LOGGING
FRDP ("before v%d - x: %f, y: %f, z: %f\n", i>>4, x, y, z);
#endif
v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
#ifdef EXTREME_LOGGING
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, flags: %d\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov, v->flags);
#endif
v->oow = 1.0f / v->w;
v->x_w = v->x * v->oow;
v->y_w = v->y * v->oow;
v->z_w = v->z * v->oow;
v->uv_calculated = 0xFFFFFFFF;
v->screen_translated = 0;
v->shade_mods_allowed = 1;
v->scr_off = 0;
if (v->x < -v->w) v->scr_off |= 1;
if (v->x > v->w) v->scr_off |= 2;
if (v->y < -v->w) v->scr_off |= 4;
if (v->y > v->w) v->scr_off |= 8;
if (v->w < 0.1f) v->scr_off |= 16;
///*
v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
#ifdef EXTREME_LOGGING
FRDP ("r: %02lx, g: %02lx, b: %02lx, a: %02lx\n", v->r, v->g, v->b, v->a);
#endif
if ((rdp.geom_mode & 0x00020000))
{
DWORD shift = v0 << 1;
v->vec[0] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 0)^3];
v->vec[1] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 1)^3];
v->vec[2] = (char)(v->flags&0xff);
if (rdp.geom_mode & 0x80000)
{
calc_linear (v);
#ifdef EXTREME_LOGGING
FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
else if (rdp.geom_mode & 0x40000)
{
calc_sphere (v);
#ifdef EXTREME_LOGGING
FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov);
#endif
}
// FRDP("calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx, nx: %.3f, ny: %.3f, nz: %.3f\n", v->r, v->g, v->b, v->vec[0], v->vec[1], v->vec[2]);
FRDP("v[%d] calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", i>>4, v->r, v->g, v->b);
float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b};
FRDP("ambient light. r: %f, g: %f, b: %f\n", color[0], color[1], color[2]);
float light_intensity = 0.0f;
DWORD l;
if (rdp.geom_mode & 0x00400000)
{
NormalizeVector (v->vec);
for (l = 0; l < rdp.num_lights-1; l++)
{
if (!rdp.light[l].nonblack)
continue;
light_intensity = DotProduct (rdp.light_vector[l], v->vec);
FRDP("light %d, intensity : %f\n", l, light_intensity);
if (light_intensity < 0.0f)
continue;
//*
if (rdp.light[l].ca > 0.0f)
{
float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x;
float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y;
float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z;
float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w;
float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f;
float p_i = rdp.light[l].ca / len;
if (p_i > 1.0f) p_i = 1.0f;
light_intensity *= p_i;
FRDP("light %d, len: %f, p_intensity : %f\n", l, len, p_i);
}
//*/
color[0] += rdp.light[l].r * light_intensity;
color[1] += rdp.light[l].g * light_intensity;
color[2] += rdp.light[l].b * light_intensity;
FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]);
}
light_intensity = DotProduct (rdp.light_vector[l], v->vec);
FRDP("light %d, intensity : %f\n", l, light_intensity);
if (light_intensity > 0.0f)
{
color[0] += rdp.light[l].r * light_intensity;
color[1] += rdp.light[l].g * light_intensity;
color[2] += rdp.light[l].b * light_intensity;
}
FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]);
}
else
{
for (l = 0; l < rdp.num_lights; l++)
{
if (rdp.light[l].nonblack && rdp.light[l].nonzero)
{
float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x;
float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y;
float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z;
float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w;
float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f;
light_intensity = rdp.light[l].ca / len;
if (light_intensity > 1.0f) light_intensity = 1.0f;
FRDP("light %d, p_intensity : %f\n", l, light_intensity);
color[0] += rdp.light[l].r * light_intensity;
color[1] += rdp.light[l].g * light_intensity;
color[2] += rdp.light[l].b * light_intensity;
//FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]);
}
}
}
if (color[0] > 1.0f) color[0] = 1.0f;
if (color[1] > 1.0f) color[1] = 1.0f;
if (color[2] > 1.0f) color[2] = 1.0f;
v->r = (BYTE)(((float)v->r)*color[0]);
v->g = (BYTE)(((float)v->g)*color[1]);
v->b = (BYTE)(((float)v->b)*color[2]);
#ifdef EXTREME_LOGGING
FRDP("color after light: r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", v->r, v->g, v->b);
#endif
}
}
}
static void uc8_moveword ()
{
BYTE index = (BYTE)((rdp.cmd0 >> 16) & 0xFF);
WORD offset = (WORD)(rdp.cmd0 & 0xFFFF);
DWORD data = rdp.cmd1;
FRDP ("uc8:moveword ");
switch (index)
{
// NOTE: right now it's assuming that it sets the integer part first. This could
// be easily fixed, but only if i had something to test with.
case 0x02:
rdp.num_lights = (data / 48);
rdp.update |= UPDATE_LIGHTS;
FRDP ("numlights: %d\n", rdp.num_lights);
break;
case 0x04:
FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1);
break;
case 0x06: // moveword SEGMENT
{
FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2);
rdp.segment[(offset >> 2) & 0xF] = data;
}
break;
case 0x08:
{
rdp.fog_multiplier = (short)(rdp.cmd1 >> 16);
rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF);
FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset);
}
break;
case 0x0c:
RDP_E ("uc8:moveword forcemtx - IGNORED\n");
RDP ("forcemtx - IGNORED\n");
break;
case 0x0e:
RDP ("perspnorm - IGNORED\n");
break;
case 0x10: // moveword coord mod
{
BYTE n = offset >> 2;
FRDP ("coord mod:%d, %08lx\n", n, data);
if (rdp.cmd0&8)
return;
DWORD idx = (rdp.cmd0>>1)&3;
DWORD pos = rdp.cmd0&0x30;
if (pos == 0)
{
uc8_coord_mod[0+idx] = (short)(rdp.cmd1>>16);
uc8_coord_mod[1+idx] = (short)(rdp.cmd1&0xffff);
}
else if (pos == 0x10)
{
uc8_coord_mod[4+idx] = (rdp.cmd1>>16)/65536.0f;
uc8_coord_mod[5+idx] = (rdp.cmd1&0xffff)/65536.0f;
uc8_coord_mod[12+idx] = uc8_coord_mod[0+idx] + uc8_coord_mod[4+idx];
uc8_coord_mod[13+idx] = uc8_coord_mod[1+idx] + uc8_coord_mod[5+idx];
}
else if (pos == 0x20)
{
uc8_coord_mod[8+idx] = (short)(rdp.cmd1>>16);
uc8_coord_mod[9+idx] = (short)(rdp.cmd1&0xffff);
#ifdef EXTREME_LOGGING
if (idx)
{
for (int k = 8; k < 16; k++)
{
FRDP("coord_mod[%d]=%f\n", k, uc8_coord_mod[k]);
}
}
#endif
}
}
break;
default:
FRDP_E("uc8:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset);
FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset);
}
}
static void uc8_movemem ()
{
int idx = rdp.cmd0 & 0xFF;
DWORD addr = segoffset(rdp.cmd1);
int ofs = (rdp.cmd0 >> 5) & 0x3FFF;
FRDP ("uc8:movemem ofs:%d ", ofs);
switch (idx)
{
case 8: // VIEWPORT
{
DWORD a = addr >> 1;
short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2;
short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2;
short scale_z = ((short*)gfx.RDRAM)[(a+2)^1];
short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2;
short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2;
short trans_z = ((short*)gfx.RDRAM)[(a+6)^1];
rdp.view_scale[0] = scale_x * rdp.scale_x;
rdp.view_scale[1] = -scale_y * rdp.scale_y;
rdp.view_scale[2] = 32.0f * scale_z;
rdp.view_trans[0] = trans_x * rdp.scale_x;
rdp.view_trans[1] = trans_y * rdp.scale_y;
rdp.view_trans[2] = 32.0f * trans_z;
rdp.update |= UPDATE_VIEWPORT;
FRDP ("viewport scale(%d, %d), trans(%d, %d), from:%08lx\n", scale_x, scale_y,
trans_x, trans_y, a);
}
break;
case 10: // LIGHT
{
int n = (ofs / 48);
if (n < 2)
{
char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3];
rdp.lookat[n][0] = (float)(dir_x) / 127.0f;
char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3];
rdp.lookat[n][1] = (float)(dir_y) / 127.0f;
char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3];
rdp.lookat[n][2] = (float)(dir_z) / 127.0f;
rdp.use_lookat = TRUE;
if (n == 1)
{
if (!dir_x && !dir_y)
rdp.use_lookat = FALSE;
}
FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]);
return;
}
n -= 2;
BYTE col = gfx.RDRAM[(addr+0)^3];
rdp.light[n].r = (float)col / 255.0f;
rdp.light[n].nonblack = col;
col = gfx.RDRAM[(addr+1)^3];
rdp.light[n].g = (float)col / 255.0f;
rdp.light[n].nonblack += col;
col = gfx.RDRAM[(addr+2)^3];
rdp.light[n].b = (float)col / 255.0f;
rdp.light[n].nonblack += col;
rdp.light[n].a = 1.0f;
rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f;
rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f;
rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f;
// **
DWORD a = addr >> 1;
//FIXME: Why unused?
//short pos = ((short*)gfx.RDRAM)[(a+16)^1];
rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+16)^1]);
rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+17)^1]);
rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+18)^1]);
rdp.light[n].w = (float)(((short*)gfx.RDRAM)[(a+19)^1]);
rdp.light[n].nonzero = gfx.RDRAM[(addr+12)^3];
rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f;
// rdp.light[n].la = rdp.light[n].ca * 1.0f;
//#ifdef EXTREME_LOGGING
FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, w: %f, ca: %f\n",
n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].w, rdp.light[n].ca);
//#endif
FRDP ("light: n: %d, r: %f, g: %f, b: %f. dir: x: %.3f, y: %.3f, z: %.3f\n",
n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b,
rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z);
#ifdef EXTREME_LOGGING
for (int t=0; t < 24; t++)
{
FRDP ("light[%d] = 0x%04lx \n", t, ((WORD*)gfx.RDRAM)[(a+t)^1]);
}
#endif
}
break;
case 14: //Normales
{
uc8_normale_addr = segoffset(rdp.cmd1);
FRDP ("Normale - addr: %08lx\n", uc8_normale_addr);
#ifdef EXTREME_LOGGING
for (int i = 0; i < 32; i++)
{
char x = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 0)^3];
char y = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 1)^3];
FRDP("#%d x = %d, y = %d\n", i, x, y);
}
DWORD a = uc8_normale_addr >> 1;
for (i = 0; i < 32; i++)
{
FRDP ("n[%d] = 0x%04lx \n", i, ((WORD*)gfx.RDRAM)[(a+i)^1]);
}
#endif
}
break;
default:
FRDP ("uc8:movemem unknown (%d)\n", idx);
}
}
static void uc8_tri4() //by Gugaman Apr 19 2002
{
if (rdp.skip_drawing)
{
RDP("uc8:tri4. skipped\n");
return;
}
FRDP("uc8:tri4 (#%d - #%d), %d-%d-%d, %d-%d-%d, %d-%d-%d, %d-%d-%d\n",
rdp.tri_n,
rdp.tri_n+3,
((rdp.cmd0 >> 23) & 0x1F),
((rdp.cmd0 >> 18) & 0x1F),
((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3)),
((rdp.cmd0 >> 10) & 0x1F),
((rdp.cmd0 >> 5) & 0x1F),
((rdp.cmd0 >> 0) & 0x1F),
((rdp.cmd1 >> 25) & 0x1F),
((rdp.cmd1 >> 20) & 0x1F),
((rdp.cmd1 >> 15) & 0x1F),
((rdp.cmd1 >> 10) & 0x1F),
((rdp.cmd1 >> 5) & 0x1F),
((rdp.cmd1 >> 0) & 0x1F));
VERTEX *v[12] = {
&rdp.vtx[(rdp.cmd0 >> 23) & 0x1F],
&rdp.vtx[(rdp.cmd0 >> 18) & 0x1F],
&rdp.vtx[((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3))],
&rdp.vtx[(rdp.cmd0 >> 10) & 0x1F],
&rdp.vtx[(rdp.cmd0 >> 5) & 0x1F],
&rdp.vtx[(rdp.cmd0 >> 0) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 25) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 20) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 15) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 10) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 5) & 0x1F],
&rdp.vtx[(rdp.cmd1 >> 0) & 0x1F]
};
BOOL updated = 0;
if (cull_tri(v))
rdp.tri_n ++;
else
{
updated = 1;
update ();
DrawTri (v);
rdp.tri_n ++;
}
if (cull_tri(v+3))
rdp.tri_n ++;
else
{
if (!updated)
{
updated = 1;
update ();
}
DrawTri (v+3);
rdp.tri_n ++;
}
if (cull_tri(v+6))
rdp.tri_n ++;
else
{
if (!updated)
{
updated = 1;
update ();
}
DrawTri (v+6);
rdp.tri_n ++;
}
if (cull_tri(v+9))
rdp.tri_n ++;
else
{
if (!updated)
{
updated = 1;
update ();
}
DrawTri (v+9);
rdp.tri_n ++;
}
}

View File

@ -0,0 +1,21 @@
{ global:
PluginStartup;
PluginShutdown;
PluginGetVersion;
ChangeWindow;
InitiateGFX;
MoveScreen;
ProcessDList;
ProcessRDPList;
RomClosed;
RomOpen;
ShowCFB;
UpdateScreen;
ViStatusChanged;
ViWidthChanged;
ReadScreen2;
SetRenderingCallback;
FBRead;
FBWrite;
FBGetFrameBufferInfo;
local: *; };

View File

@ -0,0 +1,67 @@
/**
* Glide64 Video Plugin - winlnxdefs.h
* Copyright (C) 2002 Dave2001
*
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/
*
* This program is free software; you can redistribute it and/
* or modify it under the terms of the GNU General Public Li-
* cence as published by the Free Software Foundation; either
* version 2 of the License, or any later version.
*
* This program is distributed in the hope that it will be use-
* ful, but WITHOUT ANY WARRANTY; without even the implied war-
* ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public
* Licence along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA
*
**/
#ifndef WINLNXDEFS_H
#define WINLNXDEFS_H
#ifndef WIN32
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef int INT;
typedef long long LONGLONG;
typedef int __int32;
typedef void* HINSTANCE;
typedef int PROPSHEETHEADER;
typedef int PROPSHEETPAGE;
typedef int HWND;
#define FALSE false
#define TRUE true
#define __stdcall
#define __declspec(dllexport)
#define _cdecl
#define WINAPI
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart;
INT HighPart;
} s;
struct
{
DWORD LowPart;
INT HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;
#define HIWORD(a) ((unsigned int)(a) >> 16)
#define LOWORD(a) ((a) & 0xFFFF)
#endif
#endif // WINLNXDEFS_H

View File

@ -0,0 +1,218 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/2xsai.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public 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 "../Gfx1.3.h"
static __inline int GetResult( DWORD A, DWORD B, DWORD C, DWORD D )
{
int x = 0;
int y = 0;
int r = 0;
if (A == C) x += 1; else if (B == C) y += 1;
if (A == D) x += 1; else if (B == D) y += 1;
if (x <= 1) r += 1;
if (y <= 1) r -= 1;
return r;
}
static __inline DWORD INTERPOLATE( DWORD A, DWORD B)
{
if (A != B)
return ((A & 0xFEFEFEFE) >> 1) +
(((B & 0xFEFEFEFE) >> 1) |
(A & B & 0x01010101));
else
return A;
}
static __inline DWORD Q_INTERPOLATE( DWORD A, DWORD B, DWORD C, DWORD D)
{
DWORD x = ((A & 0xFCFCFCFC) >> 2) +
((B & 0xFCFCFCFC) >> 2) +
((C & 0xFCFCFCFC) >> 2) +
((D & 0xFCFCFCFC) >> 2);
DWORD y = (((A & 0x03030303) +
(B & 0x03030303) +
(C & 0x03030303) +
(D & 0x03030303)) >> 2) & 0x03030303;
return x | y;
}
void Super2xSaI( DWORD *srcPtr, DWORD *destPtr, DWORD width, DWORD height, DWORD pitch)
{
DWORD destWidth = width << 1;
DWORD color4, color5, color6;
DWORD color1, color2, color3;
DWORD colorA0, colorA1, colorA2, colorA3;
DWORD colorB0, colorB1, colorB2, colorB3;
DWORD colorS1, colorS2;
DWORD product1a, product1b, product2a, product2b;
int row0, row1, row2, row3;
int col0, col1, col2, col3;
WORD y, x;
for (y = 0; y < height; y++)
{
if (y > 0)
{
row0 = width;
row0 = -row0;
}
else
row0 = 0;
row1 = 0;
if (y < height - 1)
{
row2 = width;
if (y < height - 2)
row3 = width << 1;
else
row3 = width;
}
else
{
row2 = 0;
row3 = 0;
}
for (x = 0; x < width; x++)
{
//--------------------------------------- B0 B1 B2 B3
// 4 5 6 S2
// 1 2 3 S1
// A0 A1 A2 A3
if (x > 0)
col0 = -1;
else
col0 = 0;
col1 = 0;
if (x < width - 1)
{
col2 = 1;
if (x < width - 2)
col3 = 2;
else
col3 = 1;
}
else
{
col2 = 0;
col3 = 0;
}
colorB0 = *(srcPtr + col0 + row0);
colorB1 = *(srcPtr + col1 + row0);
colorB2 = *(srcPtr + col2 + row0);
colorB3 = *(srcPtr + col3 + row0);
color4 = *(srcPtr + col0 + row1);
color5 = *(srcPtr + col1 + row1);
color6 = *(srcPtr + col2 + row1);
colorS2 = *(srcPtr + col3 + row1);
color1 = *(srcPtr + col0 + row2);
color2 = *(srcPtr + col1 + row2);
color3 = *(srcPtr + col2 + row2);
colorS1 = *(srcPtr + col3 + row2);
colorA0 = *(srcPtr + col0 + row3);
colorA1 = *(srcPtr + col1 + row3);
colorA2 = *(srcPtr + col2 + row3);
colorA3 = *(srcPtr + col3 + row3);
//--------------------------------------
if (color2 == color6 && color5 != color3)
product2b = product1b = color2;
else if (color5 == color3 && color2 != color6)
product2b = product1b = color5;
else if (color5 == color3 && color2 == color6)
{
int r = 0;
r += GetResult (color6, color5, color1, colorA1);
r += GetResult (color6, color5, color4, colorB1);
r += GetResult (color6, color5, colorA2, colorS1);
r += GetResult (color6, color5, colorB2, colorS2);
if (r > 0)
product2b = product1b = color6;
else if (r < 0)
product2b = product1b = color5;
else
product2b = product1b = INTERPOLATE (color5, color6);
}
else
{
if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
product2b = Q_INTERPOLATE (color3, color3, color3, color2);
else if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
product2b = Q_INTERPOLATE (color2, color2, color2, color3);
else
product2b = INTERPOLATE (color2, color3);
if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
product1b = Q_INTERPOLATE (color6, color6, color6, color5);
else if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
product1b = Q_INTERPOLATE (color6, color5, color5, color5);
else
product1b = INTERPOLATE (color5, color6);
}
if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
product2a = INTERPOLATE (color2, color5);
else if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
product2a = INTERPOLATE(color2, color5);
else
product2a = color2;
if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
product1a = INTERPOLATE (color2, color5);
else if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
product1a = INTERPOLATE(color2, color5);
else
product1a = color5;
destPtr[0] = product1a;
destPtr[1] = product1b;
destPtr[destWidth] = product2a;
destPtr[destWidth + 1] = product2b;
srcPtr++;
destPtr += 2;
}
srcPtr += (pitch-width);
destPtr += (((pitch-width)<<1)+(pitch<<1));
}
}

View File

@ -0,0 +1,27 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/2xsai.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define uint32 unsigned long
#define uint16 unsigned short
#define uint8 unsigned char
void Super2xSaI( DWORD *srcPtr, DWORD *destPtr, DWORD width, DWORD height, DWORD pitch);

View File

@ -0,0 +1,136 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
** $Revision: 1.3.4.2 $
** $Date: 2003/05/05 06:50:41 $
*/
#ifndef __3DFX_H__
#define __3DFX_H__
#include "glidesys.h"
/*
** basic data types
*/
typedef unsigned char FxU8;
typedef signed char FxI8;
typedef unsigned short FxU16;
typedef signed short FxI16;
#if defined(__alpha__) || defined (__LP64__)
typedef signed int FxI32;
typedef unsigned int FxU32;
#else
typedef signed long FxI32;
typedef unsigned long FxU32;
#endif
typedef unsigned long AnyPtr;
typedef int FxBool;
typedef float FxFloat;
typedef double FxDouble;
/*
** color types
*/
typedef unsigned long FxColor_t;
typedef struct { float r, g, b, a; } FxColor4;
/*
** fundamental types
*/
#define FXTRUE 1
#define FXFALSE 0
/*
** helper macros
*/
#define FXUNUSED( a ) ((void)(a))
#define FXBIT( i ) ( 1L << (i) )
/*
** export macros
*/
#if defined(__MSC__) || defined(_MSC_VER)
# if defined (MSVC16)
# define FX_ENTRY
# define FX_CALL
# else
# define FX_ENTRY extern
# define FX_CALL __stdcall
# endif
#elif defined(__WATCOMC__)
# define FX_ENTRY extern
# define FX_CALL __stdcall
#elif defined (__IBMC__) || defined (__IBMCPP__)
/* IBM Visual Age C/C++: */
# define FX_ENTRY extern
# define FX_CALL __stdcall
#elif defined(__DJGPP__)
# define FX_ENTRY extern
# define FX_CALL
#elif defined(__MINGW32__)
# define FX_ENTRY extern
# define FX_CALL __stdcall
#elif defined(__unix__)
# define FX_ENTRY extern
# define FX_CALL
#elif defined(__MWERKS__)
# if macintosh
# define FX_ENTRY extern
# define FX_CALL
# else /* !macintosh */
# error "Unknown MetroWerks target platform"
# endif /* !macintosh */
#elif defined(__APPLE__)
# define FX_ENTRY extern
# define FX_CALL
#else
# warning define FX_ENTRY & FX_CALL for your compiler
# define FX_ENTRY extern
# define FX_CALL
#endif
/*
** x86 compiler specific stuff
*/
#if defined(__BORLANDC_)
# define REALMODE
# define REGW( a, b ) ((a).x.b)
# define REGB( a, b ) ((a).h.b)
# define INT86( a, b, c ) int86(a,b,c)
# define INT86X( a, b, c, d ) int86x(a,b,c,d)
# define RM_SEG( a ) FP_SEG( a )
# define RM_OFF( a ) FP_OFF( a )
#elif defined(__WATCOMC__)
# undef FP_SEG
# undef FP_OFF
# define REGW( a, b ) ((a).w.b)
# define REGB( a, b ) ((a).h.b)
# define INT86( a, b, c ) int386(a,b,c)
# define INT86X( a, b, c, d ) int386x(a,b,c,d)
# define RM_SEG( a ) ( ( ( ( FxU32 ) (a) ) & 0x000F0000 ) >> 4 )
# define RM_OFF( a ) ( ( FxU16 ) (a) )
#endif
#endif /* !__3DFX_H__ */

View File

@ -0,0 +1,255 @@
3DFX GLIDE Source Code General Public License
1. PREAMBLE
This license is for software that provides a 3D graphics application
program interface (API).The license is intended to offer terms similar
to some standard General Public Licenses designed to foster open
standards and unrestricted accessibility to source code. Some of these
licenses require that, as a condition of the license of the software,
any derivative works (that is, new software which is a work containing
the original program or a portion of it) must be available for general
use, without restriction other than for a minor transfer fee, and that
the source code for such derivative works must likewise be made
available. The only restriction is that such derivative works must be
subject to the same General Public License terms as the original work.
This 3dfx GLIDE Source Code General Public License differs from the
standard licenses of this type in that it does not require the entire
derivative work to be made available under the terms of this license
nor is the recipient required to make available the source code for
the entire derivative work. Rather, the license is limited to only the
identifiable portion of the derivative work that is derived from the
licensed software. The precise terms and conditions for copying,
distribution and modification follow.
2. DEFINITIONS
2.1 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 3dfx GLIDE Source Code General
Public License.
2.2 The term "Program" as used in this Agreement refers to 3DFX's
GLIDE source code and object code and any Derivative Work.
2.3 "Derivative Work" means, for the purpose of the License, that
portion of any work that contains the Program or the identifiable
portion of a work that is derived from the Program, either verbatim or
with modifications and/or translated into another language, and that
performs 3D graphics API operations. It does not include any other
portions of a work.
2.4 "Modifications of the Program" means any work, which includes a
Derivative Work, and includes the whole of such work.
2.5 "License" means this 3dfx GLIDE Source Code General Public License.
2.6 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, any
associated interface definition files, and the scripts used to control
compilation and installation of the executable work.
2.7 "3dfx" means 3dfx Interactive, Inc.
3. LICENSED ACTIVITIES
3.1 COPYING - You may copy and distribute verbatim copies of the
Program's Source Code as you receive it, in any medium, subject to the
provision of section 3.3 and provided also that:
(a) you conspicuously and appropriately publish on each copy
an appropriate copyright notice (3dfx Interactive, Inc. 1999), a notice
that recipients who wish to copy, distribute or modify the Program can
only do so subject to this License, and a disclaimer of warranty as
set forth in section 5;
(b) keep intact all the notices that refer to this License and
to the absence of any warranty; and
(c) do not make any use of the GLIDE trademark without the prior
written permission of 3dfx, and
(d) give all recipients of the Program a copy of this License
along with the Program or instructions on how to easily receive a copy
of this License.
3.2 MODIFICATION OF THE PROGRAM/DERIVATIVE WORKS - You may modify your
copy or copies of the Program or any portion of it, and copy and
distribute such modifications subject to the provisions of section 3.3
and provided that you also meet all of the following conditions:
(a) you conspicuously and appropriately publish on each copy
of a Derivative Work an appropriate copyright notice, a notice that
recipients who wish to copy, distribute or modify the Derivative Work
can only do so subject to this License, and a disclaimer of warranty
as set forth in section 5;
(b) keep intact all the notices that refer to this License and
to the absence of any warranty; and
(c) give all recipients of the Derivative Work a copy of this
License along with the Derivative Work or instructions on how to easily
receive a copy of this License.
(d) You must cause the modified files of the Derivative Work
to carry prominent notices stating that you changed the files and the
date of any change.
(e) You must cause any Derivative Work that you distribute or
publish to be licensed at no charge to all third parties under the
terms of this License.
(f) You do not make any use of the GLIDE trademark without the
prior written permission of 3dfx.
(g) If the Derivative Work normally reads commands
interactively when run, you must cause it, when started running for
such interactive use, to print or display an announcement as follows:
"COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED THIS
SOFTWARE IS FREE AND PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED. THERE IS NO RIGHT TO USE THE GLIDE
TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX INTERACTIVE,
INC. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A FULL TEXT OF THE
DISTRIBUTION AND NON-WARRANTY PROVISIONS (REQUEST COPY FROM
INFO@3DFX.COM)."
(h) The requirements of this section 3.2 do not apply to the
modified work as a whole but only to the Derivative Work. It is not
the intent of this License 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 Works.
3.3 DISTRIBUTION
(a) All copies of the Program or Derivative Works which are
distributed must include in the file headers the following language
verbatim:
"THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED
ONLY PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO
RIGHT TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF
3DFX INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM
THE DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC (info@3dfx.com).
THIS PROGRAM. IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
FULL TEXT OF THE NON-WARRANTY PROVISIONS.
USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS
IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
THE UNITED STATES.
COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED"
(b) You may distribute the Program or a Derivative Work in
object code or executable form under the terms of Sections 3.1 and 3.2
provided that you also do one of the following:
(1) Accompany it with the complete corresponding
machine-readable source code, which must be distributed under the
terms of Sections 3.1 and 3.2; or,
(2) 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 3.1 and 3.2 on a medium
customarily used for software interchange; or,
(3) 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 3.3(b)(2) above.)
(c) 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 code.
(d) If distribution of executable code 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.
(e) Each time you redistribute the Program or any Derivative
Work, the recipient automatically receives a license from 3dfx and
successor licensors to copy, distribute or modify the Program and
Derivative Works subject to the terms and conditions of the License.
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.
(f) You may not make any use of the GLIDE trademark without
the prior written permission of 3dfx.
(g) You may not copy, modify, sublicense, or distribute the
Program or any Derivative Works except as expressly provided under
this License. Any attempt otherwise to copy, modify, sublicense or
distribute the Program or any Derivative Works 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.
4. MISCELLANEOUS
4.1 Acceptance of this License is voluntary. By using, modifying or
distributing the Program or any Derivative Work, 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. Nothing else grants you permission to modify or distribute the
Program or Derivative Works and doing so without acceptance of this
License is in violation of the U.S. and international copyright laws.
4.2 If the distribution and/or use of the Program or Derivative Works
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.
4.3 This License is to be construed according to the laws of the
State of California and you consent to personal jurisdiction in the
State of California in the event it is necessary to enforce the
provisions of this License.
5. NO WARRANTIES
5.1 TO THE EXTENT PERMITTED BY APPLICABLE LAW, THERE IS NO WARRANTY
FOR THE PROGRAM. OR DERIVATIVE WORKS THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM AND ANY DERIVATIVE WORKS"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 AND ANY DERIVATIVE WORK IS WITH YOU.
SHOULD THE PROGRAM OR ANY DERIVATIVE WORK PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
5.2 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL 3DFX
INTERACTIVE, INC., OR ANY OTHER COPYRIGHT HOLDER, OR ANY OTHER PARTY
WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM OR DERIVATIVE WORKS 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 OR DERIVATIVE WORKS (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 OR
DERIVATIVE WORKS TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/config.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public 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 <SDL_opengl.h>
#include "glide.h"
#include "main.h"
#include "../winlnxdefs.h"
typedef struct _wrapper_config
{
int res;
int filter;
int disable_glsl;
int disable_dithered_alpha;
int FBO;
int disable_auxbuf;
} wrapper_config;
FX_ENTRY void FX_CALL grConfigWrapperExt(HINSTANCE
instance, HWND hwnd)
{
}
#include "../rdp.h"
FX_ENTRY GrScreenResolution_t FX_CALL grWrapperFullScreenResolutionExt(void)
{
return settings.full_res;
}
int getFilter()
{
return settings.tex_filter;
}
int getDisableDitheredAlpha()
{
return settings.noditheredalpha;
}
int getEnableFBO()
{
return settings.FBO;
}
int getDisableAuxbuf()
{
return settings.disable_auxbuf;
}
int getDisableGLSL()
{
return settings.noglsl;
}

View File

@ -0,0 +1,368 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/filter.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdlib.h>
#include <string.h>
#include "../winlnxdefs.h"
#include "main.h"
#include "2xsai.h"
// this filter is crap, it's just some stuffs i tried to see what they're doing
// it's blurring texture edges which is good for some textures, bad for some others.
unsigned char *blur_edges(unsigned char *source, int width, int height, int *width2, int *height2)
{
unsigned char *result, *temp, *temp2;
char mx[3*3] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
char my[3*3] = {-1, -2, -1, 0, 0, 0, 1, 2 ,1};
int i,j;
*width2 = width*2;
*height2 = height*2;
result = (unsigned char*)malloc(width*2*height*2*4);
temp = (unsigned char*)malloc(width*2*height*2*4);
temp2 = (unsigned char*)malloc(width*2*height*2*4);
// size * 2
for (j=0; j<height; j++)
{
for (i=0; i<width; i++)
{
temp[j*2*width*2*4 + i*2*4 + 0] = source[j*width*4 + i*4 + 0];
temp[j*2*width*2*4 + i*2*4 + 1] = source[j*width*4 + i*4 + 1];
temp[j*2*width*2*4 + i*2*4 + 2] = source[j*width*4 + i*4 + 2];
temp[j*2*width*2*4 + i*2*4 + 3] = source[j*width*4 + i*4 + 3];
if (i < (width-1))
{
temp[j*2*width*2*4 + (i*2+1)*4 + 0] =
((int)source[j*width*4 + i*4 + 0] + (int)source[j*width*4 + (i+1)*4 + 0])>>1;
temp[j*2*width*2*4 + (i*2+1)*4 + 1] =
((int)source[j*width*4 + i*4 + 1] + (int)source[j*width*4 + (i+1)*4 + 1])>>1;
temp[j*2*width*2*4 + (i*2+1)*4 + 2] =
((int)source[j*width*4 + i*4 + 2] + (int)source[j*width*4 + (i+1)*4 + 2])>>1;
temp[j*2*width*2*4 + (i*2+1)*4 + 3] =
((int)source[j*width*4 + i*4 + 3] + (int)source[j*width*4 + (i+1)*4 + 3])>>1;
}
else
{
temp[j*2*width*2*4 + (i*2+1)*4 + 0] = temp[j*2*width*2*4 + i*2*4 + 0];
temp[j*2*width*2*4 + (i*2+1)*4 + 1] = temp[j*2*width*2*4 + i*2*4 + 1];
temp[j*2*width*2*4 + (i*2+1)*4 + 2] = temp[j*2*width*2*4 + i*2*4 + 2];
temp[j*2*width*2*4 + (i*2+1)*4 + 3] = temp[j*2*width*2*4 + i*2*4 + 3];
}
if (j < (height-1))
{
temp[(j*2+1)*width*2*4 + i*2*4 + 0] =
((int)source[j*width*4 + i*4 + 0] + (int)source[(j+1)*width*4 + i*4 + 0])>>1;
temp[(j*2+1)*width*2*4 + i*2*4 + 1] =
((int)source[j*width*4 + i*4 + 1] + (int)source[(j+1)*width*4 + i*4 + 1])>>1;
temp[(j*2+1)*width*2*4 + i*2*4 + 2] =
((int)source[j*width*4 + i*4 + 2] + (int)source[(j+1)*width*4 + i*4 + 2])>>1;
temp[(j*2+1)*width*2*4 + i*2*4 + 3] =
((int)source[j*width*4 + i*4 + 3] + (int)source[(j+1)*width*4 + i*4 + 3])>>1;
if (i < (width-1))
{
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 0] =
((int)source[j*width*4 + i*4 + 0] + (int)source[(j+1)*width*4 + (i+1)*4 + 0])>>1;
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 1] =
((int)source[j*width*4 + i*4 + 1] + (int)source[(j+1)*width*4 + (i+1)*4 + 1])>>1;
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 2] =
((int)source[j*width*4 + i*4 + 2] + (int)source[(j+1)*width*4 + (i+1)*4 + 2])>>1;
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 3] =
((int)source[j*width*4 + i*4 + 3] + (int)source[(j+1)*width*4 + (i+1)*4 + 3])>>1;
}
else
{
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 0] = temp[j*2*width*2*4 + i*2*4 + 0];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 1] = temp[j*2*width*2*4 + i*2*4 + 1];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 2] = temp[j*2*width*2*4 + i*2*4 + 2];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 3] = temp[j*2*width*2*4 + i*2*4 + 3];
}
}
else
{
temp[(j*2+1)*width*2*4 + i*2*4 + 0] = temp[j*2*width*2*4 + i*2*4 + 0];
temp[(j*2+1)*width*2*4 + i*2*4 + 1] = temp[j*2*width*2*4 + i*2*4 + 1];
temp[(j*2+1)*width*2*4 + i*2*4 + 2] = temp[j*2*width*2*4 + i*2*4 + 2];
temp[(j*2+1)*width*2*4 + i*2*4 + 3] = temp[j*2*width*2*4 + i*2*4 + 3];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 0] = temp[j*2*width*2*4 + i*2*4 + 0];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 1] = temp[j*2*width*2*4 + i*2*4 + 1];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 2] = temp[j*2*width*2*4 + i*2*4 + 2];
temp[(j*2+1)*width*2*4 + (i*2+1)*4 + 3] = temp[j*2*width*2*4 + i*2*4 + 3];
}
}
}
// gradient
for (j=0; j<height*2; j++)
{
for (i=0; i<width*2; i++)
{
int gx_r=0, gy_r=0, gx_g=0, gy_g=0, gx_b=0, gy_b=0, gx_a=0, gy_a=0, k, l;
if (i==0 || j==0 || j==height*2-1 || i==width*2-1)
{
gx_r = temp[j*width*2*4 + i*4 + 0];
gy_r = temp[j*width*2*4 + i*4 + 0];
gx_g = temp[j*width*2*4 + i*4 + 1];
gy_g = temp[j*width*2*4 + i*4 + 1];
gx_b = temp[j*width*2*4 + i*4 + 2];
gy_b = temp[j*width*2*4 + i*4 + 2];
gx_a = temp[j*width*2*4 + i*4 + 3];
gy_a = temp[j*width*2*4 + i*4 + 3];
}
else
{
for (k=0; k<3; k++)
{
for (l=0; l<3; l++)
{
gx_r += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 0] * mx[k*3+l];
gy_r += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 0] * my[k*3+l];
gx_g += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 1] * mx[k*3+l];
gy_g += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 1] * my[k*3+l];
gx_b += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 2] * mx[k*3+l];
gy_b += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 2] * my[k*3+l];
gx_a += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 3] * mx[k*3+l];
gy_a += (int)temp[(j-1+k)*width*2*4 + (i-1+l)*4 + 3] * my[k*3+l];
}
}
}
gx_r = gx_r < 0 ? -gx_r : gx_r;
gy_r = gy_r < 0 ? -gy_r : gy_r;
gx_g = gx_g < 0 ? -gx_g : gx_g;
gy_g = gy_g < 0 ? -gy_g : gy_g;
gx_b = gx_b < 0 ? -gx_b : gx_b;
gy_b = gy_b < 0 ? -gy_b : gy_b;
gx_a = gx_a < 0 ? -gx_a : gx_a;
gy_a = gy_a < 0 ? -gy_a : gy_a;
temp2[j*width*2*4 + i*4 + 0] = gx_r + gy_r;
temp2[j*width*2*4 + i*4 + 1] = gx_g + gy_g;
temp2[j*width*2*4 + i*4 + 2] = gx_b + gy_b;
temp2[j*width*2*4 + i*4 + 3] = gx_a + gy_a;
}
}
// bluring
for (j=0; j<height*2; j++)
{
for (i=0; i<width*2; i++)
{
int mini = i != 0 ? i-1 : 0;
int maxi = i != width*2-1 ? i+1 : width*2-1;
int minj = j != 0 ? j-1 : 0;
int maxj = j != height*2-1 ? j+1 : height*2-1;
int mini2 = mini != 0 ? mini-1 : 0;
int maxi2 = maxi != width*2-1 ? maxi+1 : width*2-1;
int minj2 = minj != 0 ? minj-1 : 0;
int maxj2 = maxj != height*2-1 ? maxj+1 : height*2-1;
int total;
// r
total = 0;
total += (int)temp[j*width*2*4 + i*4 + 0];
total += (int)temp[minj*width*2*4 + mini*4 + 0];
total += (int)temp[minj*width*2*4 + i*4 + 0];
total += (int)temp[minj*width*2*4 + maxi*4 + 0];
total += (int)temp[j*width*2*4 + maxi*4 + 0];
total += (int)temp[maxj*width*2*4 + maxi*4 + 0];
total += (int)temp[maxj*width*2*4 + i*4 + 0];
total += (int)temp[maxj*width*2*4 + mini*4 + 0];
total += (int)temp[j*width*2*4 + mini*4 + 0];
total += (int)temp[minj2*width*2*4 + mini2*4 + 0];
total += (int)temp[minj2*width*2*4 + mini*4 + 0];
total += (int)temp[minj2*width*2*4 + i*4 + 0];
total += (int)temp[minj2*width*2*4 + maxi*4 + 0];
total += (int)temp[minj2*width*2*4 + maxi2*4 + 0];
total += (int)temp[minj*width*2*4 + maxi2*4 + 0];
total += (int)temp[j*width*2*4 + maxi2*4 + 0];
total += (int)temp[maxj*width*2*4 + maxi2*4 + 0];
total += (int)temp[maxj2*width*2*4 + maxi2*4 + 0];
total += (int)temp[maxj2*width*2*4 + maxi*4 + 0];
total += (int)temp[maxj2*width*2*4 + i*4 + 0];
total += (int)temp[maxj2*width*2*4 + mini*4 + 0];
total += (int)temp[maxj2*width*2*4 + mini2*4 + 0];
total += (int)temp[maxj*width*2*4 + mini2*4 + 0];
total += (int)temp[j*width*2*4 + mini2*4 + 0];
total += (int)temp[minj*width*2*4 + mini2*4 + 0];
result[j*width*2*4 + i*4 + 0] =
((total / 25) * (int)temp2[j*width*2*4 + i*4 + 0] +
((int)temp[j*width*2*4 + i*4 + 0]) * (255-(int)temp2[j*width*2*4 + i*4 + 0]))/255;
// g
total = 0;
total += (int)temp[j*width*2*4 + i*4 + 1];
total += (int)temp[minj*width*2*4 + mini*4 + 1];
total += (int)temp[minj*width*2*4 + i*4 + 1];
total += (int)temp[minj*width*2*4 + maxi*4 + 1];
total += (int)temp[j*width*2*4 + maxi*4 + 1];
total += (int)temp[maxj*width*2*4 + maxi*4 + 1];
total += (int)temp[maxj*width*2*4 + i*4 + 1];
total += (int)temp[maxj*width*2*4 + mini*4 + 1];
total += (int)temp[j*width*2*4 + mini*4 + 1];
total += (int)temp[minj2*width*2*4 + mini2*4 + 1];
total += (int)temp[minj2*width*2*4 + mini*4 + 1];
total += (int)temp[minj2*width*2*4 + i*4 + 1];
total += (int)temp[minj2*width*2*4 + maxi*4 + 1];
total += (int)temp[minj2*width*2*4 + maxi2*4 + 1];
total += (int)temp[minj*width*2*4 + maxi2*4 + 1];
total += (int)temp[j*width*2*4 + maxi2*4 + 1];
total += (int)temp[maxj*width*2*4 + maxi2*4 + 1];
total += (int)temp[maxj2*width*2*4 + maxi2*4 + 1];
total += (int)temp[maxj2*width*2*4 + maxi*4 + 1];
total += (int)temp[maxj2*width*2*4 + i*4 + 1];
total += (int)temp[maxj2*width*2*4 + mini*4 + 1];
total += (int)temp[maxj2*width*2*4 + mini2*4 + 1];
total += (int)temp[maxj*width*2*4 + mini2*4 + 1];
total += (int)temp[j*width*2*4 + mini2*4 + 1];
total += (int)temp[minj*width*2*4 + mini2*4 + 1];
result[j*width*2*4 + i*4 + 1] =
((total / 25) * (int)temp2[j*width*2*4 + i*4 + 1] +
((int)temp[j*width*2*4 + i*4 + 1]) * (255-(int)temp2[j*width*2*4 + i*4 + 1]))/255;
// b
total = 0;
total += (int)temp[j*width*2*4 + i*4 + 2];
total += (int)temp[minj*width*2*4 + mini*4 + 2];
total += (int)temp[minj*width*2*4 + i*4 + 2];
total += (int)temp[minj*width*2*4 + maxi*4 + 2];
total += (int)temp[j*width*2*4 + maxi*4 + 2];
total += (int)temp[maxj*width*2*4 + maxi*4 + 2];
total += (int)temp[maxj*width*2*4 + i*4 + 2];
total += (int)temp[maxj*width*2*4 + mini*4 + 2];
total += (int)temp[j*width*2*4 + mini*4 + 2];
total += (int)temp[minj2*width*2*4 + mini2*4 + 2];
total += (int)temp[minj2*width*2*4 + mini*4 + 2];
total += (int)temp[minj2*width*2*4 + i*4 + 2];
total += (int)temp[minj2*width*2*4 + maxi*4 + 2];
total += (int)temp[minj2*width*2*4 + maxi2*4 + 2];
total += (int)temp[minj*width*2*4 + maxi2*4 + 2];
total += (int)temp[j*width*2*4 + maxi2*4 + 2];
total += (int)temp[maxj*width*2*4 + maxi2*4 + 2];
total += (int)temp[maxj2*width*2*4 + maxi2*4 + 2];
total += (int)temp[maxj2*width*2*4 + maxi*4 + 2];
total += (int)temp[maxj2*width*2*4 + i*4 + 2];
total += (int)temp[maxj2*width*2*4 + mini*4 + 2];
total += (int)temp[maxj2*width*2*4 + mini2*4 + 2];
total += (int)temp[maxj*width*2*4 + mini2*4 + 2];
total += (int)temp[j*width*2*4 + mini2*4 + 2];
total += (int)temp[minj*width*2*4 + mini2*4 + 2];
result[j*width*2*4 + i*4 + 2] =
((total / 25) * (int)temp2[j*width*2*4 + i*4 + 2] +
((int)temp[j*width*2*4 + i*4 + 2]) * (255-(int)temp2[j*width*2*4 + i*4 + 2]))/255;
// a
total = 0;
total += (int)temp[j*width*2*4 + i*4 + 3];
total += (int)temp[minj*width*2*4 + mini*4 + 3];
total += (int)temp[minj*width*2*4 + i*4 + 3];
total += (int)temp[minj*width*2*4 + maxi*4 + 3];
total += (int)temp[j*width*2*4 + maxi*4 + 3];
total += (int)temp[maxj*width*2*4 + maxi*4 + 3];
total += (int)temp[maxj*width*2*4 + i*4 + 3];
total += (int)temp[maxj*width*2*4 + mini*4 + 3];
total += (int)temp[j*width*2*4 + mini*4 + 3];
total += (int)temp[minj2*width*2*4 + mini2*4 + 3];
total += (int)temp[minj2*width*2*4 + mini*4 + 3];
total += (int)temp[minj2*width*2*4 + i*4 + 3];
total += (int)temp[minj2*width*2*4 + maxi*4 + 3];
total += (int)temp[minj2*width*2*4 + maxi2*4 + 3];
total += (int)temp[minj*width*2*4 + maxi2*4 + 3];
total += (int)temp[j*width*2*4 + maxi2*4 + 3];
total += (int)temp[maxj*width*2*4 + maxi2*4 + 3];
total += (int)temp[maxj2*width*2*4 + maxi2*4 + 3];
total += (int)temp[maxj2*width*2*4 + maxi*4 + 3];
total += (int)temp[maxj2*width*2*4 + i*4 + 3];
total += (int)temp[maxj2*width*2*4 + mini*4 + 3];
total += (int)temp[maxj2*width*2*4 + mini2*4 + 3];
total += (int)temp[maxj*width*2*4 + mini2*4 + 3];
total += (int)temp[j*width*2*4 + mini2*4 + 3];
total += (int)temp[minj*width*2*4 + mini2*4 + 3];
result[j*width*2*4 + i*4 + 3] =
((total / 25) * (int)temp2[j*width*2*4 + i*4 + 3] +
((int)temp[j*width*2*4 + i*4 + 3]) * (255-(int)temp2[j*width*2*4 + i*4 + 3]))/255;
}
}
free(temp2);
free(temp);
return result;
}
void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL );
void hq4x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL );
unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2)
{
switch(getFilter())
{
case 1:
return blur_edges(source, width, height, width2, height2);
break;
case 2:
{
unsigned char *result;
result = (unsigned char*)malloc(width*2*height*2*4);
*width2 = width*2;
*height2 = height*2;
Super2xSaI((DWORD*)source, (DWORD*)result, width, height, width);
return result;
}
break;
case 3:
{
unsigned char *result;
result = (unsigned char*)malloc(width*2*height*2*4);
*width2 = width*2;
*height2 = height*2;
hq2x_32(source, result, width, height, width*2*4);
return result;
}
break;
case 4:
{
unsigned char *result;
result = (unsigned char*)malloc(width*4*height*4*4);
*width2 = width*4;
*height2 = height*4;
hq4x_32(source, result, width, height, width*4*4);
return result;
}
break;
}
return NULL;
}

View File

@ -0,0 +1,188 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
/*
** H3EXT.H
**
** The following #defines are relevant when using Glide:
**
** One of the following "platform constants" must be defined during
** compilation:
**
** __DOS__ Defined for 32-bit DOS applications
** __WIN32__ Defined for 32-bit Windows applications
** __sparc__ Defined for Sun Solaris/SunOS
** __linux__ Defined for Linux applications
** __FreeBSD__ Defined for FreeBSD applications
** __NetBSD__ Defined for NetBSD applications
** __OpenBSD__ Defined for OpenBSD applications
** __IRIX__ Defined for SGI Irix applications
**
*/
#ifndef __H3EXT_H__
#define __H3EXT_H__
#include <3dfx.h>
#include <glidesys.h>
#include <sst1vid.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
** -----------------------------------------------------------------------
** TYPE DEFINITIONS
** -----------------------------------------------------------------------
*/
/*
** -----------------------------------------------------------------------
** CONSTANTS AND TYPES
** -----------------------------------------------------------------------
*/
/*
* gregk 5/3/99
* Constants defined for SSTH3_ALPHADITHERMODE registry key
*/
#define OPTIMAL 1
#define SHARPER 2
#define SMOOTHER 3
/* tbext */
#define GR_BUFFER_TEXTUREBUFFER_EXT 0x6
#define GR_BUFFER_TEXTUREAUXBUFFER_EXT 0x7
typedef FxU32 GrPixelFormat_t;
#define GR_PIXFMT_I_8 0x0001
#define GR_PIXFMT_AI_88 0x0002
#define GR_PIXFMT_RGB_565 0x0003
#define GR_PIXFMT_ARGB_1555 0x0004
#define GR_PIXFMT_ARGB_8888 0x0005
#define GR_PIXFMT_AA_2_RGB_565 0x0006
#define GR_PIXFMT_AA_2_ARGB_1555 0x0007
#define GR_PIXFMT_AA_2_ARGB_8888 0x0008
#define GR_PIXFMT_AA_4_RGB_565 0x0009
#define GR_PIXFMT_AA_4_ARGB_1555 0x000a
#define GR_PIXFMT_AA_4_ARGB_8888 0x000b
#define GR_PIXFMT_AA_8_RGB_565 0x000c /* 8xaa */
#define GR_PIXFMT_AA_8_ARGB_1555 0x000d
#define GR_PIXFMT_AA_8_ARGB_8888 0x000e
#define GR_LFBWRITEMODE_Z32 0x0008
typedef FxU32 GrAAMode_t;
#define GR_AA_NONE 0x0000
#define GR_AA_4SAMPLES 0x0001
typedef FxU8 GrStencil_t;
typedef FxU32 GrStencilOp_t;
#define GR_STENCILOP_KEEP 0x00 /* keep current value */
#define GR_STENCILOP_ZERO 0x01 /* set to zero */
#define GR_STENCILOP_REPLACE 0x02 /* replace with reference value */
#define GR_STENCILOP_INCR_CLAMP 0x03 /* increment - clamp */
#define GR_STENCILOP_DECR_CLAMP 0x04 /* decrement - clamp */
#define GR_STENCILOP_INVERT 0x05 /* bitwise inversion */
#define GR_STENCILOP_INCR_WRAP 0x06 /* increment - wrap */
#define GR_STENCILOP_DECR_WRAP 0x07 /* decrement - wrap */
#define GR_TEXTURE_UMA_EXT 0x06
#define GR_STENCIL_MODE_EXT 0x07
#define GR_OPENGL_MODE_EXT 0x08
typedef FxU32 GrCCUColor_t;
typedef FxU32 GrACUColor_t;
typedef FxU32 GrTCCUColor_t;
typedef FxU32 GrTACUColor_t;
#define GR_CMBX_ZERO 0x00
#define GR_CMBX_TEXTURE_ALPHA 0x01
#define GR_CMBX_ALOCAL 0x02
#define GR_CMBX_AOTHER 0x03
#define GR_CMBX_B 0x04
#define GR_CMBX_CONSTANT_ALPHA 0x05
#define GR_CMBX_CONSTANT_COLOR 0x06
#define GR_CMBX_DETAIL_FACTOR 0x07
#define GR_CMBX_ITALPHA 0x08
#define GR_CMBX_ITRGB 0x09
#define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a
#define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b
#define GR_CMBX_LOD_FRAC 0x0c
#define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d
#define GR_CMBX_OTHER_TEXTURE_RGB 0x0e
#define GR_CMBX_TEXTURE_RGB 0x0f
#define GR_CMBX_TMU_CALPHA 0x10
#define GR_CMBX_TMU_CCOLOR 0x11
typedef FxU32 GrCombineMode_t;
#define GR_FUNC_MODE_ZERO 0x00
#define GR_FUNC_MODE_X 0x01
#define GR_FUNC_MODE_ONE_MINUS_X 0x02
#define GR_FUNC_MODE_NEGATIVE_X 0x03
#define GR_FUNC_MODE_X_MINUS_HALF 0x04
typedef FxU32 GrAlphaBlendOp_t;
#define GR_BLEND_OP_ADD 0x00
#define GR_BLEND_OP_SUB 0x01
#define GR_BLEND_OP_REVSUB 0x02
#define GR_BLEND_SAME_COLOR_EXT 0x08
#define GR_BLEND_ONE_MINUS_SAME_COLOR_EXT 0x09
/* Napalm extensions to GrTextureFormat_t */
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
#define GR_TEXFMT_ARGB_8888 0x12
#define GR_TEXFMT_YUYV_422 0x13
#define GR_TEXFMT_UYVY_422 0x14
#define GR_TEXFMT_AYUV_444 0x15
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
#define GR_TEXFMT_ARGB_CMP_DXT2 0x17
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
#define GR_TEXFMT_ARGB_CMP_DXT4 0x19
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
#define GR_TEXTFMT_RGB_888 0xFF
/* Napalm extensions to GrLOD_t */
#define GR_LOD_LOG2_2048 0xb
#define GR_LOD_LOG2_1024 0xa
#define GR_LOD_LOG2_512 0x9
/* Napalm extensions to GrTexBaseRange_t */
#define GR_TEXBASE_2048 0x7
#define GR_TEXBASE_1024 0x6
#define GR_TEXBASE_512 0x5
#define GR_TEXBASE_256_TO_1 0x4
#ifdef __cplusplus
}
#endif
#include <glideutl.h>
#endif /* __H3EXT_H__ */

View File

@ -0,0 +1,859 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/geometry.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public 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 <stdio.h>
#include "glide.h"
#include "main.h"
#define Z_MAX (65536.0f)
//#define Z_MAX 1000.0f
static int xy_off;
static int xy_en;
static int z_en;
static int z_off;
static int q_off;
static int q_en;
static int pargb_off;
static int pargb_en;
static int st0_off;
static int st0_en;
static int st1_off;
static int st1_en;
static int fog_ext_off;
static int fog_ext_en;
int w_buffer_mode;
int inverted_culling;
int culling_mode;
//static float depth_bias;
inline float ZCALC(const float & z, const float & q) {
//float res = z_en ? ((z) / Z_MAX) / (q-(float)depth_bias*q*q*zscale*2/128.0f) : 1.0f;
//float res = z_en ? ((z) / Z_MAX) / (q-(float)depth_bias*zscale*9/255000000.0f) : 1.0f;
float res = z_en ? ((z) / Z_MAX) / (q) : 1.0f;
return res;
}
#define zclamp (1.0f-1.0f/zscale)
static inline void zclamp_glVertex4f(float a, float b, float c, float d)
{
if (c<zclamp) c = zclamp;
glVertex4f(a,b,c,d);
}
#define glVertex4f(a,b,c,d) zclamp_glVertex4f(a,b,c,d)
static inline float ytex(int tmu, float y) {
if (invtex[tmu])
return invtex[tmu] - y;
else
return y;
}
void init_geometry()
{
xy_en = q_en = pargb_en = st0_en = st1_en = z_en = 0;
w_buffer_mode = 0;
inverted_culling = 0;
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
}
FX_ENTRY void FX_CALL
grCoordinateSpace( GrCoordinateSpaceMode_t mode )
{
WriteLog(M64MSG_VERBOSE, "grCoordinateSpace(%d)\r\n", mode);
switch(mode)
{
case GR_WINDOW_COORDS:
break;
default:
display_warning("unknwown coordinate space : %x", mode);
}
}
FX_ENTRY void FX_CALL
grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode)
{
WriteLog(M64MSG_VERBOSE, "grVertexLayout(%d,%d,%d)\r\n", param, offset, mode);
switch(param)
{
case GR_PARAM_XY:
xy_en = mode;
xy_off = offset;
break;
case GR_PARAM_Z:
z_en = mode;
z_off = offset;
break;
case GR_PARAM_Q:
q_en = mode;
q_off = offset;
break;
case GR_PARAM_FOG_EXT:
fog_ext_en = mode;
fog_ext_off = offset;
break;
case GR_PARAM_PARGB:
pargb_en = mode;
pargb_off = offset;
break;
case GR_PARAM_ST0:
st0_en = mode;
st0_off = offset;
break;
case GR_PARAM_ST1:
st1_en = mode;
st1_off = offset;
break;
default:
display_warning("unknown grVertexLayout parameter : %x", param);
}
}
FX_ENTRY void FX_CALL
grCullMode( GrCullMode_t mode )
{
WriteLog(M64MSG_VERBOSE, "grCullMode(%d)\r\n", mode);
static int oldmode = -1, oldinv = -1;
culling_mode = mode;
if (inverted_culling == oldinv && oldmode == mode)
return;
oldmode = mode;
oldinv = inverted_culling;
switch(mode)
{
case GR_CULL_DISABLE:
glDisable(GL_CULL_FACE);
break;
case GR_CULL_NEGATIVE:
if (!inverted_culling)
glCullFace(GL_FRONT);
else
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
break;
case GR_CULL_POSITIVE:
if (!inverted_culling)
glCullFace(GL_BACK);
else
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
break;
default:
display_warning("unknown cull mode : %x", mode);
}
}
// Depth buffer
FX_ENTRY void FX_CALL
grDepthBufferMode( GrDepthBufferMode_t mode )
{
WriteLog(M64MSG_VERBOSE, "grDepthBufferMode(%d)\r\n", mode);
switch(mode)
{
case GR_DEPTHBUFFER_DISABLE:
glDisable(GL_DEPTH_TEST);
w_buffer_mode = 0;
return;
case GR_DEPTHBUFFER_WBUFFER:
case GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS:
glEnable(GL_DEPTH_TEST);
w_buffer_mode = 1;
break;
case GR_DEPTHBUFFER_ZBUFFER:
case GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS:
glEnable(GL_DEPTH_TEST);
w_buffer_mode = 0;
break;
default:
display_warning("unknown depth buffer mode : %x", mode);
}
}
FX_ENTRY void FX_CALL
grDepthBufferFunction( GrCmpFnc_t function )
{
WriteLog(M64MSG_VERBOSE, "grDepthBufferFunction(%d)\r\n", function);
switch(function)
{
case GR_CMP_GEQUAL:
if (w_buffer_mode)
glDepthFunc(GL_LEQUAL);
else
glDepthFunc(GL_GEQUAL);
break;
case GR_CMP_LEQUAL:
if (w_buffer_mode)
glDepthFunc(GL_GEQUAL);
else
glDepthFunc(GL_LEQUAL);
break;
case GR_CMP_LESS:
if (w_buffer_mode)
glDepthFunc(GL_GREATER);
else
glDepthFunc(GL_LESS);
break;
case GR_CMP_ALWAYS:
glDepthFunc(GL_ALWAYS);
break;
case GR_CMP_EQUAL:
// if (w_buffer_mode)
// glDepthFunc(GL_NOTEQUAL);
// else
glDepthFunc(GL_EQUAL);
break;
case GR_CMP_GREATER:
if (w_buffer_mode)
glDepthFunc(GL_LESS);
else
glDepthFunc(GL_GREATER);
break;
case GR_CMP_NEVER:
glDepthFunc(GL_NEVER);
break;
case GR_CMP_NOTEQUAL:
// if (w_buffer_mode)
// glDepthFunc(GL_EQUAL);
// else
glDepthFunc(GL_NOTEQUAL);
break;
default:
display_warning("unknown depth buffer function : %x", function);
}
}
FX_ENTRY void FX_CALL
grDepthMask( FxBool mask )
{
WriteLog(M64MSG_VERBOSE, "grDepthMask(%d)\r\n", mask);
glDepthMask(mask);
}
#include <SDL.h>
float biasFactor = 0;
void FindBestDepthBias()
{
float f, bestz = 0.25f;
int x;
if (biasFactor) return;
biasFactor = 64.0f; // default value
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glEnable(GL_POLYGON_OFFSET_FILL);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glColor4ub(255,255,255,255);
glDepthMask(GL_TRUE);
for (x=0, f=1.0f; f<=65536.0f; x+=4, f*=2.0f) {
float z;
glPolygonOffset(0, f);
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(float(x+4 - widtho)/(width/2), float(0 - heighto)/(height/2), 0.5);
glVertex3f(float(x - widtho)/(width/2), float(0 - heighto)/(height/2), 0.5);
glVertex3f(float(x+4 - widtho)/(width/2), float(4 - heighto)/(height/2), 0.5);
glVertex3f(float(x - widtho)/(width/2), float(4 - heighto)/(height/2), 0.5);
glEnd();
glReadPixels(x+2, 2+viewport_offset, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
z -= 0.75f + 8e-6f;
if (z<0.0f) z = -z;
if (z < bestz) {
bestz = z;
biasFactor = f;
}
WriteLog(M64MSG_VERBOSE, "f %g z %g\n", f, z);
}
WriteLog(M64MSG_INFO, " --> bias factor %g\n", biasFactor);
glPopAttrib();
// SDL_GL_SwapBuffers();
// getchar();
}
FX_ENTRY void FX_CALL
grDepthBiasLevel( FxI32 level )
{
WriteLog(M64MSG_VERBOSE, "grDepthBiasLevel(%d)\r\n", level);
//depth_bias = level;
if (level)
{
if(w_buffer_mode)
glPolygonOffset(1.0f, -(float)level*zscale/255.0f);
else
glPolygonOffset(0, (float)level*biasFactor);
//glPolygonOffset(0, (float)level*128.0f*zscale/2);
glEnable(GL_POLYGON_OFFSET_FILL);
}
else
{
glPolygonOffset(0,0);
glDisable(GL_POLYGON_OFFSET_FILL);
}
}
// draw
FX_ENTRY void FX_CALL
grDrawTriangle( const void *a, const void *b, const void *c )
{
float *a_x = (float*)a + xy_off/sizeof(float);
float *a_y = (float*)a + xy_off/sizeof(float) + 1;
float *a_z = (float*)a + z_off/sizeof(float);
float *a_q = (float*)a + q_off/sizeof(float);
unsigned char *a_pargb = (unsigned char*)a + pargb_off;
float *a_s0 = (float*)a + st0_off/sizeof(float);
float *a_t0 = (float*)a + st0_off/sizeof(float) + 1;
float *a_s1 = (float*)a + st1_off/sizeof(float);
float *a_t1 = (float*)a + st1_off/sizeof(float) + 1;
float *a_fog = (float*)a + fog_ext_off/sizeof(float);
float *b_x = (float*)b + xy_off/sizeof(float);
float *b_y = (float*)b + xy_off/sizeof(float) + 1;
float *b_z = (float*)b + z_off/sizeof(float);
float *b_q = (float*)b + q_off/sizeof(float);
unsigned char *b_pargb = (unsigned char*)b + pargb_off;
float *b_s0 = (float*)b + st0_off/sizeof(float);
float *b_t0 = (float*)b + st0_off/sizeof(float) + 1;
float *b_s1 = (float*)b + st1_off/sizeof(float);
float *b_t1 = (float*)b + st1_off/sizeof(float) + 1;
float *b_fog = (float*)b + fog_ext_off/sizeof(float);
float *c_x = (float*)c + xy_off/sizeof(float);
float *c_y = (float*)c + xy_off/sizeof(float) + 1;
float *c_z = (float*)c + z_off/sizeof(float);
float *c_q = (float*)c + q_off/sizeof(float);
unsigned char *c_pargb = (unsigned char*)c + pargb_off;
float *c_s0 = (float*)c + st0_off/sizeof(float);
float *c_t0 = (float*)c + st0_off/sizeof(float) + 1;
float *c_s1 = (float*)c + st1_off/sizeof(float);
float *c_t1 = (float*)c + st1_off/sizeof(float) + 1;
float *c_fog = (float*)c + fog_ext_off/sizeof(float);
WriteLog(M64MSG_VERBOSE, "grDrawTriangle()\r\n");
//if(*a_fog == 0.0f) *a_fog = 1.0f;
//if(*b_fog == 0.0f) *b_fog = 1.0f;
//if(*c_fog == 0.0f) *c_fog = 1.0f;
// ugly ? i know but nvidia drivers are losing the viewport otherwise
if(!render_to_texture && viewport_width)
{
glViewport(0, viewport_offset, viewport_width, viewport_height);
viewport_width=0;
}
reloadTexture();
if(glsl_support && need_to_compile) compile_shader();
glBegin(GL_TRIANGLES);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *a_s0 / *a_q / (float)tex1_width,
ytex(0, *a_t0 / *a_q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *a_s1 / *a_q / (float)tex0_width,
ytex(1, *a_t1 / *a_q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*a_s0 / *a_q / (float)tex0_width,
ytex(0, *a_t0 / *a_q / (float)tex0_height));
}
if (pargb_en)
glColor4f(a_pargb[2]/255.0f, a_pargb[1]/255.0f, a_pargb[0]/255.0f, a_pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *a_q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *a_fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *a_q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *a_fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *a_q)/255.0f);
else
glFogCoordfEXT((1.0f / *a_fog)/255.0f);*/
}
}
glVertex4f((*a_x - (float)widtho) / (float)(width/2) / *a_q,
-(*a_y - (float)heighto) / (float)(height/2) / *a_q, ZCALC(*a_z, *a_q), 1.0f / *a_q);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *b_s0 / *b_q / (float)tex1_width,
ytex(0, *b_t0 / *b_q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *b_s1 / *b_q / (float)tex0_width,
ytex(1, *b_t1 / *b_q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*b_s0 / *b_q / (float)tex0_width,
ytex(0, *b_t0 / *b_q / (float)tex0_height));
}
if (pargb_en)
glColor4f(b_pargb[2]/255.0f, b_pargb[1]/255.0f, b_pargb[0]/255.0f, b_pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *b_q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *b_fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *b_q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *b_fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *b_q)/255.0f);
else
glFogCoordfEXT((1.0f / *b_fog)/255.0f);*/
}
}
glVertex4f((*b_x - (float)widtho) / (float)(width/2) / *b_q,
-(*b_y - (float)heighto) / (float)(height/2) / *b_q, ZCALC(*b_z, *b_q), 1.0f / *b_q);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *c_s0 / *c_q / (float)tex1_width,
ytex(0, *c_t0 / *c_q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *c_s1 / *c_q / (float)tex0_width,
ytex(1, *c_t1 / *c_q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*c_s0 / *c_q / (float)tex0_width,
ytex(0, *c_t0 / *c_q / (float)tex0_height));
}
if (pargb_en)
glColor4f(c_pargb[2]/255.0f, c_pargb[1]/255.0f, c_pargb[0]/255.0f, c_pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *c_q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *c_fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *c_q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *c_fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *c_q)/255.0f);
else
glFogCoordfEXT((1.0f / *c_fog)/255.0f);*/
}
}
glVertex4f((*c_x - (float)widtho) / (float)(width/2) / *c_q,
-(*c_y - (float)heighto) / (float)(height/2) / *c_q, ZCALC(*c_z ,*c_q), 1.0f / *c_q);
glEnd();
}
FX_ENTRY void FX_CALL
grDrawPoint( const void *pt )
{
float *x = (float*)pt + xy_off/sizeof(float);
float *y = (float*)pt + xy_off/sizeof(float) + 1;
float *z = (float*)pt + z_off/sizeof(float);
float *q = (float*)pt + q_off/sizeof(float);
unsigned char *pargb = (unsigned char*)pt + pargb_off;
float *s0 = (float*)pt + st0_off/sizeof(float);
float *t0 = (float*)pt + st0_off/sizeof(float) + 1;
float *s1 = (float*)pt + st1_off/sizeof(float);
float *t1 = (float*)pt + st1_off/sizeof(float) + 1;
float *fog = (float*)pt + fog_ext_off/sizeof(float);
WriteLog(M64MSG_VERBOSE, "grDrawPoint()\r\n");
reloadTexture();
if(glsl_support && need_to_compile) compile_shader();
glBegin(GL_POINTS);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *s0 / *q / (float)tex1_width,
ytex(0, *t0 / *q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *s1 / *q / (float)tex0_width,
ytex(1, *t1 / *q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*s0 / *q / (float)tex0_width,
ytex(0, *t0 / *q / (float)tex0_height));
}
if (pargb_en)
glColor4f(pargb[2]/255.0f, pargb[1]/255.0f, pargb[0]/255.0f, pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/255.0f);
else
glFogCoordfEXT((1.0f / *fog)/255.0f);*/
}
}
glVertex4f((*x - (float)widtho) / (float)(width/2) / *q,
-(*y - (float)heighto) / (float)(height/2) / *q, ZCALC(*z ,*q), 1.0f / *q);
glEnd();
}
FX_ENTRY void FX_CALL
grDrawLine( const void *a, const void *b )
{
float *a_x = (float*)a + xy_off/sizeof(float);
float *a_y = (float*)a + xy_off/sizeof(float) + 1;
float *a_z = (float*)a + z_off/sizeof(float);
float *a_q = (float*)a + q_off/sizeof(float);
unsigned char *a_pargb = (unsigned char*)a + pargb_off;
float *a_s0 = (float*)a + st0_off/sizeof(float);
float *a_t0 = (float*)a + st0_off/sizeof(float) + 1;
float *a_s1 = (float*)a + st1_off/sizeof(float);
float *a_t1 = (float*)a + st1_off/sizeof(float) + 1;
float *a_fog = (float*)a + fog_ext_off/sizeof(float);
float *b_x = (float*)b + xy_off/sizeof(float);
float *b_y = (float*)b + xy_off/sizeof(float) + 1;
float *b_z = (float*)b + z_off/sizeof(float);
float *b_q = (float*)b + q_off/sizeof(float);
unsigned char *b_pargb = (unsigned char*)b + pargb_off;
float *b_s0 = (float*)b + st0_off/sizeof(float);
float *b_t0 = (float*)b + st0_off/sizeof(float) + 1;
float *b_s1 = (float*)b + st1_off/sizeof(float);
float *b_t1 = (float*)b + st1_off/sizeof(float) + 1;
float *b_fog = (float*)b + fog_ext_off/sizeof(float);
WriteLog(M64MSG_VERBOSE, "grDrawLine()\r\n");
//if(*a_fog == 0.0f) *a_fog = 1.0f;
//if(*b_fog == 0.0f) *b_fog = 1.0f;
reloadTexture();
if(glsl_support && need_to_compile) compile_shader();
glBegin(GL_LINES);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *a_s0 / *a_q / (float)tex1_width, ytex(0, *a_t0 / *a_q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *a_s1 / *a_q / (float)tex0_width, ytex(1, *a_t1 / *a_q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*a_s0 / *a_q / (float)tex0_width, ytex(0, *a_t0 / *a_q / (float)tex0_height));
}
if (pargb_en)
glColor4f(a_pargb[2]/255.0f, a_pargb[1]/255.0f, a_pargb[0]/255.0f, a_pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *a_q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *a_fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *a_q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *a_fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *a_q)/255.0f);
else
glFogCoordfEXT((1.0f / *a_fog)/255.0f);*/
}
}
glVertex4f((*a_x - (float)widtho) / (float)(width/2) / *a_q,
-(*a_y - (float)heighto) / (float)(height/2) / *a_q, ZCALC(*a_z, *a_q), 1.0f / *a_q);
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *b_s0 / *b_q / (float)tex1_width,
ytex(0, *b_t0 / *b_q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *b_s1 / *b_q / (float)tex0_width,
ytex(1, *b_t1 / *b_q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*b_s0 / *b_q / (float)tex0_width,
ytex(0, *b_t0 / *b_q / (float)tex0_height));
}
if (pargb_en)
glColor4f(b_pargb[2]/255.0f, b_pargb[1]/255.0f, b_pargb[0]/255.0f, b_pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *b_q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *b_fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *b_q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *b_fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *b_q)/255.0f);
else
glFogCoordfEXT((1.0f / *b_fog)/255.0f);*/
}
}
glVertex4f((*b_x - (float)widtho) / (float)(width/2) / *b_q,
-(*b_y - (float)heighto) / (float)(height/2) / *b_q, ZCALC(*b_z, *b_q), 1.0f / *b_q);
glEnd();
}
FX_ENTRY void FX_CALL
grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers2)
{
unsigned int i;
float *x, *y, *q, *s0, *t0, *s1, *t1, *z, *fog;
unsigned char *pargb;
void **pointers = (void**)pointers2;
WriteLog(M64MSG_VERBOSE, "grDrawVertexArray(%d,%d)\r\n", mode, Count);
reloadTexture();
if(glsl_support && need_to_compile) compile_shader();
switch(mode)
{
case GR_TRIANGLE_FAN:
glBegin(GL_TRIANGLE_FAN);
break;
default:
display_warning("grDrawVertexArray : unknown mode : %x", mode);
}
for (i=0; i<Count; i++)
{
x = (float*)pointers[i] + xy_off/sizeof(float);
y = (float*)pointers[i] + xy_off/sizeof(float) + 1;
z = (float*)pointers[i] + z_off/sizeof(float);
q = (float*)pointers[i] + q_off/sizeof(float);
pargb = (unsigned char*)pointers[i] + pargb_off;
s0 = (float*)pointers[i] + st0_off/sizeof(float);
t0 = (float*)pointers[i] + st0_off/sizeof(float) + 1;
s1 = (float*)pointers[i] + st1_off/sizeof(float);
t1 = (float*)pointers[i] + st1_off/sizeof(float) + 1;
fog = (float*)pointers[i] + fog_ext_off/sizeof(float);
//if(*fog == 0.0f) *fog = 1.0f;
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *s0 / *q / (float)tex1_width,
ytex(0, *t0 / *q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *s1 / *q / (float)tex0_width,
ytex(1, *t1 / *q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*s0 / *q / (float)tex0_width,
ytex(0, *t0 / *q / (float)tex0_height));
}
if (pargb_en)
glColor4f(pargb[2]/255.0f, pargb[1]/255.0f, pargb[0]/255.0f, pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/255.0f);
else
glFogCoordfEXT((1.0f / *fog)/255.0f);*/
}
}
//glFogCoordfEXT(192.0f);
//glSecondaryColor3f(192.0f / 256.0f,0,0);
//if((1.0f / *fog)/256.0f < 0.0f || (1.0f / *fog)/256.0f > 1.0f)
glVertex4f((*x - (float)widtho) / (float)(width/2) / *q,
-(*y - (float)heighto) / (float)(height/2) / *q, ZCALC(*z, *q), 1.0f / *q);
}
glEnd();
}
FX_ENTRY void FX_CALL
grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride)
{
unsigned int i;
float *x, *y, *q, *s0, *t0, *s1, *t1, *z, *fog;
unsigned char *pargb;
WriteLog(M64MSG_VERBOSE, "grDrawVertexArrayContiguous(%d,%d,%d)\r\n", mode, Count, stride);
// ZIGGY apparently, grDrawVertexArrayContiguous is only used to overwrite the
// whole screen, so we treat it as a grClearBuffer, no need to reload the texture
buffer_cleared = TRUE;
//reloadTexture();
if(glsl_support && need_to_compile) compile_shader();
switch(mode)
{
case GR_TRIANGLE_STRIP:
glBegin(GL_TRIANGLE_STRIP);
break;
case GR_TRIANGLE_FAN:
glBegin(GL_TRIANGLE_FAN);
break;
default:
display_warning("grDrawVertexArrayContiguous : unknown mode : %x", mode);
}
for (i=0; i<Count; i++)
{
x = (float*)((unsigned char*)pointers+stride*i) + xy_off/sizeof(float);
y = (float*)((unsigned char*)pointers+stride*i) + xy_off/sizeof(float) + 1;
z = (float*)((unsigned char*)pointers+stride*i) + z_off/sizeof(float);
q = (float*)((unsigned char*)pointers+stride*i) + q_off/sizeof(float);
pargb = (unsigned char*)pointers+stride*i + pargb_off;
s0 = (float*)((unsigned char*)pointers+stride*i) + st0_off/sizeof(float);
t0 = (float*)((unsigned char*)pointers+stride*i) + st0_off/sizeof(float) + 1;
s1 = (float*)((unsigned char*)pointers+stride*i) + st1_off/sizeof(float);
t1 = (float*)((unsigned char*)pointers+stride*i) + st1_off/sizeof(float) + 1;
fog = (float*)((unsigned char*)pointers+stride*i) + fog_ext_off/sizeof(float);
//if(*fog == 0.0f) *fog = 1.0f;
if (nbTextureUnits > 2)
{
if (st0_en)
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *s0 / *q / (float)tex1_width,
ytex(0, *t0 / *q / (float)tex1_height));
if (st1_en)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *s1 / *q / (float)tex0_width,
ytex(1, *t1 / *q / (float)tex0_height));
}
else
{
if (st0_en)
glTexCoord2f(*s0 / *q / (float)tex0_width,
ytex(0, *t0 / *q / (float)tex0_height));
}
if (pargb_en)
glColor4f(pargb[2]/255.0f, pargb[1]/255.0f, pargb[0]/255.0f, pargb[3]/255.0f);
if (fog_enabled && fog_coord_support)
{
if(!glsl_support)
{
if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/*/256.0f*/);
else
glFogCoordfEXT((1.0f / *fog)/*/256.0f*/);
}
else
{
if(!fog_ext_en || fog_enabled != 2)
glSecondaryColor3f((1.0f / *q) / 255.0f, 0.0f, 0.0f);
else
glSecondaryColor3f((1.0f / *fog) / 255.0f, 0.0f, 0.0f);
/*if(!fog_ext_en || fog_enabled != 2)
glFogCoordfEXT((1.0f / *q)/255.0f);
else
glFogCoordfEXT((1.0f / *fog)/255.0f);*/
}
}
glVertex4f((*x - (float)widtho) / (float)(width/2) / *q,
-(*y - (float)heighto) / (float)(height/2) / *q, ZCALC(*z, *q), 1.0f / *q);
}
glEnd();
}

View File

@ -0,0 +1,947 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
/*
** GLIDE.H
**
** The following #defines are relevant when using Glide:
**
** One of the following "platform constants" must be defined during
** compilation:
**
** __DOS__ Defined for 32-bit DOS applications
** __WIN32__ Defined for 32-bit Windows applications
** __sparc__ Defined for Sun Solaris/SunOS
** __linux__ Defined for Linux applications
** __FreeBSD__ Defined for FreeBSD applications
** __NetBSD__ Defined for NetBSD applications
** __OpenBSD__ Defined for OpenBSD applications
** __IRIX__ Defined for SGI Irix applications
**
*/
#ifndef __GLIDE_H__
#define __GLIDE_H__
#include <3dfx.h>
#include <glidesys.h>
#include <sst1vid.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
** -----------------------------------------------------------------------
** TYPE DEFINITIONS
** -----------------------------------------------------------------------
*/
typedef FxU32 GrColor_t;
typedef FxU8 GrAlpha_t;
typedef FxU32 GrMipMapId_t;
typedef FxU32 GrStipplePattern_t;
typedef FxU8 GrFog_t;
typedef FxU32 GrContext_t;
typedef int (FX_CALL *GrProc)();
/*
** -----------------------------------------------------------------------
** CONSTANTS AND TYPES
** -----------------------------------------------------------------------
*/
#define GR_NULL_MIPMAP_HANDLE ((GrMipMapId_t) -1)
#define GR_MIPMAPLEVELMASK_EVEN FXBIT(0)
#define GR_MIPMAPLEVELMASK_ODD FXBIT(1)
#define GR_MIPMAPLEVELMASK_BOTH (GR_MIPMAPLEVELMASK_EVEN | GR_MIPMAPLEVELMASK_ODD )
#define GR_LODBIAS_BILINEAR 0.5
#define GR_LODBIAS_TRILINEAR 0.0
typedef FxI32 GrChipID_t;
#define GR_TMU0 0x0
#define GR_TMU1 0x1
#define GR_TMU2 0x2
#define GR_FBI 0x0
typedef FxI32 GrCombineFunction_t;
#define GR_COMBINE_FUNCTION_ZERO 0x0
#define GR_COMBINE_FUNCTION_NONE GR_COMBINE_FUNCTION_ZERO
#define GR_COMBINE_FUNCTION_LOCAL 0x1
#define GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2
#define GR_COMBINE_FUNCTION_SCALE_OTHER 0x3
#define GR_COMBINE_FUNCTION_BLEND_OTHER GR_COMBINE_FUNCTION_SCALE_OTHER
#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4
#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7
#define GR_COMBINE_FUNCTION_BLEND GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL
#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8
#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9
#define GR_COMBINE_FUNCTION_BLEND_LOCAL GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL
#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10
typedef FxI32 GrCombineFactor_t;
#define GR_COMBINE_FACTOR_ZERO 0x0
#define GR_COMBINE_FACTOR_NONE GR_COMBINE_FACTOR_ZERO
#define GR_COMBINE_FACTOR_LOCAL 0x1
#define GR_COMBINE_FACTOR_OTHER_ALPHA 0x2
#define GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3
#define GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4
#define GR_COMBINE_FACTOR_TEXTURE_RGB 0x5
#define GR_COMBINE_FACTOR_DETAIL_FACTOR GR_COMBINE_FACTOR_TEXTURE_ALPHA
#define GR_COMBINE_FACTOR_LOD_FRACTION 0x5
#define GR_COMBINE_FACTOR_ONE 0x8
#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9
#define GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa
#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb
#define GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc
#define GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA
#define GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd
typedef FxI32 GrCombineLocal_t;
#define GR_COMBINE_LOCAL_ITERATED 0x0
#define GR_COMBINE_LOCAL_CONSTANT 0x1
#define GR_COMBINE_LOCAL_NONE GR_COMBINE_LOCAL_CONSTANT
#define GR_COMBINE_LOCAL_DEPTH 0x2
typedef FxI32 GrCombineOther_t;
#define GR_COMBINE_OTHER_ITERATED 0x0
#define GR_COMBINE_OTHER_TEXTURE 0x1
#define GR_COMBINE_OTHER_CONSTANT 0x2
#define GR_COMBINE_OTHER_NONE GR_COMBINE_OTHER_CONSTANT
typedef FxI32 GrAlphaSource_t;
#define GR_ALPHASOURCE_CC_ALPHA 0x0
#define GR_ALPHASOURCE_ITERATED_ALPHA 0x1
#define GR_ALPHASOURCE_TEXTURE_ALPHA 0x2
#define GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA 0x3
typedef FxI32 GrColorCombineFnc_t;
#define GR_COLORCOMBINE_ZERO 0x0
#define GR_COLORCOMBINE_CCRGB 0x1
#define GR_COLORCOMBINE_ITRGB 0x2
#define GR_COLORCOMBINE_ITRGB_DELTA0 0x3
#define GR_COLORCOMBINE_DECAL_TEXTURE 0x4
#define GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB 0x5
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB 0x6
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 0x7
#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA 0x8
#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA 0x9
#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB 0xa
#define GR_COLORCOMBINE_TEXTURE_ADD_ITRGB 0xb
#define GR_COLORCOMBINE_TEXTURE_SUB_ITRGB 0xc
#define GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA 0xd
#define GR_COLORCOMBINE_DIFF_SPEC_A 0xe
#define GR_COLORCOMBINE_DIFF_SPEC_B 0xf
#define GR_COLORCOMBINE_ONE 0x10
typedef FxI32 GrAlphaBlendFnc_t;
#define GR_BLEND_ZERO 0x0
#define GR_BLEND_SRC_ALPHA 0x1
#define GR_BLEND_SRC_COLOR 0x2
#define GR_BLEND_DST_COLOR GR_BLEND_SRC_COLOR
#define GR_BLEND_DST_ALPHA 0x3
#define GR_BLEND_ONE 0x4
#define GR_BLEND_ONE_MINUS_SRC_ALPHA 0x5
#define GR_BLEND_ONE_MINUS_SRC_COLOR 0x6
#define GR_BLEND_ONE_MINUS_DST_COLOR GR_BLEND_ONE_MINUS_SRC_COLOR
#define GR_BLEND_ONE_MINUS_DST_ALPHA 0x7
#define GR_BLEND_RESERVED_8 0x8
#define GR_BLEND_RESERVED_9 0x9
#define GR_BLEND_RESERVED_A 0xa
#define GR_BLEND_RESERVED_B 0xb
#define GR_BLEND_RESERVED_C 0xc
#define GR_BLEND_RESERVED_D 0xd
#define GR_BLEND_RESERVED_E 0xe
#define GR_BLEND_ALPHA_SATURATE 0xf
#define GR_BLEND_PREFOG_COLOR GR_BLEND_ALPHA_SATURATE
typedef FxI32 GrAspectRatio_t;
#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */
#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */
#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */
#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */
#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */
#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */
#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */
typedef FxI32 GrBuffer_t;
#define GR_BUFFER_FRONTBUFFER 0x0
#define GR_BUFFER_BACKBUFFER 0x1
#define GR_BUFFER_AUXBUFFER 0x2
#define GR_BUFFER_DEPTHBUFFER 0x3
#define GR_BUFFER_ALPHABUFFER 0x4
#define GR_BUFFER_TRIPLEBUFFER 0x5
typedef FxI32 GrChromakeyMode_t;
#define GR_CHROMAKEY_DISABLE 0x0
#define GR_CHROMAKEY_ENABLE 0x1
typedef FxI32 GrChromaRangeMode_t;
#define GR_CHROMARANGE_RGB_ALL_EXT 0x0
#define GR_CHROMARANGE_DISABLE_EXT 0x00
#define GR_CHROMARANGE_ENABLE_EXT 0x01
typedef FxI32 GrTexChromakeyMode_t;
#define GR_TEXCHROMA_DISABLE_EXT 0x0
#define GR_TEXCHROMA_ENABLE_EXT 0x1
#define GR_TEXCHROMARANGE_RGB_ALL_EXT 0x0
typedef FxI32 GrCmpFnc_t;
#define GR_CMP_NEVER 0x0
#define GR_CMP_LESS 0x1
#define GR_CMP_EQUAL 0x2
#define GR_CMP_LEQUAL 0x3
#define GR_CMP_GREATER 0x4
#define GR_CMP_NOTEQUAL 0x5
#define GR_CMP_GEQUAL 0x6
#define GR_CMP_ALWAYS 0x7
typedef FxI32 GrColorFormat_t;
#define GR_COLORFORMAT_ARGB 0x0
#define GR_COLORFORMAT_ABGR 0x1
#define GR_COLORFORMAT_RGBA 0x2
#define GR_COLORFORMAT_BGRA 0x3
typedef FxI32 GrCullMode_t;
#define GR_CULL_DISABLE 0x0
#define GR_CULL_NEGATIVE 0x1
#define GR_CULL_POSITIVE 0x2
typedef FxI32 GrDepthBufferMode_t;
#define GR_DEPTHBUFFER_DISABLE 0x0
#define GR_DEPTHBUFFER_ZBUFFER 0x1
#define GR_DEPTHBUFFER_WBUFFER 0x2
#define GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS 0x3
#define GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS 0x4
typedef FxI32 GrDitherMode_t;
#define GR_DITHER_DISABLE 0x0
#define GR_DITHER_2x2 0x1
#define GR_DITHER_4x4 0x2
typedef FxI32 GrStippleMode_t;
#define GR_STIPPLE_DISABLE 0x0
#define GR_STIPPLE_PATTERN 0x1
#define GR_STIPPLE_ROTATE 0x2
typedef FxI32 GrFogMode_t;
#define GR_FOG_DISABLE 0x0
#define GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT 0x1
#define GR_FOG_WITH_TABLE_ON_Q 0x2
#define GR_FOG_WITH_TABLE_ON_W GR_FOG_WITH_TABLE_ON_Q
#define GR_FOG_WITH_ITERATED_Z 0x3
#define GR_FOG_WITH_ITERATED_ALPHA_EXT 0x4
#define GR_FOG_MULT2 0x100
#define GR_FOG_ADD2 0x200
typedef FxU32 GrLock_t;
#define GR_LFB_READ_ONLY 0x00
#define GR_LFB_WRITE_ONLY 0x01
#define GR_LFB_IDLE 0x00
#define GR_LFB_NOIDLE 0x10
#define GR_LFB_WRITE_ONLY_EXPLICIT_EXT 0x02 /* explicitly not allow reading from the lfb pointer */
typedef FxI32 GrLfbBypassMode_t;
#define GR_LFBBYPASS_DISABLE 0x0
#define GR_LFBBYPASS_ENABLE 0x1
typedef FxI32 GrLfbWriteMode_t;
#define GR_LFBWRITEMODE_565 0x0 /* RGB:RGB */
#define GR_LFBWRITEMODE_555 0x1 /* RGB:RGB */
#define GR_LFBWRITEMODE_1555 0x2 /* ARGB:ARGB */
#define GR_LFBWRITEMODE_RESERVED1 0x3
#define GR_LFBWRITEMODE_888 0x4 /* RGB */
#define GR_LFBWRITEMODE_8888 0x5 /* ARGB */
#define GR_LFBWRITEMODE_RESERVED2 0x6
#define GR_LFBWRITEMODE_RESERVED3 0x7
#define GR_LFBWRITEMODE_RESERVED4 0x8
#define GR_LFBWRITEMODE_RESERVED5 0x9
#define GR_LFBWRITEMODE_RESERVED6 0xa
#define GR_LFBWRITEMODE_RESERVED7 0xb
#define GR_LFBWRITEMODE_565_DEPTH 0xc /* RGB:DEPTH */
#define GR_LFBWRITEMODE_555_DEPTH 0xd /* RGB:DEPTH */
#define GR_LFBWRITEMODE_1555_DEPTH 0xe /* ARGB:DEPTH */
#define GR_LFBWRITEMODE_ZA16 0xf /* DEPTH:DEPTH */
#define GR_LFBWRITEMODE_ANY 0xFF
typedef FxI32 GrOriginLocation_t;
#define GR_ORIGIN_UPPER_LEFT 0x0
#define GR_ORIGIN_LOWER_LEFT 0x1
#define GR_ORIGIN_ANY 0xFF
typedef struct {
int size;
void *lfbPtr;
FxU32 strideInBytes;
GrLfbWriteMode_t writeMode;
GrOriginLocation_t origin;
} GrLfbInfo_t;
typedef FxI32 GrLOD_t;
#define GR_LOD_LOG2_256 0x8
#define GR_LOD_LOG2_128 0x7
#define GR_LOD_LOG2_64 0x6
#define GR_LOD_LOG2_32 0x5
#define GR_LOD_LOG2_16 0x4
#define GR_LOD_LOG2_8 0x3
#define GR_LOD_LOG2_4 0x2
#define GR_LOD_LOG2_2 0x1
#define GR_LOD_LOG2_1 0x0
typedef FxI32 GrMipMapMode_t;
#define GR_MIPMAP_DISABLE 0x0 /* no mip mapping */
#define GR_MIPMAP_NEAREST 0x1 /* use nearest mipmap */
#define GR_MIPMAP_NEAREST_DITHER 0x2 /* GR_MIPMAP_NEAREST + LOD dith */
typedef FxI32 GrSmoothingMode_t;
#define GR_SMOOTHING_DISABLE 0x0
#define GR_SMOOTHING_ENABLE 0x1
typedef FxI32 GrTextureClampMode_t;
#define GR_TEXTURECLAMP_WRAP 0x0
#define GR_TEXTURECLAMP_CLAMP 0x1
#define GR_TEXTURECLAMP_MIRROR_EXT 0x2
typedef FxI32 GrTextureCombineFnc_t;
#define GR_TEXTURECOMBINE_ZERO 0x0 /* texout = 0 */
#define GR_TEXTURECOMBINE_DECAL 0x1 /* texout = texthis */
#define GR_TEXTURECOMBINE_OTHER 0x2 /* this TMU in passthru mode */
#define GR_TEXTURECOMBINE_ADD 0x3 /* tout = tthis + t(this+1) */
#define GR_TEXTURECOMBINE_MULTIPLY 0x4 /* texout = tthis * t(this+1) */
#define GR_TEXTURECOMBINE_SUBTRACT 0x5 /* Sutract from upstream TMU */
#define GR_TEXTURECOMBINE_DETAIL 0x6 /* detail--detail on tthis */
#define GR_TEXTURECOMBINE_DETAIL_OTHER 0x7 /* detail--detail on tthis+1 */
#define GR_TEXTURECOMBINE_TRILINEAR_ODD 0x8 /* trilinear--odd levels tthis*/
#define GR_TEXTURECOMBINE_TRILINEAR_EVEN 0x9 /*trilinear--even levels tthis*/
#define GR_TEXTURECOMBINE_ONE 0xa /* texout = 0xFFFFFFFF */
typedef FxI32 GrTextureFilterMode_t;
#define GR_TEXTUREFILTER_POINT_SAMPLED 0x0
#define GR_TEXTUREFILTER_BILINEAR 0x1
typedef FxI32 GrTextureFormat_t;
/* KoolSmoky - */
#define GR_TEXFMT_8BIT 0x0
#define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT
#define GR_TEXFMT_YIQ_422 0x1
#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */
#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */
#define GR_TEXFMT_RSVD0 0x6 /* GR_TEXFMT_P_8_RGBA */
#define GR_TEXFMT_P_8_6666 GR_TEXFMT_RSVD0
#define GR_TEXFMT_P_8_6666_EXT GR_TEXFMT_RSVD0
#define GR_TEXFMT_RSVD1 0x7
#define GR_TEXFMT_16BIT 0x8
#define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT
#define GR_TEXFMT_AYIQ_8422 0x9
#define GR_TEXFMT_RGB_565 0xa
#define GR_TEXFMT_ARGB_1555 0xb
#define GR_TEXFMT_ARGB_4444 0xc
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd
#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */
#define GR_TEXFMT_RSVD2 0xf
#define GR_TEXFMT_RSVD4 GR_TEXFMT_RSVD2
typedef FxU32 GrTexTable_t;
#define GR_TEXTABLE_NCC0 0x0
#define GR_TEXTABLE_NCC1 0x1
#define GR_TEXTABLE_PALETTE 0x2
#define GR_TEXTABLE_PALETTE_6666_EXT 0x3
typedef FxU32 GrNCCTable_t;
#define GR_NCCTABLE_NCC0 0x0
#define GR_NCCTABLE_NCC1 0x1
typedef FxU32 GrTexBaseRange_t;
#define GR_TEXBASE_256 0x3
#define GR_TEXBASE_128 0x2
#define GR_TEXBASE_64 0x1
#define GR_TEXBASE_32_TO_1 0x0
typedef FxU32 GrEnableMode_t;
#define GR_MODE_DISABLE 0x0
#define GR_MODE_ENABLE 0x1
#define GR_AA_ORDERED 0x01
#define GR_ALLOW_MIPMAP_DITHER 0x02
#define GR_PASSTHRU 0x03
#define GR_SHAMELESS_PLUG 0x04
#define GR_VIDEO_SMOOTHING 0x05
typedef FxU32 GrCoordinateSpaceMode_t;
#define GR_WINDOW_COORDS 0x00
#define GR_CLIP_COORDS 0x01
/* Types of data in strips */
#define GR_FLOAT 0
#define GR_U8 1
/* Parameters for strips */
#define GR_PARAM_XY 0x01
#define GR_PARAM_Z 0x02
#define GR_PARAM_W 0x03
#define GR_PARAM_Q 0x04
#define GR_PARAM_FOG_EXT 0x05
#define GR_PARAM_A 0x10
#define GR_PARAM_RGB 0x20
#define GR_PARAM_PARGB 0x30
#define GR_PARAM_ST0 0x40
#define GR_PARAM_ST1 GR_PARAM_ST0+1
#define GR_PARAM_ST2 GR_PARAM_ST0+2
#define GR_PARAM_Q0 0x50
#define GR_PARAM_Q1 GR_PARAM_Q0+1
#define GR_PARAM_Q2 GR_PARAM_Q0+2
#define GR_PARAM_DISABLE 0x00
#define GR_PARAM_ENABLE 0x01
/*
** grDrawVertexArray/grDrawVertexArrayContiguous primitive type
*/
#define GR_POINTS 0
#define GR_LINE_STRIP 1
#define GR_LINES 2
#define GR_POLYGON 3
#define GR_TRIANGLE_STRIP 4
#define GR_TRIANGLE_FAN 5
#define GR_TRIANGLES 6
#define GR_TRIANGLE_STRIP_CONTINUE 7
#define GR_TRIANGLE_FAN_CONTINUE 8
/*
** grGet/grReset types
*/
#define GR_BITS_DEPTH 0x01
#define GR_BITS_RGBA 0x02
#define GR_FIFO_FULLNESS 0x03
#define GR_FOG_TABLE_ENTRIES 0x04
#define GR_GAMMA_TABLE_ENTRIES 0x05
#define GR_GLIDE_STATE_SIZE 0x06
#define GR_GLIDE_VERTEXLAYOUT_SIZE 0x07
#define GR_IS_BUSY 0x08
#define GR_LFB_PIXEL_PIPE 0x09
#define GR_MAX_TEXTURE_SIZE 0x0a
#define GR_MAX_TEXTURE_ASPECT_RATIO 0x0b
#define GR_MEMORY_FB 0x0c
#define GR_MEMORY_TMU 0x0d
#define GR_MEMORY_UMA 0x0e
#define GR_NUM_BOARDS 0x0f
#define GR_NON_POWER_OF_TWO_TEXTURES 0x10
#define GR_NUM_FB 0x11
#define GR_NUM_SWAP_HISTORY_BUFFER 0x12
#define GR_NUM_TMU 0x13
#define GR_PENDING_BUFFERSWAPS 0x14
#define GR_REVISION_FB 0x15
#define GR_REVISION_TMU 0x16
#define GR_STATS_LINES 0x17 /* grGet/grReset */
#define GR_STATS_PIXELS_AFUNC_FAIL 0x18
#define GR_STATS_PIXELS_CHROMA_FAIL 0x19
#define GR_STATS_PIXELS_DEPTHFUNC_FAIL 0x1a
#define GR_STATS_PIXELS_IN 0x1b
#define GR_STATS_PIXELS_OUT 0x1c
#define GR_STATS_PIXELS 0x1d /* grReset */
#define GR_STATS_POINTS 0x1e /* grGet/grReset */
#define GR_STATS_TRIANGLES_IN 0x1f
#define GR_STATS_TRIANGLES_OUT 0x20
#define GR_STATS_TRIANGLES 0x21 /* grReset */
#define GR_SWAP_HISTORY 0x22
#define GR_SUPPORTS_PASSTHRU 0x23
#define GR_TEXTURE_ALIGN 0x24
#define GR_VIDEO_POSITION 0x25
#define GR_VIEWPORT 0x26
#define GR_WDEPTH_MIN_MAX 0x27
#define GR_ZDEPTH_MIN_MAX 0x28
#define GR_VERTEX_PARAMETER 0x29
#define GR_BITS_GAMMA 0x2a
#define GR_GET_RESERVED_1 0x1000
/*
** grGetString types
*/
#define GR_EXTENSION 0xa0
#define GR_HARDWARE 0xa1
#define GR_RENDERER 0xa2
#define GR_VENDOR 0xa3
#define GR_VERSION 0xa4
/*
** -----------------------------------------------------------------------
** STRUCTURES
** -----------------------------------------------------------------------
*/
typedef struct {
GrLOD_t smallLodLog2;
GrLOD_t largeLodLog2;
GrAspectRatio_t aspectRatioLog2;
GrTextureFormat_t format;
void *data;
} GrTexInfo;
typedef struct GrSstPerfStats_s {
FxU32 pixelsIn; /* # pixels processed (minus buffer clears) */
FxU32 chromaFail; /* # pixels not drawn due to chroma key */
FxU32 zFuncFail; /* # pixels not drawn due to Z comparison */
FxU32 aFuncFail; /* # pixels not drawn due to alpha comparison */
FxU32 pixelsOut; /* # pixels drawn (including buffer clears) */
} GrSstPerfStats_t;
typedef struct {
GrScreenResolution_t resolution;
GrScreenRefresh_t refresh;
int numColorBuffers;
int numAuxBuffers;
} GrResolution;
typedef GrResolution GlideResolution;
#define GR_QUERY_ANY ((FxU32)(~0))
typedef FxU32 GrLfbSrcFmt_t;
#define GR_LFB_SRC_FMT_565 0x00
#define GR_LFB_SRC_FMT_555 0x01
#define GR_LFB_SRC_FMT_1555 0x02
#define GR_LFB_SRC_FMT_888 0x04
#define GR_LFB_SRC_FMT_8888 0x05
#define GR_LFB_SRC_FMT_565_DEPTH 0x0c
#define GR_LFB_SRC_FMT_555_DEPTH 0x0d
#define GR_LFB_SRC_FMT_1555_DEPTH 0x0e
#define GR_LFB_SRC_FMT_ZA16 0x0f
#define GR_LFB_SRC_FMT_RLE16 0x80
#ifdef H3D
#define GR_HINT_H3DENABLE 4
#undef GR_HINTTYPE_MAX
#define GR_HINTTYPE_MAX 4
#endif
/*
** -----------------------------------------------------------------------
** FUNCTION PROTOTYPES
** -----------------------------------------------------------------------
*/
#ifndef FX_GLIDE_NO_FUNC_PROTO
/*
** rendering functions
*/
FX_ENTRY void FX_CALL
grDrawPoint( const void *pt );
FX_ENTRY void FX_CALL
grDrawLine( const void *v1, const void *v2 );
FX_ENTRY void FX_CALL
grDrawTriangle( const void *a, const void *b, const void *c );
FX_ENTRY void FX_CALL
grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode);
FX_ENTRY void FX_CALL
grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers);
FX_ENTRY void FX_CALL
grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride);
/*
** Antialiasing Functions
*/
FX_ENTRY void FX_CALL
grAADrawTriangle(
const void *a, const void *b, const void *c,
FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
);
/*
** buffer management
*/
FX_ENTRY void FX_CALL
grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth );
FX_ENTRY void FX_CALL
grBufferSwap( FxU32 swap_interval );
FX_ENTRY void FX_CALL
grRenderBuffer( GrBuffer_t buffer );
/*
** error management
*/
typedef void (*GrErrorCallbackFnc_t)( const char *string, FxBool fatal );
FX_ENTRY void FX_CALL
grErrorSetCallback( GrErrorCallbackFnc_t fnc );
/*
** SST routines
*/
FX_ENTRY void FX_CALL
grFinish(void);
FX_ENTRY void FX_CALL
grFlush(void);
FX_ENTRY GrContext_t FX_CALL
grSstWinOpen(
FxU32 hWnd,
GrScreenResolution_t screen_resolution,
GrScreenRefresh_t refresh_rate,
GrColorFormat_t color_format,
GrOriginLocation_t origin_location,
int nColBuffers,
int nAuxBuffers);
FX_ENTRY FxBool FX_CALL
grSstWinClose( GrContext_t context );
FX_ENTRY void FX_CALL
grSetNumPendingBuffers(FxI32 NumPendingBuffers);
FX_ENTRY FxBool FX_CALL
grSelectContext( GrContext_t context );
FX_ENTRY void FX_CALL
grSstOrigin(GrOriginLocation_t origin);
FX_ENTRY void FX_CALL
grSstSelect( int which_sst );
/*
** Glide configuration and special effect maintenance functions
*/
FX_ENTRY void FX_CALL
grAlphaBlendFunction(
GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df,
GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df
);
FX_ENTRY void FX_CALL
grAlphaCombine(
GrCombineFunction_t function, GrCombineFactor_t factor,
GrCombineLocal_t local, GrCombineOther_t other,
FxBool invert
);
FX_ENTRY void FX_CALL
grAlphaControlsITRGBLighting( FxBool enable );
FX_ENTRY void FX_CALL
grAlphaTestFunction( GrCmpFnc_t function );
FX_ENTRY void FX_CALL
grAlphaTestReferenceValue( GrAlpha_t value );
FX_ENTRY void FX_CALL
grChromakeyMode( GrChromakeyMode_t mode );
FX_ENTRY void FX_CALL
grChromakeyValue( GrColor_t value );
FX_ENTRY void FX_CALL
grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy );
FX_ENTRY void FX_CALL
grColorCombine(
GrCombineFunction_t function, GrCombineFactor_t factor,
GrCombineLocal_t local, GrCombineOther_t other,
FxBool invert );
FX_ENTRY void FX_CALL
grColorMask( FxBool rgb, FxBool a );
FX_ENTRY void FX_CALL
grCullMode( GrCullMode_t mode );
FX_ENTRY void FX_CALL
grConstantColorValue( GrColor_t value );
FX_ENTRY void FX_CALL
grDepthBiasLevel( FxI32 level );
FX_ENTRY void FX_CALL
grDepthBufferFunction( GrCmpFnc_t function );
FX_ENTRY void FX_CALL
grDepthBufferMode( GrDepthBufferMode_t mode );
FX_ENTRY void FX_CALL
grDepthMask( FxBool mask );
FX_ENTRY void FX_CALL
grDisableAllEffects( void );
FX_ENTRY void FX_CALL
grDitherMode( GrDitherMode_t mode );
FX_ENTRY void FX_CALL
grFogColorValue( GrColor_t fogcolor );
FX_ENTRY void FX_CALL
grFogMode( GrFogMode_t mode );
FX_ENTRY void FX_CALL
grFogTable( const GrFog_t ft[] );
FX_ENTRY void FX_CALL
grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue);
FX_ENTRY void FX_CALL
grSplash(float x, float y, float width, float height, FxU32 frame);
FX_ENTRY FxU32 FX_CALL
grGet( FxU32 pname, FxU32 plength, FxI32 *params );
FX_ENTRY const char * FX_CALL
grGetString( FxU32 pname );
FX_ENTRY FxI32 FX_CALL
grQueryResolutions( const GrResolution *resTemplate, GrResolution *output );
FX_ENTRY FxBool FX_CALL
grReset( FxU32 what );
FX_ENTRY GrProc FX_CALL
grGetProcAddress( const char *procName );
FX_ENTRY void FX_CALL
grEnable( GrEnableMode_t mode );
FX_ENTRY void FX_CALL
grDisable( GrEnableMode_t mode );
FX_ENTRY void FX_CALL
grCoordinateSpace( GrCoordinateSpaceMode_t mode );
FX_ENTRY void FX_CALL
grDepthRange( FxFloat n, FxFloat f );
FX_ENTRY void FX_CALL
grStippleMode( GrStippleMode_t mode );
FX_ENTRY void FX_CALL
grStipplePattern( GrStipplePattern_t mode );
FX_ENTRY void FX_CALL
grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height );
/*
** texture mapping control functions
*/
FX_ENTRY FxU32 FX_CALL
grTexCalcMemRequired(
GrLOD_t lodmin, GrLOD_t lodmax,
GrAspectRatio_t aspect, GrTextureFormat_t fmt);
FX_ENTRY FxU32 FX_CALL
grTexTextureMemRequired( FxU32 evenOdd,
GrTexInfo *info );
FX_ENTRY FxU32 FX_CALL
grTexMinAddress( GrChipID_t tmu );
FX_ENTRY FxU32 FX_CALL
grTexMaxAddress( GrChipID_t tmu );
FX_ENTRY void FX_CALL
grTexNCCTable( GrNCCTable_t table );
FX_ENTRY void FX_CALL
grTexSource( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info );
FX_ENTRY void FX_CALL
grTexClampMode(
GrChipID_t tmu,
GrTextureClampMode_t s_clampmode,
GrTextureClampMode_t t_clampmode
);
FX_ENTRY void FX_CALL
grTexCombine(
GrChipID_t tmu,
GrCombineFunction_t rgb_function,
GrCombineFactor_t rgb_factor,
GrCombineFunction_t alpha_function,
GrCombineFactor_t alpha_factor,
FxBool rgb_invert,
FxBool alpha_invert
);
FX_ENTRY void FX_CALL
grTexDetailControl(
GrChipID_t tmu,
int lod_bias,
FxU8 detail_scale,
float detail_max
);
FX_ENTRY void FX_CALL
grTexFilterMode(
GrChipID_t tmu,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode
);
FX_ENTRY void FX_CALL
grTexLodBiasValue(GrChipID_t tmu, float bias );
FX_ENTRY void FX_CALL
grTexDownloadMipMap( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info );
FX_ENTRY void FX_CALL
grTexDownloadMipMapLevel( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data );
FX_ENTRY FxBool FX_CALL
grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
FxU32 startAddress,
GrLOD_t thisLod,
GrLOD_t largeLod,
GrAspectRatio_t aspectRatio,
GrTextureFormat_t format,
FxU32 evenOdd,
void *data,
int start,
int end );
FX_ENTRY void FX_CALL
grTexDownloadTable( GrTexTable_t type,
void *data );
FX_ENTRY void FX_CALL
grTexDownloadTablePartial( GrTexTable_t type,
void *data,
int start,
int end );
FX_ENTRY void FX_CALL
grTexMipMapMode( GrChipID_t tmu,
GrMipMapMode_t mode,
FxBool lodBlend );
FX_ENTRY void FX_CALL
grTexMultibase( GrChipID_t tmu,
FxBool enable );
FX_ENTRY void FX_CALL
grTexMultibaseAddress( GrChipID_t tmu,
GrTexBaseRange_t range,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info );
/*
** linear frame buffer functions
*/
FX_ENTRY FxBool FX_CALL
grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
GrOriginLocation_t origin, FxBool pixelPipeline,
GrLfbInfo_t *info );
FX_ENTRY FxBool FX_CALL
grLfbUnlock( GrLock_t type, GrBuffer_t buffer );
FX_ENTRY void FX_CALL
grLfbConstantAlpha( GrAlpha_t alpha );
FX_ENTRY void FX_CALL
grLfbConstantDepth( FxU32 depth );
FX_ENTRY void FX_CALL
grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords);
FX_ENTRY void FX_CALL
grLfbWriteColorFormat(GrColorFormat_t colorFormat);
FX_ENTRY FxBool FX_CALL
grLfbWriteRegion( GrBuffer_t dst_buffer,
FxU32 dst_x, FxU32 dst_y,
GrLfbSrcFmt_t src_format,
FxU32 src_width, FxU32 src_height,
FxBool pixelPipeline,
FxI32 src_stride, void *src_data );
FX_ENTRY FxBool FX_CALL
grLfbReadRegion( GrBuffer_t src_buffer,
FxU32 src_x, FxU32 src_y,
FxU32 src_width, FxU32 src_height,
FxU32 dst_stride, void *dst_data );
/*
** glide management functions
*/
FX_ENTRY void FX_CALL
grGlideInit( void );
FX_ENTRY void FX_CALL
grGlideShutdown( void );
FX_ENTRY void FX_CALL
grGlideGetState( void *state );
FX_ENTRY void FX_CALL
grGlideSetState( const void *state );
FX_ENTRY void FX_CALL
grGlideGetVertexLayout( void *layout );
FX_ENTRY void FX_CALL
grGlideSetVertexLayout( const void *layout );
#endif /* FX_GLIDE_NO_FUNC_PROTO */
#ifdef __cplusplus
}
#endif
#include <glideutl.h>
#endif /* __GLIDE_H__ */

View File

@ -0,0 +1,162 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glidesys.h,v 1.3.4.3 2003/07/24 03:51:08 anholt Exp $
** $Log:
** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce
** branching.
** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the
** Napalm Glide open source release. Changes include cleaned up offensive
** comments and new legal headers.
** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator
** $
**
** 4 11/05/98 11:18a Russp
** Fix GLIDE_NUM_TMU error check (change "&&" to "||")
**
** 3 7/24/98 1:41p Hohn
**
** 2 6/15/98 10:50a Peter
** made csim compile time option
*
* 1 1/16/98 4:29p Atai
* create glide 3 src
*
* 10 12/09/97 12:20p Peter
* mac glide port
*
* 9 11/04/97 4:00p Dow
* Banshee Mods
*
* 8 8/18/97 3:52p Peter
* pre-hw arrival fixes/cleanup
*
* 7 6/02/97 4:09p Peter
* Compile w/ gcc for Dural
*
* 6 5/27/97 1:16p Peter
* Basic cvg, w/o cmd fifo stuff.
*
* 5 5/21/97 6:05a Peter
*/
#ifndef __GLIDESYS_H__
#define __GLIDESYS_H__
/*
n** -----------------------------------------------------------------------
** COMPILER/ENVIRONMENT CONFIGURATION
** -----------------------------------------------------------------------
*/
/* Endianness is stored in bits [30:31] */
#define GLIDE_ENDIAN_SHIFT 30
#define GLIDE_ENDIAN_LITTLE (0x1 << GLIDE_ENDIAN_SHIFT)
#define GLIDE_ENDIAN_BIG (0x2 << GLIDE_ENDIAN_SHIFT)
/* OS is stored in bits [0:6] */
#define GLIDE_OS_SHIFT 0
#define GLIDE_OS_UNIX 0x1
#define GLIDE_OS_DOS32 0x2
#define GLIDE_OS_WIN32 0x4
#define GLIDE_OS_MACOS 0x8
#define GLIDE_OS_OS2 0x10
#define GLIDE_OS_OTHER 0x40 /* For Proprietary Arcade HW */
/* Sim vs. Hardware is stored in bits [7:8] */
#define GLIDE_SST_SHIFT 7
#define GLIDE_SST_SIM (0x1 << GLIDE_SST_SHIFT)
#define GLIDE_SST_HW (0x2 << GLIDE_SST_SHIFT)
/* Hardware Type is stored in bits [9:13] */
#define GLIDE_HW_SHIFT 9
#define GLIDE_HW_SST1 (0x1 << GLIDE_HW_SHIFT)
#define GLIDE_HW_SST96 (0x2 << GLIDE_HW_SHIFT)
#define GLIDE_HW_H3 (0x4 << GLIDE_HW_SHIFT)
#define GLIDE_HW_SST2 (0x8 << GLIDE_HW_SHIFT)
#define GLIDE_HW_CVG (0x10 << GLIDE_HW_SHIFT)
/*
** Make sure we handle all instances of WIN32
*/
#ifndef __WIN32__
# if defined (_WIN32) || defined (WIN32) || defined(__NT__)
# define __WIN32__
# endif
#endif
/* We need two checks on the OS: one for endian, the other for OS */
/* Check for endianness */
#if defined(__IRIX__) || defined(__sparc__) || defined(MACOS)
# define GLIDE_ENDIAN GLIDE_ENDIAN_BIG
#else
# define GLIDE_ENDIAN GLIDE_ENDIAN_LITTLE
#endif
/* Check for OS */
#if defined(__IRIX__) || defined(__sparc__) || defined(__linux__) || \
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__GNU__)
# define GLIDE_OS GLIDE_OS_UNIX
#elif defined(__DOS__)
# define GLIDE_OS GLIDE_OS_DOS32
#elif defined(__WIN32__)
# define GLIDE_OS GLIDE_OS_WIN32
#elif defined(macintosh)
# define GLIDE_OS GLIDE_OS_MACOS
#else
#error "Unknown OS"
#endif
/* Check for Simulator vs. Hardware */
#if HAL_CSIM || HWC_CSIM
# define GLIDE_SST GLIDE_SST_SIM
#else
# define GLIDE_SST GLIDE_SST_HW
#endif
/* Check for type of hardware */
#ifdef SST96
# define GLIDE_HW GLIDE_HW_SST96
#elif defined(H3)
# define GLIDE_HW GLIDE_HW_H3
#elif defined(SST2)
# define GLIDE_HW GLIDE_HW_SST2
#elif defined(CVG)
# define GLIDE_HW GLIDE_HW_CVG
#else /* Default to SST1 */
# define GLIDE_HW GLIDE_HW_SST1
#endif
#define GLIDE_PLATFORM (GLIDE_ENDIAN | GLIDE_OS | GLIDE_SST | GLIDE_HW)
/*
** Control the number of TMUs
*/
#ifndef GLIDE_NUM_TMU
# define GLIDE_NUM_TMU 2
#endif
#if ((GLIDE_NUM_TMU < 0) || (GLIDE_NUM_TMU > 3))
# error "GLIDE_NUM_TMU set to an invalid value"
#endif
#endif /* __GLIDESYS_H__ */

View File

@ -0,0 +1,154 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glideutl.h,v 1.3.4.2 2003/06/05 08:23:53 koolsmoky Exp $
** $Log:
** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce
** branching.
** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the
** Napalm Glide open source release. Changes include cleaned up offensive
** comments and new legal headers.
** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator
** $
**
** 4 7/24/98 1:41p Hohn
**
** 3 1/30/98 4:27p Atai
** gufog* prototype
**
** 1 1/29/98 4:00p Atai
*
* 1 1/16/98 4:29p Atai
* create glide 3 src
*
* 11 1/07/98 11:18a Atai
* remove GrMipMapInfo and GrGC.mm_table in glide3
*
* 10 1/06/98 6:47p Atai
* undo grSplash and remove gu routines
*
* 9 1/05/98 6:04p Atai
* move 3df gu related data structure from glide.h to glideutl.h
*
* 8 12/18/97 2:13p Peter
* fogTable cataclysm
*
* 7 12/15/97 5:52p Atai
* disable obsolete glide2 api for glide3
*
* 6 8/14/97 5:32p Pgj
* remove dead code per GMT
*
* 5 6/12/97 5:19p Pgj
* Fix bug 578
*
* 4 3/05/97 9:36p Jdt
* Removed guFbWriteRegion added guEncodeRLE16
*
* 3 1/16/97 3:45p Dow
* Embedded fn protos in ifndef FX_GLIDE_NO_FUNC_PROTO
*/
/* Glide Utility routines */
#ifndef __GLIDEUTL_H__
#define __GLIDEUTL_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
** 3DF texture file structs
*/
typedef struct
{
FxU32 width, height;
int small_lod, large_lod;
GrAspectRatio_t aspect_ratio;
GrTextureFormat_t format;
} Gu3dfHeader;
typedef struct
{
FxU8 yRGB[16];
FxI16 iRGB[4][3];
FxI16 qRGB[4][3];
FxU32 packed_data[12];
} GuNccTable;
typedef struct {
FxU32 data[256];
} GuTexPalette;
typedef union {
GuNccTable nccTable;
GuTexPalette palette;
} GuTexTable;
typedef struct
{
Gu3dfHeader header;
GuTexTable table;
void *data;
FxU32 mem_required; /* memory required for mip map in bytes. */
} Gu3dfInfo;
#ifndef FX_GLIDE_NO_FUNC_PROTO
/*
** Gamma functions
*/
FX_ENTRY void FX_CALL
guGammaCorrectionRGB( FxFloat red, FxFloat green, FxFloat blue );
/*
** fog stuff
*/
FX_ENTRY float FX_CALL
guFogTableIndexToW( int i );
FX_ENTRY void FX_CALL
guFogGenerateExp( GrFog_t *fogtable, float density );
FX_ENTRY void FX_CALL
guFogGenerateExp2( GrFog_t *fogtable, float density );
FX_ENTRY void FX_CALL
guFogGenerateLinear(GrFog_t *fogtable,
float nearZ, float farZ );
/*
** hi-level texture manipulation tools.
*/
FX_ENTRY FxBool FX_CALL
gu3dfGetInfo( const char *filename, Gu3dfInfo *info );
FX_ENTRY FxBool FX_CALL
gu3dfLoad( const char *filename, Gu3dfInfo *data );
#endif /* FX_GLIDE_NO_FUNC_PROTO */
#ifdef __cplusplus
}
#endif
#endif /* __GLIDEUTL_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/main.h *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public 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 MAIN_H
#define MAIN_H
#include "../m64p.h"
#ifdef WIN32
#include <SDL_opengl.h>
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
extern PFNGLFOGCOORDFEXTPROC glFogCoordfEXT;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
extern PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
extern PFNGLUNIFORM1FARBPROC glUniform1fARB;
extern PFNGLUNIFORM1IARBPROC glUniform1iARB;
extern PFNGLUNIFORM4FARBPROC glUniform4fARB;
extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
#else
#define GL_GLEXT_PROTOTYPES
#include <SDL_opengl.h>
#endif
#include "../winlnxdefs.h"
#ifdef VPDEBUG
void dump_tex(int id);
void dump_start();
void dump_stop();
extern int dumping;
#endif
// VP z precision fix
// no more necessary, now using z clamping instead.
//#define zscale 0.025f
#define zscale 1.0f
//#define zscale 2.0f
//#define zscale 0.5f
// VP added this utility function
// returns the bytes per pixel of a given GR texture format
int grTexFormatSize(int fmt);
extern int packed_pixels_support;
extern int default_texture; // the infamous "32*1024*1024" is now configurable
extern int depth_texture;
void set_depth_shader();
void set_bw_shader();
extern float invtex[2];
extern int buffer_cleared; // mark that the buffer has been cleared, used to check if we need to reload the texture buffer content
#include "glide.h"
void display_warning(const unsigned char *text, ...);
void display_warning(const char *text, ...);
void init_geometry();
void init_textures();
void init_combiner();
void free_textures();
void updateCombiner(int i);
void updateCombinera(int i);
void remove_tex(unsigned int idmin, unsigned int idmax);
void add_tex(unsigned int id);
extern int w_buffer_mode;
extern GLint nbTextureUnits;
extern int width, height, widtho, heighto;
extern int tex0_width, tex0_height, tex1_width, tex1_height;
extern float texture_env_color[4];
extern int fog_enabled;
extern float lambda;
extern int need_lambda[2];
extern float lambda_color[2][4];
extern int inverted_culling;
extern int culling_mode;
extern int render_to_texture;
extern int lfb_color_fmt;
extern int need_to_compile;
extern int blackandwhite0;
extern int blackandwhite1;
extern int blend_func_separate_support;
extern int fog_coord_support;
//extern int pbuffer_support;
extern int glsl_support;
extern unsigned int pBufferAddress;
extern int viewport_width, viewport_height, viewport_offset;
void grChromaRangeExt(GrColor_t color0, GrColor_t color1, FxU32 mode);
void grChromaRangeModeExt(GrChromakeyMode_t mode);
void grTexChromaRangeExt(GrChipID_t tmu, GrColor_t color0, GrColor_t color1, GrTexChromakeyMode_t mode);
void grTexChromaModeExt(GrChipID_t tmu, GrChromakeyMode_t mode);
void updateTexture();
void reloadTexture();
void free_combiners();
void compile_shader();
void set_lambda();
void set_copy_shader();
// config functions
FX_ENTRY void FX_CALL grConfigWrapperExt(HINSTANCE instance, HWND hwnd);
FX_ENTRY GrScreenResolution_t FX_CALL grWrapperFullScreenResolutionExt(void);
int getFullScreenWidth();
int getFullScreenHeight();
int getFilter();
int getDisableGLSL();
// ZIGGY framebuffer copy extension
// allow to copy the depth or color buffer from back/front to front/back
#define GR_FBCOPY_MODE_DEPTH 0
#define GR_FBCOPY_MODE_COLOR 1
#define GR_FBCOPY_BUFFER_BACK 0
#define GR_FBCOPY_BUFFER_FRONT 1
FX_ENTRY void FX_CALL grFramebufferCopyExt(int x, int y, int w, int h,
int buffer_from, int buffer_to, int mode);
// COMBINE extension
typedef FxU32 GrCCUColor_t;
typedef FxU32 GrACUColor_t;
typedef FxU32 GrTCCUColor_t;
typedef FxU32 GrTACUColor_t;
typedef FxU32 GrCombineMode_t;
#define GR_FUNC_MODE_ZERO 0x00
#define GR_FUNC_MODE_X 0x01
#define GR_FUNC_MODE_ONE_MINUS_X 0x02
#define GR_FUNC_MODE_NEGATIVE_X 0x03
#define GR_FUNC_MODE_X_MINUS_HALF 0x04
#define GR_CMBX_ZERO 0x00
#define GR_CMBX_TEXTURE_ALPHA 0x01
#define GR_CMBX_ALOCAL 0x02
#define GR_CMBX_AOTHER 0x03
#define GR_CMBX_B 0x04
#define GR_CMBX_CONSTANT_ALPHA 0x05
#define GR_CMBX_CONSTANT_COLOR 0x06
#define GR_CMBX_DETAIL_FACTOR 0x07
#define GR_CMBX_ITALPHA 0x08
#define GR_CMBX_ITRGB 0x09
#define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a
#define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b
#define GR_CMBX_LOD_FRAC 0x0c
#define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d
#define GR_CMBX_OTHER_TEXTURE_RGB 0x0e
#define GR_CMBX_TEXTURE_RGB 0x0f
#define GR_CMBX_TMU_CALPHA 0x10
#define GR_CMBX_TMU_CCOLOR 0x11
FX_ENTRY void FX_CALL
grColorCombineExt(GrCCUColor_t a, GrCombineMode_t a_mode,
GrCCUColor_t b, GrCombineMode_t b_mode,
GrCCUColor_t c, FxBool c_invert,
GrCCUColor_t d, FxBool d_invert,
FxU32 shift, FxBool invert);
FX_ENTRY void FX_CALL
grAlphaCombineExt(GrACUColor_t a, GrCombineMode_t a_mode,
GrACUColor_t b, GrCombineMode_t b_mode,
GrACUColor_t c, FxBool c_invert,
GrACUColor_t d, FxBool d_invert,
FxU32 shift, FxBool invert);
FX_ENTRY void FX_CALL
grTexColorCombineExt(GrChipID_t tmu,
GrTCCUColor_t a, GrCombineMode_t a_mode,
GrTCCUColor_t b, GrCombineMode_t b_mode,
GrTCCUColor_t c, FxBool c_invert,
GrTCCUColor_t d, FxBool d_invert,
FxU32 shift, FxBool invert);
FX_ENTRY void FX_CALL
grTexAlphaCombineExt(GrChipID_t tmu,
GrTACUColor_t a, GrCombineMode_t a_mode,
GrTACUColor_t b, GrCombineMode_t b_mode,
GrTACUColor_t c, FxBool c_invert,
GrTACUColor_t d, FxBool d_invert,
FxU32 shift, FxBool invert);
FX_ENTRY void FX_CALL
grConstantColorValueExt(GrChipID_t tmu,
GrColor_t value);
#ifndef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
#endif
#define CHECK_FRAMEBUFFER_STATUS() \
{\
GLenum status; \
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); \
/*display_warning("%x\n", status);*/\
switch(status) { \
case GL_FRAMEBUFFER_COMPLETE_EXT: \
/*display_warning("framebuffer complete!\n");*/\
break; \
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: \
display_warning("framebuffer GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");\
/* you gotta choose different formats */ \
/*assert(0);*/ \
break; \
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: \
display_warning("framebuffer INCOMPLETE_ATTACHMENT\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: \
display_warning("framebuffer FRAMEBUFFER_MISSING_ATTACHMENT\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: \
display_warning("framebuffer FRAMEBUFFER_DIMENSIONS\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: \
display_warning("framebuffer INCOMPLETE_DUPLICATE_ATTACHMENT\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: \
display_warning("framebuffer INCOMPLETE_FORMATS\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: \
display_warning("framebuffer INCOMPLETE_DRAW_BUFFER\n");\
break; \
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: \
display_warning("framebuffer INCOMPLETE_READ_BUFFER\n");\
break; \
case GL_FRAMEBUFFER_BINDING_EXT: \
display_warning("framebuffer BINDING_EXT\n");\
break; \
default: \
break; \
/* programming error; will fail on all hardware */ \
/*assert(0);*/ \
}\
}
#ifdef VPDEBUG
#define LOGGING
#endif
#ifdef LOGGING
void OPEN_LOG();
void CLOSE_LOG();
void LOG(char *text, ...);
#else // LOGGING
#define OPEN_LOG()
#define CLOSE_LOG()
//#define LOG(...)
#endif // LOGGING
#endif

View File

@ -0,0 +1,149 @@
/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
**
** $Header: /cvsroot/glide/glide3x/h5/incsrc/sst1vid.h,v 1.3.4.1 2003/04/06 18:23:10 koolsmoky Exp $
** $Log:
** 7 3dfx 1.4.1.0.1.0 10/11/00 Brent Forced check in to enforce
** branching.
** 6 3dfx 1.4.1.0 06/20/00 Joseph Kain Changes to support the
** Napalm Glide open source release. Changes include cleaned up offensive
** comments and new legal headers.
** 5 3dfx 1.4 12/10/99 Leo Galway Removed previous hi-res
** mode information for Glide3. These modes were only necessary for
** Cornerstone (or future hi-res) support in RT4.2 source branch and
** proceeded to break the V3 and V2 builds (from 3dfx view), hence they have
** been removed.
** 4 3dfx 1.3 12/08/99 Leo Galway Added mode information for
** 1600x1280, 1792x1440, 1920x1080, 1920x1200, 2046x1536 (as a result of
** glide being tested with Cornerstone modes). Although not all of these
** modes are currently capable under Glide, their inclusion prevents Glide
** apps from displaying in incorrect modes when these hi-res modes are
** selected. Search for SUSTAINED_ENGINEERING_CHANGE_BEGIN.
** 3 3dfx 1.2 09/17/99 Jeremy Zelsnack
** 2 3dfx 1.1 09/17/99 Jeremy Zelsnack
** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator
** $
**
** 8 3/04/99 1:19p Atai
** sync new res modes
**
** 10 2/27/99 12:28p Dow
** new resolutions
**
** 6 2/13/99 1:56p Dow
** Added new resolution constants
**
** 5 7/24/98 1:38p Hohn
*
* 4 9/09/97 7:35p Sellers
* Added 400x300 resolution
*
* 3 8/24/97 9:31a Sellers
* moved new video timing to sst1vid.h
* redefined 1600x1280 to be 1600x1200
*
* 2 6/05/97 11:14p Pgj
*
* 5 7/24/96 3:43p Sellers
* added 512x384 @ 60 Hz for arcade monitors
* added 512x256 @ 60 Hz for arcade monitors
*
* 4 7/18/96 10:58a Sellers
* fixed FT and TF clock delay values for lower frequencies with
* .5/.5 combos
*
* 3 6/18/96 6:54p Sellers
* added sst1InitShutdownSli() to fix Glide Splash screen problems with
* SLI
*
* 2 6/13/96 7:45p Sellers
* added "voodoo.ini" support
* added DirectX support
* misc cleanup
*
* 2 6/11/96 1:43p Sellers
* added support for 60, 75, 85, and 120 Hz refresh rates for "most"
* resolutions
*
* 1 5/08/96 5:43p Paik
* Video definitions
*/
#ifndef __SST1VID_H__
#define __SST1VID_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Video defines */
typedef FxI32 GrScreenRefresh_t;
#define GR_REFRESH_60Hz 0x0
#define GR_REFRESH_70Hz 0x1
#define GR_REFRESH_72Hz 0x2
#define GR_REFRESH_75Hz 0x3
#define GR_REFRESH_80Hz 0x4
#define GR_REFRESH_90Hz 0x5
#define GR_REFRESH_100Hz 0x6
#define GR_REFRESH_85Hz 0x7
#define GR_REFRESH_120Hz 0x8
#define GR_REFRESH_NONE 0xff
typedef FxI32 GrScreenResolution_t;
#define GR_RESOLUTION_320x200 0x0
#define GR_RESOLUTION_320x240 0x1
#define GR_RESOLUTION_400x256 0x2
#define GR_RESOLUTION_512x384 0x3
#define GR_RESOLUTION_640x200 0x4
#define GR_RESOLUTION_640x350 0x5
#define GR_RESOLUTION_640x400 0x6
#define GR_RESOLUTION_640x480 0x7
#define GR_RESOLUTION_800x600 0x8
#define GR_RESOLUTION_960x720 0x9
#define GR_RESOLUTION_856x480 0xa
#define GR_RESOLUTION_512x256 0xb
#define GR_RESOLUTION_1024x768 0xC
#define GR_RESOLUTION_1280x1024 0xD
#define GR_RESOLUTION_1600x1200 0xE
#define GR_RESOLUTION_400x300 0xF
#define GR_RESOLUTION_1152x864 0x10
#define GR_RESOLUTION_1280x960 0x11
#define GR_RESOLUTION_1600x1024 0x12
#define GR_RESOLUTION_1792x1344 0x13
#define GR_RESOLUTION_1856x1392 0x14
#define GR_RESOLUTION_1920x1440 0x15
#define GR_RESOLUTION_2048x1536 0x16
#define GR_RESOLUTION_2048x2048 0x17
#define GR_RESOLUTION_NONE 0xff
#ifdef GR_RESOLUTION_MAX
#undef GR_RESOLUTION_MAX
#endif
#ifdef GR_RESOLUTION_MIN
#undef GR_RESOLUTION_MIN
#endif
#define GR_RESOLUTION_MIN GR_RESOLUTION_320x200
#define GR_RESOLUTION_MAX GR_RESOLUTION_2048x2048
#ifdef __cplusplus
}
#endif
#endif /* __SST1VID_H__ */

View File

@ -0,0 +1,810 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - glide64/wrapper/textures.cpp *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2005-2006 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdlib.h>
#include <stdio.h>
#include "glide.h"
#include "main.h"
extern BOOL isExtensionSupported(const char *extension); // defined in main.cpp
/* Napalm extensions to GrTextureFormat_t */
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
#define GR_TEXFMT_ARGB_8888 0x12
#define GR_TEXFMT_YUYV_422 0x13
#define GR_TEXFMT_UYVY_422 0x14
#define GR_TEXFMT_AYUV_444 0x15
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
#define GR_TEXFMT_ARGB_CMP_DXT2 0x17
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
#define GR_TEXFMT_ARGB_CMP_DXT4 0x19
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
#define GR_TEXTFMT_RGB_888 0xFF
#define TMU_SIZE 8*2048*2048
int tex0_width, tex0_height, tex1_width, tex1_height;
float lambda;
static int min_filter0, mag_filter0, wrap_s0, wrap_t0;
static int min_filter1, mag_filter1, wrap_s1, wrap_t1;
unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);
typedef struct _texlist
{
unsigned int id;
struct _texlist *next;
} texlist;
static int nbTex = 0;
static texlist *list = NULL;
void remove_tex(unsigned int idmin, unsigned int idmax)
{
GLuint *t;
int n = 0;
texlist *aux = list;
int sz = nbTex;
if (aux == NULL) return;
t = (GLuint*)malloc(sz * sizeof(int));
while (aux && aux->id >= idmin && aux->id < idmax)
{
if (n >= sz)
t = (GLuint*)realloc(t, ++sz*sizeof(int));
t[n++] = aux->id;
aux = aux->next;
free(list);
list = aux;
nbTex--;
}
while (aux != NULL && aux->next != NULL)
{
if (aux->next->id >= idmin && aux->next->id < idmax)
{
texlist *aux2 = aux->next->next;
if (n >= sz)
t = (GLuint*)realloc(t, ++sz*sizeof(int));
t[n++] = aux->next->id;
free(aux->next);
aux->next = aux2;
nbTex--;
}
aux = aux->next;
}
glDeleteTextures(n, t);
free(t);
//printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);
}
// void remove_all_tex()
// {
// texlist *aux = list;
// int sz = nbTex;
// if (aux == NULL) return;
// FILE * fp = fopen("toto.txt", "w");
// while (aux)
// {
// fprintf(fp, "%x\n", aux->id);
// fflush(fp);
// glDeleteTextures(1, &aux->id);
// fprintf(fp, "%x %x\n", aux, aux->next);
// fflush(fp);
// aux = aux->next;
// free(list);
// fprintf(fp, "plop\n");
// fflush(fp);
// list = aux;
// nbTex--;
// }
// fclose(fp);
// }
void add_tex(unsigned int id)
{
texlist *aux = list;
texlist *aux2;
//printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);
if (list == NULL || id < list->id)
{
nbTex++;
list = (texlist*)malloc(sizeof(texlist));
list->next = aux;
list->id = id;
return;
}
while (aux->next != NULL && aux->next->id < id) aux = aux->next;
// ZIGGY added this test so that add_tex now accept re-adding an existing texture
if (aux->next != NULL && aux->next->id == id) return;
nbTex++;
aux2 = aux->next;
aux->next = (texlist*)malloc(sizeof(texlist));
aux->next->id = id;
aux->next->next = aux2;
}
void init_textures()
{
tex0_width = tex0_height = tex1_width = tex1_height = 2;
// ZIGGY because free_textures isn't called (Pj64 doesn't like it), it's better
// to leave these so that they'll be reused (otherwise we have a memory leak)
// list = NULL;
// nbTex = 0;
}
void free_textures()
{
remove_tex(0x00000000, 0xFFFFFFFF);
}
FX_ENTRY FxU32 FX_CALL
grTexMinAddress( GrChipID_t tmu )
{
WriteLog(M64MSG_VERBOSE, "grTexMinAddress(%d)\r\n", tmu);
return tmu*TMU_SIZE;
}
FX_ENTRY FxU32 FX_CALL
grTexMaxAddress( GrChipID_t tmu )
{
WriteLog(M64MSG_VERBOSE, "grTexMaxAddress(%d)\r\n", tmu);
return tmu*TMU_SIZE + TMU_SIZE - 1;
}
FX_ENTRY FxU32 FX_CALL
grTexTextureMemRequired( FxU32 evenOdd,
GrTexInfo *info )
{
int width, height;
WriteLog(M64MSG_VERBOSE, "grTextureMemRequired(%d)\r\n", evenOdd);
if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");
if (info->aspectRatioLog2 < 0)
{
height = 1 << info->largeLodLog2;
width = height >> -info->aspectRatioLog2;
}
else
{
width = 1 << info->largeLodLog2;
height = width >> info->aspectRatioLog2;
}
switch(info->format)
{
case GR_TEXFMT_ALPHA_8:
case GR_TEXFMT_ALPHA_INTENSITY_44:
return width*height;
break;
case GR_TEXFMT_ARGB_1555:
case GR_TEXFMT_ARGB_4444:
case GR_TEXFMT_ALPHA_INTENSITY_88:
case GR_TEXFMT_RGB_565:
return width*height*2;
break;
case GR_TEXFMT_ARGB_8888:
return width*height*4;
break;
default:
display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);
}
return 0;
}
FX_ENTRY FxU32 FX_CALL
grTexCalcMemRequired(
GrLOD_t lodmin, GrLOD_t lodmax,
GrAspectRatio_t aspect, GrTextureFormat_t fmt)
{
int width, height;
WriteLog(M64MSG_VERBOSE, "grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);
if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");
if (aspect < 0)
{
height = 1 << lodmax;
width = height >> -aspect;
}
else
{
width = 1 << lodmax;
height = width >> aspect;
}
switch(fmt)
{
case GR_TEXFMT_ALPHA_8:
case GR_TEXFMT_ALPHA_INTENSITY_44:
return width*height;
break;
case GR_TEXFMT_ARGB_1555:
case GR_TEXFMT_ARGB_4444:
case GR_TEXFMT_ALPHA_INTENSITY_88:
case GR_TEXFMT_RGB_565:
return width*height*2;
break;
case GR_TEXFMT_ARGB_8888:
return width*height*4;
break;
default:
display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);
}
return 0;
}
int grTexFormatSize(int fmt)
{
int factor = -1;
switch(fmt) {
case GR_TEXFMT_ALPHA_8:
factor = 1;
break;
case GR_TEXFMT_ALPHA_INTENSITY_44:
factor = 1;
break;
case GR_TEXFMT_RGB_565:
factor = 2;
break;
case GR_TEXFMT_ARGB_1555:
factor = 2;
break;
case GR_TEXFMT_ALPHA_INTENSITY_88:
factor = 2;
break;
case GR_TEXFMT_ARGB_4444:
factor = 2;
break;
case GR_TEXFMT_ARGB_8888:
factor = 4;
break;
default:
display_warning("grTexFormatSize : unknown texture format: %x", fmt);
}
return factor;
}
int packed_pixels_support = -1;
int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)
{
int factor = -1;
switch(fmt) {
case GR_TEXFMT_ALPHA_8:
factor = 1;
*gltexfmt = GL_INTENSITY;
*glpixfmt = GL_LUMINANCE;
*glpackfmt = GL_UNSIGNED_BYTE;
break;
case GR_TEXFMT_ALPHA_INTENSITY_44:
return -1;
// factor = 1;
// gltexfmt = GL_LUMINANCE4_ALPHA4;
// glpixfmt = GL_LUMINANCE_ALPHA;
// glpackfmt = GL_UNSIGNED_BYTE;
break;
case GR_TEXFMT_RGB_565:
// trick, this format is only used actually for depth texture
// factor = 2;
// *gltexfmt = GL_DEPTH_COMPONENT;
// *glpixfmt = GL_DEPTH_COMPONENT;
// *glpackfmt = GL_UNSIGNED_SHORT;
// break;
// return -1;
factor = 2;
*gltexfmt = GL_RGB;
*glpixfmt = GL_RGB;
*glpackfmt = GL_UNSIGNED_SHORT_5_6_5;
break;
case GR_TEXFMT_ARGB_1555:
factor = 2;
*gltexfmt = GL_RGBA;
*glpixfmt = GL_BGRA;
*glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case GR_TEXFMT_ALPHA_INTENSITY_88:
factor = 2;
*gltexfmt = GL_LUMINANCE_ALPHA;
*glpixfmt = GL_LUMINANCE_ALPHA;
*glpackfmt = GL_UNSIGNED_BYTE;
break;
case GR_TEXFMT_ARGB_4444:
factor = 2;
*gltexfmt = GL_RGBA;
*glpixfmt = GL_BGRA;
*glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
break;
case GR_TEXFMT_ARGB_8888:
factor = 4;
*gltexfmt = GL_RGBA;
*glpixfmt = GL_BGRA;
*glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;
break;
default:
display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);
}
return factor;
}
FX_ENTRY void FX_CALL
grTexDownloadMipMap( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info )
{
int width, height, i, j;
unsigned char* texture = NULL;
unsigned char* filtered_texture = NULL;
int factor;
int glformat = GL_RGBA8;
int gltexfmt, glpixfmt, glpackfmt;
gltexfmt = glpixfmt = glpackfmt = 0;
WriteLog(M64MSG_VERBOSE, "grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");
if (info->aspectRatioLog2 < 0)
{
height = 1 << info->largeLodLog2;
width = height >> -info->aspectRatioLog2;
}
else
{
width = 1 << info->largeLodLog2;
height = width >> info->aspectRatioLog2;
}
if (packed_pixels_support < 0) {
if (isExtensionSupported("GL_EXT_packed_pixels") == FALSE)
packed_pixels_support = 0;
else
packed_pixels_support = 1;
}
if (!packed_pixels_support || getFilter())
factor = -1;
else
factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);
if (factor < 0) {
texture = (unsigned char*)malloc(width*height*4);
// VP fixed the texture conversions to be more accurate, also swapped
// the for i/j loops so that is is less likely to break the memory cache
switch(info->format)
{
case GR_TEXFMT_ALPHA_8:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
texture[i*width*4+j*4+0]= ((unsigned char*)info->data)[i*width+j];
texture[i*width*4+j*4+1]= ((unsigned char*)info->data)[i*width+j];
texture[i*width*4+j*4+2]= ((unsigned char*)info->data)[i*width+j];
texture[i*width*4+j*4+3]= ((unsigned char*)info->data)[i*width+j];
}
}
factor = 1;
glformat = GL_INTENSITY8;
break;
case GR_TEXFMT_ALPHA_INTENSITY_44:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
// VP fix : we want F --> FF and 0 --> 00
FxU32 a = ((unsigned char*)info->data)[i*width+j]&0xF0;
a = a | (a>>4);
texture[i*width*4+j*4+3]= a | (a>>4);
a = ((unsigned char*)info->data)[i*width+j]&0x0F;
a = a | (a<<4);
texture[i*width*4+j*4+0]= a;
texture[i*width*4+j*4+1]= a;
texture[i*width*4+j*4+2]= a;
}
}
factor = 1;
glformat = GL_LUMINANCE4_ALPHA4;
break;
case GR_TEXFMT_RGB_565:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
FxU32 a;
texture[i*width*4+j*4+3] = 0;
a = ((((unsigned short*)info->data)[i*width+j]>>11)&0x1F);
texture[i*width*4+j*4+0]=(a<<3) | (a>>2);
a = ((((unsigned short*)info->data)[i*width+j]>> 5)&0x3F);
texture[i*width*4+j*4+1]=(a<<2) | (a>>4);
a = ((((unsigned short*)info->data)[i*width+j]>> 0)&0x1F);
texture[i*width*4+j*4+2]=(a<<3) | (a>>2);
}
}
factor = 2;
break;
case GR_TEXFMT_ARGB_1555:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
FxU32 a;
texture[i*width*4+j*4+3]=(((unsigned short*)info->data)[i*width+j]>>15)!=0 ? 0xFF : 0;
a = ((((unsigned short*)info->data)[i*width+j]>>10)&0x1F);
texture[i*width*4+j*4+0]=(a<<3) | (a>>2);
a = ((((unsigned short*)info->data)[i*width+j]>> 5)&0x1F);
texture[i*width*4+j*4+1]=(a<<3) | (a>>2);
a = ((((unsigned short*)info->data)[i*width+j]>> 0)&0x1F);
texture[i*width*4+j*4+2]=(a<<3) | (a>>2);
}
}
factor = 2;
glformat = GL_RGB5_A1;
break;
case GR_TEXFMT_ALPHA_INTENSITY_88:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
texture[i*width*4+j*4+3]= ((unsigned char*)info->data)[i*width*2+j*2+1];
texture[i*width*4+j*4+0]= ((unsigned char*)info->data)[i*width*2+j*2];
texture[i*width*4+j*4+1]= ((unsigned char*)info->data)[i*width*2+j*2];
texture[i*width*4+j*4+2]= ((unsigned char*)info->data)[i*width*2+j*2];
}
}
factor = 2;
glformat = GL_LUMINANCE8_ALPHA8;
break;
case GR_TEXFMT_ARGB_4444:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
// VP fix : we want F --> FF and 0 --> 00
FxU32 a = ((((unsigned short*)info->data)[i*width+j]>>12));
texture[i*width*4+j*4+3]=a | (a<<4);
a = ((((unsigned short*)info->data)[i*width+j]>> 8)&0xF);
texture[i*width*4+j*4+0]=a | (a<<4);
a = ((((unsigned short*)info->data)[i*width+j]>> 4)&0xF);
texture[i*width*4+j*4+1]=a | (a<<4);
a = ((((unsigned short*)info->data)[i*width+j] )&0xF);
texture[i*width*4+j*4+2]=a | (a<<4);
}
}
factor = 2;
glformat = GL_RGBA4;
break;
case GR_TEXFMT_ARGB_8888:
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
texture[i*width*4+j*4+3]= ((unsigned char*)info->data)[i*width*4+j*4+3];
texture[i*width*4+j*4+0]= ((unsigned char*)info->data)[i*width*4+j*4+2];
texture[i*width*4+j*4+1]= ((unsigned char*)info->data)[i*width*4+j*4+1];
texture[i*width*4+j*4+2]= ((unsigned char*)info->data)[i*width*4+j*4+0];
}
}
factor = 4;
glformat = GL_RGBA8;
break;
default:
display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);
factor = 0;
}
}
if (nbTextureUnits <= 2)
glActiveTextureARB(GL_TEXTURE1_ARB);
else
glActiveTextureARB(GL_TEXTURE2_ARB);
remove_tex(startAddress+1, startAddress+1+width*height*factor);
add_tex(startAddress+1);
glBindTexture(GL_TEXTURE_2D, startAddress+1);
if (texture != NULL) {
if (getFilter() == 0) {
glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
} else
{
int width2, height2;
filtered_texture = filter(texture, width, height, &width2, &height2);
glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, filtered_texture);
}
} else {
glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);
// if (info->format == GR_TEXFMT_RGB_565) {
// GLint ifmt;
// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &ifmt);
// LOG("dltex (%06x) %3dx%3d format %x --> %x\n", startAddress, width, height, info->format, ifmt);
// printf("dltex (%06x) %3dx%3d format %x --> %x\n", startAddress, width, height, info->format, ifmt);
// }
}
glBindTexture(GL_TEXTURE_2D, default_texture);
if (texture) free(texture);
if (filtered_texture) free(filtered_texture);
}
int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );
FX_ENTRY void FX_CALL
grTexSource( GrChipID_t tmu,
FxU32 startAddress,
FxU32 evenOdd,
GrTexInfo *info )
{
WriteLog(M64MSG_VERBOSE, "grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);
//if ((startAddress+1) == pBufferAddress && render_to_texture) updateTexture();
//if ((startAddress+1) == pBufferAddress) display_warning("texsource");
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
{
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
glActiveTextureARB(GL_TEXTURE0_ARB);
if (info->aspectRatioLog2 < 0)
{
tex0_height = 256;
tex0_width = tex0_height >> -info->aspectRatioLog2;
}
else
{
tex0_width = 256;
tex0_height = tex0_width >> info->aspectRatioLog2;
}
glBindTexture(GL_TEXTURE_2D, startAddress+1);
#ifdef VPDEBUG
dump_tex(startAddress+1);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
if(!glsl_support)
{
if (need_lambda[0])
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, lambda_color[0]);
else
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color);
updateCombiner(0);
updateCombinera(0);
}
//printf("grTexSource %x %dx%d fmt %x\n", startAddress+1, tex0_width, tex0_height, info->format);
}
else
{
glActiveTextureARB(GL_TEXTURE1_ARB);
if (info->aspectRatioLog2 < 0)
{
tex1_height = 256;
tex1_width = tex1_height >> -info->aspectRatioLog2;
}
else
{
tex1_width = 256;
tex1_height = tex1_width >> info->aspectRatioLog2;
}
glBindTexture(GL_TEXTURE_2D, startAddress+1);
#ifdef VPDEBUG
dump_tex(startAddress+1);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
if(!glsl_support)
{
if (need_lambda[1])
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, lambda_color[1]);
else
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color);
updateCombiner(1);
updateCombinera(1);
}
//printf("grTexSource %x %dx%d fmt %x\n", startAddress+1, tex1_width, tex1_height, info->format);
}
if(!CheckTextureBufferFormat(tmu, startAddress+1, info))
{
if(tmu == 0 && blackandwhite1 != 0)
{
blackandwhite1 = 0;
need_to_compile = 1;
}
if(tmu == 1 && blackandwhite0 != 0)
{
blackandwhite0 = 0;
need_to_compile = 1;
}
}
}
FX_ENTRY void FX_CALL
grTexDetailControl(
GrChipID_t tmu,
int lod_bias,
FxU8 detail_scale,
float detail_max
)
{
WriteLog(M64MSG_VERBOSE, "grTexDetailControl(%d,%d,%d,%f)\r\n", tmu, lod_bias, detail_scale, detail_max);
if (lod_bias != 31 && detail_scale != 7)
{
if (!lod_bias && !detail_scale && !detail_max) return;
else
display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);
}
lambda = detail_max;
if(lambda > 1.0f)
{
lambda = 1.0f - (255.0f - lambda);
}
if(lambda > 1.0f) display_warning("lambda:%f", lambda);
if(!glsl_support)
{
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
{
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
if (need_lambda[0])
{
int i;
glActiveTextureARB(GL_TEXTURE0_ARB);
for (i=0; i<3; i++) lambda_color[0][i] = texture_env_color[i];
lambda_color[0][3] = lambda;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, lambda_color[0]);
}
}
else
{
if (need_lambda[1])
{
int i;
glActiveTextureARB(GL_TEXTURE1_ARB);
for (i=0; i<3; i++) lambda_color[1][i] = texture_env_color[i];
lambda_color[1][3] = lambda;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, lambda_color[1]);
}
}
}
else
set_lambda();
}
FX_ENTRY void FX_CALL
grTexLodBiasValue(GrChipID_t tmu, float bias )
{
WriteLog(M64MSG_VERBOSE, "grTexLodBiasValue(%d,%f)\r\n", tmu, bias);
/*if (bias != 0 && bias != 1.0f)
display_warning("grTexLodBiasValue : %f", bias);*/
}
FX_ENTRY void FX_CALL
grTexFilterMode(
GrChipID_t tmu,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode
)
{
WriteLog(M64MSG_VERBOSE, "grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
{
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;
else min_filter0 = GL_LINEAR;
if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;
else mag_filter0 = GL_LINEAR;
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);
}
else
{
if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;
else min_filter1 = GL_LINEAR;
if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;
else mag_filter1 = GL_LINEAR;
glActiveTextureARB(GL_TEXTURE1_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);
}
}
FX_ENTRY void FX_CALL
grTexClampMode(
GrChipID_t tmu,
GrTextureClampMode_t s_clampmode,
GrTextureClampMode_t t_clampmode
)
{
WriteLog(M64MSG_VERBOSE, "grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);
if (tmu == GR_TMU1 || nbTextureUnits <= 2)
{
if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;
switch(s_clampmode)
{
case GR_TEXTURECLAMP_WRAP:
wrap_s0 = GL_REPEAT;
break;
case GR_TEXTURECLAMP_CLAMP:
wrap_s0 = GL_CLAMP_TO_EDGE;
break;
case GR_TEXTURECLAMP_MIRROR_EXT:
wrap_s0 = GL_MIRRORED_REPEAT_ARB;
break;
default:
display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
}
switch(t_clampmode)
{
case GR_TEXTURECLAMP_WRAP:
wrap_t0 = GL_REPEAT;
break;
case GR_TEXTURECLAMP_CLAMP:
wrap_t0 = GL_CLAMP_TO_EDGE;
break;
case GR_TEXTURECLAMP_MIRROR_EXT:
wrap_t0 = GL_MIRRORED_REPEAT_ARB;
break;
default:
display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);
}
else
{
switch(s_clampmode)
{
case GR_TEXTURECLAMP_WRAP:
wrap_s1 = GL_REPEAT;
break;
case GR_TEXTURECLAMP_CLAMP:
wrap_s1 = GL_CLAMP_TO_EDGE;
break;
case GR_TEXTURECLAMP_MIRROR_EXT:
wrap_s1 = GL_MIRRORED_REPEAT_ARB;
break;
default:
display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);
}
switch(t_clampmode)
{
case GR_TEXTURECLAMP_WRAP:
wrap_t1 = GL_REPEAT;
break;
case GR_TEXTURECLAMP_CLAMP:
wrap_t1 = GL_CLAMP_TO_EDGE;
break;
case GR_TEXTURECLAMP_MIRROR_EXT:
wrap_t1 = GL_MIRRORED_REPEAT_ARB;
break;
default:
display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);
}
glActiveTextureARB(GL_TEXTURE1_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);
}
}