m64p: Committing a clone of the glide64mk2 2.0 repo
This commit is contained in:
parent
8a2b008a11
commit
01b92f46ca
|
@ -0,0 +1,26 @@
|
|||
Mupen64Plus-Video-Glide64mk2 INSTALL
|
||||
------------------------------------
|
||||
|
||||
This text file was written to explain the installation process of the
|
||||
Mupen64Plus-Video-Glide64mk2 module.
|
||||
|
||||
If this module is part of a Mupen64Plus source code bundle, the user should run
|
||||
the "m64p_install.sh" script in the root of the unzipped bundle to install all
|
||||
of the included modules in the bundle.
|
||||
|
||||
If this module is a standalone source code release, you should build the library
|
||||
from source code and install it via the makefile, like this:
|
||||
|
||||
$ cd projects/unix
|
||||
$ make all
|
||||
$ sudo make install
|
||||
|
||||
If you want to build the Mupen64Plus-Video-Glide64mk2 module for installation in a
|
||||
home folder for a single user, you may build it like this (replacing
|
||||
<my-folder> with your desired local installation path):
|
||||
|
||||
$ cd projects/unix
|
||||
$ make all
|
||||
$ make install LIBDIR=<my-folder> SHAREDIR=<my-folder>
|
||||
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
Mupen64Plus-video-glide64mk2 LICENSE
|
||||
------------------------------------
|
||||
|
||||
Mupen64Plus-video-glide64mk2 is licensed under the GNU General Public License version 2.
|
||||
|
||||
The authors of Mupen64Plus-video-glide64mk2 are:
|
||||
* Sven Eckelmann
|
||||
* Wahrhaft
|
||||
* Riley Labrecque
|
||||
* and others.
|
||||
|
||||
Mupen64Plus-video-glide64mk2 is based on the 10th anniversary release of the Glide64
|
||||
plugin, which is GPL-licensed and was originally written by Gonetz and others.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, 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
|
||||
|
||||
|
||||
Appendix: 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
Mupen64Plus-Video-Glide64mk2 RELEASE
|
||||
-------------------------------------
|
||||
|
||||
Mupen64Plus-Video-Glide64mk2 v2.0 - July 4, 2013
|
||||
------------------------------------------------
|
||||
- lots of bug fixing and cleanup
|
||||
- remove wxwidgets dependencies
|
||||
- ported old 32-bit x86 assembly language code to C for other platforms/CPUs
|
||||
- add Visual Studio 2012 project files
|
||||
- convert to Mupen64Plus build system and API
|
||||
- merged wahrhaft's Glide64 and Glitch64 changes from earlier porting effort
|
||||
- ported later changes from Mudlord's repository
|
||||
- add initial source code from Gonetz's google code repo "10th anniversary Glide64 release"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,244 @@
|
|||
3DFX FXT1 Source Code General Public License
|
||||
|
||||
|
||||
1. PREAMBLE
|
||||
|
||||
This license is for software that provides texture compression and
|
||||
decompression, particularly in the context of video games. 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 FXT1 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 FXT1 Source Code General
|
||||
Public License.
|
||||
|
||||
2.2 The term "Program" as used in this Agreement refers to 3DFX's
|
||||
FXT1 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 texture compression and decompression. 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 FXT1 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) 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) 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. SEE THE 3DFX FXT1 GENERAL PUBLIC LICENSE
|
||||
FOR A FULL TEXT OF THE DISTRIBUTION AND NON-WARRANTY PROVISIONS
|
||||
(REQUEST COPY FROM INFO@3DFX.COM)."
|
||||
|
||||
(g) 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 FXT1 GENERAL PUBLIC LICENSE. 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 FXT1 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 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.
|
||||
|
|
@ -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.
|
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{A4D13408-A794-4199-8FC7-4A9A32505005}</ProjectGuid>
|
||||
<RootNamespace>n64Glide</RootNamespace>
|
||||
<ProjectName>mupen64plus-video-glide64mk2</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
|
||||
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">F:\Code\Third Party\boost;$(IncludePath)</IncludePath>
|
||||
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">F:\Code\Third Party\boost\stage\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\Debug/n64Glide.tlb</TypeLibraryName>
|
||||
<HeaderFileName>
|
||||
</HeaderFileName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeaderOutputFile>.\Debug/n64Glide.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>opengl32.lib;glu32.lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib\libpng.lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib\zlib.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\lib;..\..\..\mupen64plus-win32-deps\boost-1.53.0\boost\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\Debug/Glide64.pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>.\Debug/Glide64.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug/n64Glide.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\Release/n64Glide.tlb</TypeLibraryName>
|
||||
<HeaderFileName>
|
||||
</HeaderFileName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<AdditionalIncludeDirectories>..\..\..\mupen64plus-win32-deps\boost-1.53.0\;..\..\..\mupen64plus-core\src\api;..\..\src\Glide64;..\..\src\Glide64\inc;..\..\src\GlideHQ;..\..\src\GlideHQ\tc-1.1+;..\..\src\Glitch64;..\..\src\Glitch64\inc;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_VARIADIC_MAX=10;_CRT_SECURE_NO_WARNINGS;__MSC__;WIN32;__VISUALC__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<PrecompiledHeaderOutputFile>.\Release/n64Glide.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>SDL.lib;zlib.lib;libpng.lib;opengl32.lib;winmm.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;msvcrt.lib;LIBCMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\..\..\mupen64plus-win32-deps\boost-1.53.0\boost\libs;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\lib;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\lib;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>
|
||||
</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release/n64Glide.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<MASM>
|
||||
<EnableMASM51Compatibility>true</EnableMASM51Compatibility>
|
||||
</MASM>
|
||||
<PostBuildEvent>
|
||||
<Message>Copying shared data and libraries to build directory...</Message>
|
||||
<Command>copy ..\..\data\* "$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\Glide64\3dmath.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Combine.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Config.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\CRC.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Debugger.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\DepthBufferRender.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\FBtoScreen.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Ini.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Keys.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Main.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\osal_dynamiclib_win32.c" />
|
||||
<ClCompile Include="..\..\src\Glide64\rdp.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\TexBuffer.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\TexCache.cpp" />
|
||||
<ClCompile Include="..\..\src\Glide64\Util.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\Ext_TxFilter.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\tc-1.1+\dxtn.c" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\tc-1.1+\fxt1.c" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\tc-1.1+\texstore.c" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\tc-1.1+\wrapper.c" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TextureFilters.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TextureFilters_2xsai.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TextureFilters_hq2x.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TextureFilters_hq4x.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxCache.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxDbg.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxFilter.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxFilterExport.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxHiResCache.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxImage.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxQuantize.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxReSample.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxTexCache.cpp" />
|
||||
<ClCompile Include="..\..\src\GlideHQ\TxUtil.cpp" />
|
||||
<ClCompile Include="..\..\src\Glitch64\combiner.cpp" />
|
||||
<ClCompile Include="..\..\src\Glitch64\geometry.cpp" />
|
||||
<ClCompile Include="..\..\src\Glitch64\glitchmain.cpp">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release/%(Filename)1.obj</ObjectFileName>
|
||||
<XMLDocumentationFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)1.xdc</XMLDocumentationFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Glitch64\textures.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
|
@ -0,0 +1,458 @@
|
|||
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
# * Mupen64plus-video-glide64mk2 - 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 Glide64mk2 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
|
||||
BOOST_SUFFIX = -mt
|
||||
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
|
||||
BOOST_SUFFIX = -mt
|
||||
CPPFLAGS += -DNO_FILTER_THREAD
|
||||
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 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 -flto
|
||||
WARNFLAGS ?= -Wall
|
||||
CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src -I../../src/Glitch64/inc -DGCC
|
||||
CXXFLAGS += -fvisibility-inlines-hidden -std=gnu++0x
|
||||
LDFLAGS += $(SHARED)
|
||||
BOOST_SUFFIX ?=
|
||||
|
||||
ifeq ($(CPU), X86)
|
||||
CFLAGS += -mmmx -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
|
||||
else
|
||||
CFLAGS += -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 += -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
|
||||
|
||||
CXXFLAGS += -std=c++11 -stdlib=libc++
|
||||
ifeq ($(CPU), X86)
|
||||
LDFLAGS += -bundle -L/opt/local/lib
|
||||
LDLIBS += -ldl
|
||||
ifeq ($(ARCH_DETECTED), 64BITS)
|
||||
CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
|
||||
else
|
||||
CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OS), FREEBSD)
|
||||
LDLIBS += -lc
|
||||
endif
|
||||
|
||||
ifeq ($(origin PKG_CONFIG), undefined)
|
||||
PKG_CONFIG = $(CROSS_COMPILE)pkg-config
|
||||
ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
|
||||
$(error $(PKG_CONFIG) not found)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), OSX) # use system zlib on OSX
|
||||
ZLIB_LDLIBS += -lz
|
||||
endif
|
||||
|
||||
ifeq ($(origin ZLIB_CFLAGS) $(origin ZLIB_LDLIBS), undefined undefined)
|
||||
ifeq ($(shell $(PKG_CONFIG) --modversion zlib 2>/dev/null),)
|
||||
$(error No zlib development libraries found!)
|
||||
endif
|
||||
ZLIB_CFLAGS += $(shell $(PKG_CONFIG) --cflags zlib)
|
||||
ZLIB_LDLIBS += $(shell $(PKG_CONFIG) --libs zlib)
|
||||
endif
|
||||
CFLAGS += $(ZLIB_CFLAGS)
|
||||
LDLIBS += $(ZLIB_LDLIBS)
|
||||
|
||||
ifeq ($(origin LIBPNG_CFLAGS) $(origin LIBPNG_LDLIBS), undefined undefined)
|
||||
ifeq ($(shell $(PKG_CONFIG) --modversion libpng 2>/dev/null),)
|
||||
$(error No libpng development libraries found!)
|
||||
endif
|
||||
LIBPNG_CFLAGS += $(shell $(PKG_CONFIG) --cflags libpng)
|
||||
LIBPNG_LDLIBS += $(shell $(PKG_CONFIG) --libs libpng)
|
||||
endif
|
||||
CFLAGS += $(LIBPNG_CFLAGS)
|
||||
LDLIBS += $(LIBPNG_LDLIBS)
|
||||
|
||||
|
||||
# search for OpenGL libraries
|
||||
ifeq ($(OS), OSX)
|
||||
GL_LDLIBS = -framework OpenGL
|
||||
endif
|
||||
ifeq ($(OS), MINGW)
|
||||
GL_LDLIBS = -lopengl32
|
||||
endif
|
||||
ifeq ($(origin GL_CFLAGS) $(origin GL_LDLIBS), undefined undefined)
|
||||
ifeq ($(shell $(PKG_CONFIG) --modversion gl 2>/dev/null),)
|
||||
$(error No OpenGL development libraries found!)
|
||||
endif
|
||||
GL_CFLAGS += $(shell $(PKG_CONFIG) --cflags gl)
|
||||
GL_LDLIBS += $(shell $(PKG_CONFIG) --libs gl)
|
||||
endif
|
||||
CFLAGS += $(GL_CFLAGS)
|
||||
LDLIBS += $(GL_LDLIBS)
|
||||
|
||||
# test for presence of SDL
|
||||
ifeq ($(origin SDL_CFLAGS) $(origin SDL_LDLIBS), undefined undefined)
|
||||
SDL_CONFIG = $(CROSS_COMPILE)sdl-config
|
||||
ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),)
|
||||
$(error No SDL development libraries found!)
|
||||
endif
|
||||
ifeq ($(OS),OSX)
|
||||
SDL_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
|
||||
SDL_LDLIBS += -L/usr/local/lib -lSDL -Wl,-framework,Cocoa
|
||||
else
|
||||
SDL_CFLAGS += $(shell $(SDL_CONFIG) --cflags)
|
||||
SDL_LDLIBS += $(shell $(SDL_CONFIG) --libs)
|
||||
endif
|
||||
endif
|
||||
CFLAGS += $(SDL_CFLAGS)
|
||||
LDLIBS += $(SDL_LDLIBS)
|
||||
|
||||
ifneq ($(OS), MINGW)
|
||||
CPPFLAGS += -D__unix__
|
||||
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) $(CXXFLAGS) $(LDFLAGS) $(TARGET_ARCH)
|
||||
|
||||
# set special flags for given Makefile parameters
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -g
|
||||
INSTALL_STRIP_FLAG ?=
|
||||
else
|
||||
ifneq ($(OS),OSX)
|
||||
INSTALL_STRIP_FLAG ?= -s
|
||||
endif
|
||||
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)/Glitch64/combiner.cpp \
|
||||
$(SRCDIR)/Glitch64/geometry.cpp \
|
||||
$(SRCDIR)/Glitch64/glitchmain.cpp \
|
||||
$(SRCDIR)/Glitch64/textures.cpp \
|
||||
$(SRCDIR)/Glide64/3dmath.cpp \
|
||||
$(SRCDIR)/Glide64/Combine.cpp \
|
||||
$(SRCDIR)/Glide64/Config.cpp \
|
||||
$(SRCDIR)/Glide64/CRC.cpp \
|
||||
$(SRCDIR)/Glide64/Debugger.cpp \
|
||||
$(SRCDIR)/Glide64/DepthBufferRender.cpp \
|
||||
$(SRCDIR)/Glide64/FBtoScreen.cpp \
|
||||
$(SRCDIR)/Glide64/Ini.cpp \
|
||||
$(SRCDIR)/Glide64/Keys.cpp \
|
||||
$(SRCDIR)/Glide64/Main.cpp \
|
||||
$(SRCDIR)/Glide64/rdp.cpp \
|
||||
$(SRCDIR)/Glide64/TexBuffer.cpp \
|
||||
$(SRCDIR)/Glide64/TexCache.cpp \
|
||||
$(SRCDIR)/Glide64/Util.cpp
|
||||
|
||||
ifneq ($(HIRES), 0)
|
||||
SOURCE += \
|
||||
$(SRCDIR)/GlideHQ/Ext_TxFilter.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxFilterExport.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxFilter.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxCache.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxTexCache.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxHiResCache.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxQuantize.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxUtil.cpp \
|
||||
$(SRCDIR)/GlideHQ/TextureFilters.cpp \
|
||||
$(SRCDIR)/GlideHQ/TextureFilters_2xsai.cpp \
|
||||
$(SRCDIR)/GlideHQ/TextureFilters_hq2x.cpp \
|
||||
$(SRCDIR)/GlideHQ/TextureFilters_hq4x.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxImage.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxReSample.cpp \
|
||||
$(SRCDIR)/GlideHQ/TxDbg.cpp \
|
||||
$(SRCDIR)/GlideHQ/tc-1.1+/fxt1.c \
|
||||
$(SRCDIR)/GlideHQ/tc-1.1+/dxtn.c \
|
||||
$(SRCDIR)/GlideHQ/tc-1.1+/wrapper.c \
|
||||
$(SRCDIR)/GlideHQ/tc-1.1+/texstore.c
|
||||
|
||||
CPPFLAGS += -DTEXTURE_FILTER # -DDUMP_CACHE
|
||||
LDLIBS += -lboost_filesystem$(BOOST_SUFFIX) -lboost_system$(BOOST_SUFFIX)
|
||||
endif
|
||||
|
||||
ifeq ($(OS),MINGW)
|
||||
SOURCE += $(SRCDIR)/Glide64/osal_dynamiclib_win32.c
|
||||
else
|
||||
SOURCE += $(SRCDIR)/Glide64/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-glide64mk2$(POSTFIX).$(SO_EXTENSION)
|
||||
|
||||
targets:
|
||||
@echo "Mupen64plus-video-glide64mk2 N64 Graphics plugin makefile. "
|
||||
@echo " Targets:"
|
||||
@echo " all == Build Mupen64plus-video-glide64mk2 plugin"
|
||||
@echo " clean == remove object files"
|
||||
@echo " rebuild == clean and re-build all"
|
||||
@echo " install == Install Mupen64Plus-video-glide64mk2 plugin"
|
||||
@echo " uninstall == Uninstall Mupen64Plus-video-glide64mk2 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 -flto)"
|
||||
@echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)"
|
||||
@echo " PIC=(1|0) == Force enable/disable of position independent code"
|
||||
@echo " POSTFIX=name == String added to the name of the the build (default: '')"
|
||||
@echo " HIRES=(1|0) == Enables/Disables support for hires textures and texture filters (default: 1)"
|
||||
@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 " 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/Glide64mk2.ini" "$(DESTDIR)$(SHAREDIR)"
|
||||
|
||||
uninstall:
|
||||
$(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
|
||||
$(RM) "$(DESTDIR)$(SHAREDIR)/Glide64mk2.ini"
|
||||
|
||||
clean:
|
||||
$(RM) -r $(OBJDIR) $(TARGET)
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
# build dependency files
|
||||
CFLAGS += -MD
|
||||
-include $(OBJECTS:.o=.d)
|
||||
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
|
||||
# standard build rules
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||
$(COMPILE.c) -o $@ $<
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(COMPILE.cc) -o $@ $<
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
|
||||
.PHONY: all clean install uninstall targets
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#include "Gfx_1.3.h"
|
||||
extern "C" {
|
||||
#ifndef NOSSE
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <math.h>
|
||||
#include "3dmath.h"
|
||||
|
||||
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 (wxUint32 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 = (wxUint8)(color[0]*255.0f);
|
||||
v->g = (wxUint8)(color[1]*255.0f);
|
||||
v->b = (wxUint8)(color[2]*255.0f);
|
||||
}
|
||||
|
||||
//*
|
||||
void calc_linear (VERTEX *v)
|
||||
{
|
||||
if (settings.force_calc_sphere)
|
||||
{
|
||||
calc_sphere(v);
|
||||
return;
|
||||
}
|
||||
DECLAREALIGN16VAR(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 (x > 1.0f)
|
||||
x = 1.0f;
|
||||
else if (x < -1.0f)
|
||||
x = -1.0f;
|
||||
if (y > 1.0f)
|
||||
y = 1.0f;
|
||||
else if (y < -1.0f)
|
||||
y = -1.0f;
|
||||
|
||||
if (rdp.cur_cache[0])
|
||||
{
|
||||
// scale >> 6 is size to map to
|
||||
v->ou = (acosf(x)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_s_scale >> 6);
|
||||
v->ov = (acosf(y)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_t_scale >> 6);
|
||||
}
|
||||
v->uv_scaled = 1;
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP ("calc linear u: %f, v: %f\n", v->ou, v->ov);
|
||||
#endif
|
||||
}
|
||||
|
||||
void calc_sphere (VERTEX *v)
|
||||
{
|
||||
// LRDP("calc_sphere\n");
|
||||
DECLAREALIGN16VAR(vec[3]);
|
||||
int s_scale, t_scale;
|
||||
if (settings.hacks&hack_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, y;
|
||||
if (!rdp.use_lookat)
|
||||
{
|
||||
x = vec[0];
|
||||
y = vec[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
x = DotProduct (rdp.lookat[0], vec);
|
||||
y = DotProduct (rdp.lookat[1], vec);
|
||||
}
|
||||
v->ou = (x * 0.5f + 0.5f) * s_scale;
|
||||
v->ov = (y * 0.5f + 0.5f) * t_scale;
|
||||
v->uv_scaled = 1;
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP ("calc sphere u: %f, v: %f\n", v->ou, v->ov);
|
||||
#endif
|
||||
}
|
||||
|
||||
float DotProductC(register float *v1, register float *v2)
|
||||
{
|
||||
register float result;
|
||||
result = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
return(result);
|
||||
}
|
||||
|
||||
void NormalizeVectorC(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;
|
||||
}
|
||||
}
|
||||
|
||||
void TransformVectorC(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 InverseTransformVectorC (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 MulMatricesC(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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2008.03.29 H.Morii - added SSE 3DNOW! 3x3 1x3 matrix multiplication
|
||||
// and 3DNOW! 4x4 4x4 matrix multiplication
|
||||
// 2011-01-03 Balrog - removed because is in NASM format and not 64-bit compatible
|
||||
// This will need fixing.
|
||||
MULMATRIX MulMatrices = MulMatricesC;
|
||||
TRANSFORMVECTOR TransformVector = TransformVectorC;
|
||||
TRANSFORMVECTOR InverseTransformVector = InverseTransformVectorC;
|
||||
DOTPRODUCT DotProduct = DotProductC;
|
||||
NORMALIZEVECTOR NormalizeVector = NormalizeVectorC;
|
||||
|
||||
void MulMatricesSSE(float m1[4][4],float m2[4][4],float r[4][4])
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(NO_ASM) && !defined(NOSSE)
|
||||
/* [row][col]*/
|
||||
typedef float v4sf __attribute__ ((vector_size (16)));
|
||||
v4sf row0 = _mm_loadu_ps(m2[0]);
|
||||
v4sf row1 = _mm_loadu_ps(m2[1]);
|
||||
v4sf row2 = _mm_loadu_ps(m2[2]);
|
||||
v4sf row3 = _mm_loadu_ps(m2[3]);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
v4sf leftrow = _mm_loadu_ps(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) && !defined(NOSSE)
|
||||
__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
|
||||
}
|
||||
|
||||
|
||||
|
||||
void math_init()
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
int IsSSE = FALSE;
|
||||
#if defined(__GNUC__) && !defined(NO_ASM) && !defined(NOSSE)
|
||||
int edx, eax;
|
||||
GLIDE64_TRY
|
||||
{
|
||||
#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
|
||||
}
|
||||
GLIDE64_CATCH
|
||||
{ return; }
|
||||
// Check for SSE
|
||||
if (edx & (1 << 25))
|
||||
IsSSE = TRUE;
|
||||
#elif !defined(NO_ASM) && !defined(NOSSE)
|
||||
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;
|
||||
LOG("3DNOW! detected.\n");
|
||||
}
|
||||
|
||||
#endif //_DEBUG
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
void calc_light (VERTEX *v);
|
||||
void calc_linear (VERTEX *v);
|
||||
void calc_sphere (VERTEX *v);
|
||||
|
||||
void math_init();
|
||||
|
||||
typedef void (*MULMATRIX)(float m1[4][4],float m2[4][4],float r[4][4]);
|
||||
extern MULMATRIX MulMatrices;
|
||||
typedef void (*TRANSFORMVECTOR)(float *src,float *dst,float mat[4][4]);
|
||||
extern TRANSFORMVECTOR TransformVector;
|
||||
extern TRANSFORMVECTOR InverseTransformVector;
|
||||
typedef float (*DOTPRODUCT)(register float *v1, register float *v2);
|
||||
extern DOTPRODUCT DotProduct;
|
||||
typedef void (*NORMALIZEVECTOR)(float *v);
|
||||
extern NORMALIZEVECTOR NormalizeVector;
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// CRC32 calculation functions
|
||||
//
|
||||
// Created by Gonetz, 2004
|
||||
//
|
||||
//****************************************************************
|
||||
//*
|
||||
#define CRC32_POLYNOMIAL 0x04C11DB7
|
||||
|
||||
unsigned int CRCTable[ 256 ];
|
||||
|
||||
unsigned int Reflect( unsigned int 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 );
|
||||
}
|
||||
}
|
||||
//*/
|
||||
//*
|
||||
unsigned int CRC32( unsigned int crc, void *buffer, unsigned int count )
|
||||
{
|
||||
unsigned int orig = crc;
|
||||
unsigned char * p = reinterpret_cast<unsigned char*>(buffer);
|
||||
while (count--)
|
||||
crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++];
|
||||
return crc ^ orig;
|
||||
}
|
||||
//*/
|
||||
|
||||
/*
|
||||
wxUint32 CRC_Calculate( wxUint32 crc, void *buffer, wxUint32 count )
|
||||
{
|
||||
wxUint32 Crc32=crc;
|
||||
__asm {
|
||||
mov esi, buffer
|
||||
mov ecx, count
|
||||
mov edx, crc
|
||||
xor eax, eax
|
||||
|
||||
loop1:
|
||||
inc esi
|
||||
mov al, dl
|
||||
xor al, byte ptr [esi]
|
||||
shr edx, 8
|
||||
mov ebx, [CRCTable+eax*4]
|
||||
xor edx, ebx
|
||||
|
||||
loop loop1
|
||||
|
||||
xor Crc32, edx
|
||||
}
|
||||
return Crc32;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
unsigned int CRC_Calculate( unsigned int crc, void *buffer, unsigned int count )
|
||||
{
|
||||
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;
|
||||
}
|
||||
//*/
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// CRC32 calculation functions
|
||||
//
|
||||
// Created by Gonetz, 2004
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
void CRC_BuildTable();
|
||||
|
||||
unsigned int CRC32( unsigned int crc, void *buffer, unsigned int count );
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
#ifndef COMBINE_H
|
||||
#define COMBINE_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
|
||||
{
|
||||
wxUint32 ccolor; // constant color to set at the end, color and alpha
|
||||
wxUint32 c_fnc, c_fac, c_loc, c_oth; // grColorCombine flags
|
||||
wxUint32 a_fnc, a_fac, a_loc, a_oth; // grAlphaCombine flags
|
||||
wxUint32 tex, tmu0_func, tmu0_fac, tmu0_invert, tmu1_func, tmu1_fac, tmu1_invert;
|
||||
wxUint32 tmu0_a_func, tmu0_a_fac, tmu0_a_invert, tmu1_a_func, tmu1_a_fac, tmu1_a_invert;
|
||||
int dc0_lodbias, dc1_lodbias;
|
||||
wxUint8 dc0_detailscale, dc1_detailscale;
|
||||
float dc0_detailmax, dc1_detailmax;
|
||||
float lodbias0, lodbias1;
|
||||
wxUint32 abf1, abf2;
|
||||
wxUint32 mod_0, modcolor_0, modcolor1_0, modcolor2_0, modfactor_0;
|
||||
wxUint32 mod_1, modcolor_1, modcolor1_1, modcolor2_1, modfactor_1;
|
||||
//combine extensions
|
||||
wxUint32 c_ext_a, c_ext_a_mode, c_ext_b, c_ext_b_mode, c_ext_c, c_ext_d;
|
||||
int c_ext_c_invert, c_ext_d_invert;
|
||||
wxUint32 a_ext_a, a_ext_a_mode, a_ext_b, a_ext_b_mode, a_ext_c, a_ext_d;
|
||||
int a_ext_c_invert, a_ext_d_invert;
|
||||
wxUint32 t0c_ext_a, t0c_ext_a_mode, t0c_ext_b, t0c_ext_b_mode, t0c_ext_c, t0c_ext_d;
|
||||
int t0c_ext_c_invert, t0c_ext_d_invert;
|
||||
wxUint32 t0a_ext_a, t0a_ext_a_mode, t0a_ext_b, t0a_ext_b_mode, t0a_ext_c, t0a_ext_d;
|
||||
int t0a_ext_c_invert, t0a_ext_d_invert;
|
||||
wxUint32 t1c_ext_a, t1c_ext_a_mode, t1c_ext_b, t1c_ext_b_mode, t1c_ext_c, t1c_ext_d;
|
||||
int t1c_ext_c_invert, t1c_ext_d_invert;
|
||||
wxUint32 t1a_ext_a, t1a_ext_a_mode, t1a_ext_b, t1a_ext_b_mode, t1a_ext_c, t1a_ext_d;
|
||||
int t1a_ext_c_invert, t1a_ext_d_invert;
|
||||
GRCOLORCOMBINEEXT grColorCombineExt;
|
||||
GRCOLORCOMBINEEXT grAlphaCombineExt;
|
||||
GRTEXCOLORCOMBINEEXT grTexColorCombineExt;
|
||||
GRTEXCOLORCOMBINEEXT grTexAlphaCombineExt;
|
||||
GRCONSTANTCOLORVALUEEXT grConstantColorValueExt;
|
||||
wxUint32 tex_ccolor;
|
||||
int combine_ext;
|
||||
wxUint8 cmb_ext_use;
|
||||
wxUint8 tex_cmb_ext_use;
|
||||
wxUint32 shade_mod_hash;
|
||||
} 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
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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 "Gfx_1.3.h"
|
||||
#include "Config.h"
|
||||
#include "m64p.h"
|
||||
#include "rdp.h"
|
||||
|
||||
#ifndef OLDAPI
|
||||
|
||||
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-Glide64mk2", &video_glide64_section) != M64ERR_SUCCESS)
|
||||
{
|
||||
ERRLOG("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;
|
||||
}
|
||||
|
||||
int Config_ReadScreenInt(const char *itemname)
|
||||
{
|
||||
return ConfigGetParamInt(video_general_section, itemname);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
BOOL Config_ReadInt(const char *itemname, const char *desc, int def_value, int create, int isBoolean)
|
||||
{
|
||||
VLOG("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);
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
// Resolutions, MUST be in the correct order (SST1VID.H)
|
||||
wxUint32 resolutions[0x18][2] = {
|
||||
{ 320, 200 },
|
||||
{ 320, 240 },
|
||||
{ 400, 256 },
|
||||
{ 512, 384 },
|
||||
{ 640, 200 },
|
||||
{ 640, 350 },
|
||||
{ 640, 400 },
|
||||
{ 640, 480 },
|
||||
{ 800, 600 },
|
||||
{ 960, 720 },
|
||||
{ 856, 480 },
|
||||
{ 512, 256 },
|
||||
{ 1024, 768 },
|
||||
{ 1280, 1024 },
|
||||
{ 1600, 1200 },
|
||||
{ 400, 300 },
|
||||
|
||||
// 0x10
|
||||
{ 1152, 864 },
|
||||
{ 1280, 960 },
|
||||
{ 1600, 1024 },
|
||||
{ 1792, 1344 },
|
||||
{ 1856, 1392 },
|
||||
{ 1920, 1440 },
|
||||
{ 2048, 1536 },
|
||||
{ 2048, 2048 }
|
||||
};
|
||||
|
||||
|
||||
BOOL Config_Open()
|
||||
{
|
||||
INI_Open();
|
||||
if(INI_FindSection("SETTINGS",FALSE) == FALSE) {
|
||||
INI_Close();
|
||||
ERRLOG("Could not open configuration");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int Config_ReadScreenInt(const char *itemname) {
|
||||
int res_data = Config_ReadInt("resolution", NULL, 7, FALSE, FALSE);
|
||||
if(!strcmp("ScreenWidth", itemname))
|
||||
return resolutions[res_data][0];
|
||||
else if(!strcmp("ScreenHeight", itemname))
|
||||
return resolutions[res_data][1];
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
BOOL Config_ReadInt(const char *itemname, const char *desc, int def_value, int create, int isBoolean) {
|
||||
VLOG("Getting value %s", itemname);
|
||||
int z = INI_ReadInt(itemname, def_value, FALSE);
|
||||
if(isBoolean) z=(z && 1);
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEXTURE_FILTER
|
||||
wxUint32 texfltr[] = {
|
||||
NO_FILTER, //"None"
|
||||
SMOOTH_FILTER_1, //"Smooth filtering 1"
|
||||
SMOOTH_FILTER_2, //"Smooth filtering 2"
|
||||
SMOOTH_FILTER_3, //"Smooth filtering 3"
|
||||
SMOOTH_FILTER_4, //"Smooth filtering 4"
|
||||
SHARP_FILTER_1, //"Sharp filtering 1"
|
||||
SHARP_FILTER_2, //"Sharp filtering 2"
|
||||
};
|
||||
|
||||
wxUint32 texenht[] = {
|
||||
NO_ENHANCEMENT, //"None"
|
||||
NO_ENHANCEMENT, //"Store"
|
||||
X2_ENHANCEMENT, //"X2"
|
||||
X2SAI_ENHANCEMENT, //"X2SAI"
|
||||
HQ2X_ENHANCEMENT, //"HQ2X"
|
||||
HQ2XS_ENHANCEMENT, //"HQ2XS"
|
||||
LQ2X_ENHANCEMENT, //"LQ2X"
|
||||
LQ2XS_ENHANCEMENT, //"LQ2XS"
|
||||
HQ4X_ENHANCEMENT, //"HQ4X"
|
||||
};
|
||||
|
||||
wxUint32 texcmpr[] = {
|
||||
//NO_COMPRESSION, //"None"
|
||||
// NCC_COMPRESSION, //"NCC"
|
||||
S3TC_COMPRESSION, //"S3TC"
|
||||
FXT1_COMPRESSION, //"FXT1"
|
||||
};
|
||||
|
||||
wxUint32 texhirs[] = {
|
||||
NO_HIRESTEXTURES, //"Do not use"
|
||||
RICE_HIRESTEXTURES, //"Rice format"
|
||||
// GHQ_HIRESTEXTURES, //"GlideHQ format"
|
||||
// JABO_HIRESTEXTURES, //"Jabo format"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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();
|
||||
int Config_ReadScreenInt(const char *itemname);
|
||||
PackedScreenResolution Config_ReadScreenSettings();
|
||||
BOOL Config_ReadInt(const char *itemname, const char *desc, int def_value, int create=TRUE, BOOL isBoolean=TRUE);
|
||||
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#define SELECTED_NONE 0x00000000
|
||||
#define SELECTED_TRI 0x00000001
|
||||
#define SELECTED_TEX 0x00000002
|
||||
|
||||
typedef struct TEX_INFO_t
|
||||
{
|
||||
wxUint32 cur_cache[2]; // Current cache #
|
||||
wxUint8 format;
|
||||
wxUint8 size;
|
||||
wxUint32 width, height;
|
||||
wxUint16 line, wid;
|
||||
wxUint8 palette;
|
||||
wxUint8 clamp_s, clamp_t;
|
||||
wxUint8 mirror_s, mirror_t;
|
||||
wxUint8 mask_s, mask_t;
|
||||
wxUint8 shift_s, shift_t;
|
||||
wxUint16 ul_s, ul_t, lr_s, lr_t;
|
||||
wxUint16 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
|
||||
{
|
||||
wxUint32 nv; // Number of vertices
|
||||
VERTEX *v; // Vertices (2d screen coords) of the triangle, used to outline
|
||||
wxUint32 cycle1, cycle2, cycle_mode; // Combine mode at the time of rendering
|
||||
wxUint8 uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both
|
||||
wxUint32 geom_mode; // geometry mode flags
|
||||
wxUint32 othermode_h; // setothermode_h flags
|
||||
wxUint32 othermode_l; // setothermode_l flags
|
||||
wxUint32 tri_n; // Triangle number
|
||||
wxUint32 flags;
|
||||
|
||||
int type; // 0-normal, 1-texrect, 2-fillrect
|
||||
|
||||
// texture info
|
||||
TEX_INFO t[2];
|
||||
|
||||
// colors
|
||||
wxUint32 fog_color;
|
||||
wxUint32 fill_color;
|
||||
wxUint32 prim_color;
|
||||
wxUint32 blend_color;
|
||||
wxUint32 env_color;
|
||||
wxUint32 prim_lodmin, prim_lodfrac;
|
||||
|
||||
TRI_INFO_t *pNext;
|
||||
} TRI_INFO;
|
||||
|
||||
typedef struct DEBUGGER_t
|
||||
{
|
||||
int capture; // Capture moment for debugging?
|
||||
|
||||
wxUint32 selected; // Selected object (see flags above)
|
||||
TRI_INFO *tri_sel;
|
||||
|
||||
wxUint32 tex_scroll; // texture scrolling
|
||||
wxUint32 tex_sel;
|
||||
|
||||
// CAPTURE INFORMATION
|
||||
wxUint8 *screen; // Screen capture
|
||||
TRI_INFO *tri_list; // Triangle information list
|
||||
TRI_INFO *tri_last; // Last in the list (first in)
|
||||
|
||||
wxUint32 tmu; // tmu #
|
||||
|
||||
wxUint32 draw_mode;
|
||||
|
||||
// Page number
|
||||
int page;
|
||||
|
||||
} GLIDE64_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
|
||||
|
||||
extern GLIDE64_DEBUGGER _debugger;
|
||||
|
||||
void debug_init ();
|
||||
void debug_capture ();
|
||||
void debug_cacheviewer ();
|
||||
void debug_mouse ();
|
||||
void debug_keys ();
|
||||
void output (float x, float y, int scale, const char *fmt, ...);
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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 "Gfx_1.3.h"
|
||||
#include "rdp.h"
|
||||
#include "DepthBufferRender.h"
|
||||
|
||||
wxUint16 * zLUT = 0;
|
||||
|
||||
void ZLUT_init()
|
||||
{
|
||||
if (zLUT)
|
||||
return;
|
||||
zLUT = new wxUint16[0x40000];
|
||||
for(int i=0; i<0x40000; i++)
|
||||
{
|
||||
wxUint32 exponent = 0;
|
||||
wxUint32 testbit = 1 << 17;
|
||||
while((i & testbit) && (exponent < 7))
|
||||
{
|
||||
exponent++;
|
||||
testbit = 1 << (17 - exponent);
|
||||
}
|
||||
|
||||
wxUint32 mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff;
|
||||
zLUT[i] = (wxUint16)(((exponent << 11) | mantissa) << 2);
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
__inline int idiv16(int x, int y) // (x << 16) / y
|
||||
{
|
||||
//x = (((long long)x) << 16) / ((long long)y);
|
||||
/*
|
||||
eax = x;
|
||||
ebx = y;
|
||||
edx = x;
|
||||
(x << 16) | ()
|
||||
*/
|
||||
#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));
|
||||
#else
|
||||
x = (((long long)x) << 16) / ((long long)y);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
__inline int iceil(int x)
|
||||
{
|
||||
x += 0xffff;
|
||||
return (x >> 16);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
wxUint16 * destptr = (wxUint16*)(gfx.RDRAM+rdp.zimg);
|
||||
int y1 = iceil(min_y);
|
||||
if (y1 >= (int)rdp.scissor_o.lr_y) return;
|
||||
int shift;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x1 = iceil(left_x);
|
||||
if (x1 < (int)rdp.scissor_o.ul_x)
|
||||
x1 = rdp.scissor_o.ul_x;
|
||||
int width = iceil(right_x) - x1;
|
||||
if (x1+width >= (int)rdp.scissor_o.lr_x)
|
||||
width = rdp.scissor_o.lr_x - x1 - 1;
|
||||
|
||||
if(width > 0 && y1 >= (int)rdp.scissor_o.ul_y) {
|
||||
|
||||
// Prestep initial z
|
||||
|
||||
int prestep = (x1 << 16) - left_x;
|
||||
int z = left_z + imul16(prestep, dzdx);
|
||||
|
||||
shift = x1 + y1*rdp.zi_width;
|
||||
//draw to depth buffer
|
||||
int trueZ;
|
||||
int idx;
|
||||
wxUint16 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++;
|
||||
if (y1 >= (int)rdp.scissor_o.lr_y) return;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Software rendering to N64 depth buffer
|
||||
// Created by Gonetz, Dec 2004
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef DEPTH_BUFFER_RENDER_H
|
||||
#define DEPTH_BUFFER_RENDER_H
|
||||
|
||||
struct vertexi
|
||||
{
|
||||
int x,y; // Screen position in 16:16 bit fixed point
|
||||
int z; // z value in 16:16 bit fixed point
|
||||
};
|
||||
|
||||
extern wxUint16 * zLUT;
|
||||
void ZLUT_init();
|
||||
void ZLUT_release();
|
||||
|
||||
void Rasterize(vertexi * vtx, int vertices, int dzdx);
|
||||
|
||||
#endif //DEPTH_BUFFER_RENDER_H
|
|
@ -0,0 +1,659 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Draw N64 frame buffer to screen.
|
||||
// Created by Gonetz, 2007
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
|
||||
#include "Gfx_1.3.h"
|
||||
#include "FBtoScreen.h"
|
||||
#include "TexCache.h"
|
||||
|
||||
static int SetupFBtoScreenCombiner(wxUint32 texture_size, wxUint32 opaque)
|
||||
{
|
||||
int tmu;
|
||||
if (voodoo.tmem_ptr[GR_TMU0]+texture_size < voodoo.tex_max_addr[0])
|
||||
{
|
||||
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,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
FXFALSE,
|
||||
FXFALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (voodoo.tmem_ptr[GR_TMU1]+texture_size >= voodoo.tex_max_addr[1])
|
||||
ClearCache ();
|
||||
tmu = GR_TMU1;
|
||||
grTexCombine( GR_TMU1,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
FXFALSE,
|
||||
FXFALSE );
|
||||
grTexCombine( GR_TMU0,
|
||||
GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
FXFALSE,
|
||||
FXFALSE );
|
||||
}
|
||||
int filter = (rdp.filter_mode!=2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_BILINEAR;
|
||||
grTexFilterMode (tmu, filter, filter);
|
||||
grTexClampMode (tmu,
|
||||
GR_TEXTURECLAMP_CLAMP,
|
||||
GR_TEXTURECLAMP_CLAMP);
|
||||
// grConstantColorValue (0xFFFFFFFF);
|
||||
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_TEXTURE,
|
||||
// GR_COMBINE_OTHER_CONSTANT,
|
||||
FXFALSE);
|
||||
grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_TEXTURE,
|
||||
FXFALSE);
|
||||
if (opaque)
|
||||
{
|
||||
grAlphaTestFunction (GR_CMP_ALWAYS);
|
||||
grAlphaBlendFunction( GR_BLEND_ONE,
|
||||
GR_BLEND_ZERO,
|
||||
GR_BLEND_ONE,
|
||||
GR_BLEND_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,
|
||||
GR_BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
GR_BLEND_ONE,
|
||||
GR_BLEND_ZERO);
|
||||
}
|
||||
grDepthBufferFunction (GR_CMP_ALWAYS);
|
||||
grCullMode(GR_CULL_DISABLE);
|
||||
grDepthMask (FXFALSE);
|
||||
rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;
|
||||
return tmu;
|
||||
}
|
||||
|
||||
static void DrawRE2Video(FB_TO_SCREEN_INFO & fb_info, float scale)
|
||||
{
|
||||
float scale_y = (float)fb_info.width/rdp.vi_height;
|
||||
float height = settings.scr_res_x/scale_y;
|
||||
float ul_x = 0.5f;
|
||||
float ul_y = (settings.scr_res_y - height)/2.0f;
|
||||
float lr_y = settings.scr_res_y - ul_y - 1.0f;
|
||||
float lr_x = settings.scr_res_x - 1.0f;
|
||||
float lr_u = (fb_info.width - 1)*scale;
|
||||
float lr_v = (fb_info.height - 1)*scale;
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },
|
||||
{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
}
|
||||
|
||||
static void DrawRE2Video256(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
FRDP("DrawRE2Video256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
wxUint32 * src = (wxUint32*)(gfx.RDRAM+fb_info.addr);
|
||||
GrTexInfo t_info;
|
||||
t_info.smallLodLog2 = GR_LOD_LOG2_256;
|
||||
t_info.largeLodLog2 = GR_LOD_LOG2_256;
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
wxUint16 * tex = (wxUint16*)texture_buffer;
|
||||
wxUint16 * dst = tex;
|
||||
wxUint32 col;
|
||||
wxUint8 r, g, b;
|
||||
fb_info.height = min(256, fb_info.height);
|
||||
for (wxUint32 h = 0; h < fb_info.height; h++)
|
||||
{
|
||||
for (wxUint32 w = 0; w < 256; w++)
|
||||
{
|
||||
col = *(src++);
|
||||
r = (wxUint8)((col >> 24)&0xFF);
|
||||
r = (wxUint8)((float)r / 255.0f * 31.0f);
|
||||
g = (wxUint8)((col >> 16)&0xFF);
|
||||
g = (wxUint8)((float)g / 255.0f * 63.0f);
|
||||
b = (wxUint8)((col >> 8)&0xFF);
|
||||
b = (wxUint8)((float)b / 255.0f * 31.0f);
|
||||
*(dst++) = (r << 11) | (g << 5) | b;
|
||||
}
|
||||
src += (fb_info.width - 256);
|
||||
}
|
||||
t_info.format = GR_TEXFMT_RGB_565;
|
||||
t_info.data = tex;
|
||||
int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);
|
||||
grTexDownloadMipMap (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
grTexSource (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
DrawRE2Video(fb_info, 1.0f);
|
||||
}
|
||||
|
||||
static void DrawFrameBufferToScreen256(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
if (settings.hacks&hack_RE2)
|
||||
{
|
||||
DrawRE2Video256(fb_info);
|
||||
return;
|
||||
}
|
||||
FRDP("DrawFrameBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;
|
||||
wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;
|
||||
GrTexInfo t_info;
|
||||
wxUint8 * image = gfx.RDRAM+fb_info.addr;
|
||||
wxUint32 width256 = ((width-1) >> 8) + 1;
|
||||
wxUint32 height256 = ((height-1) >> 8) + 1;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
t_info.format = GR_TEXFMT_ARGB_1555;
|
||||
wxUint16 * tex = (wxUint16*)texture_buffer;
|
||||
t_info.data = tex;
|
||||
wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque);
|
||||
wxUint16 * src = (wxUint16*)image;
|
||||
src += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
wxUint32 * src32 = (wxUint32*)image;
|
||||
src32 += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
wxUint32 w_tail = width%256;
|
||||
wxUint32 h_tail = height%256;
|
||||
wxUint16 c;
|
||||
wxUint32 c32;
|
||||
wxUint32 idx;
|
||||
wxUint32 bound = BMASK+1-fb_info.addr;
|
||||
bound = fb_info.size == 2 ? bound >> 1 : bound >> 2;
|
||||
wxUint8 r, g, b, a;
|
||||
wxUint32 cur_width, cur_height, cur_tail;
|
||||
wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu];
|
||||
if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE))
|
||||
{
|
||||
tex_adr = TEXMEM_2MB_EDGE;
|
||||
}
|
||||
for (wxUint32 h = 0; h < height256; h++)
|
||||
{
|
||||
for (wxUint32 w = 0; w < width256; w++)
|
||||
{
|
||||
cur_width = (256*(w+1) < width) ? 256 : w_tail;
|
||||
cur_height = (256*(h+1) < height) ? 256 : h_tail;
|
||||
cur_tail = 256 - cur_width;
|
||||
wxUint16 * dst = tex;
|
||||
if (fb_info.size == 2)
|
||||
{
|
||||
for (wxUint32 y=0; y < cur_height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < cur_width; x++)
|
||||
{
|
||||
idx = (x+256*w+(y+256*h)*fb_info.width)^1;
|
||||
if (idx >= bound)
|
||||
break;
|
||||
c = src[idx];
|
||||
*(dst++) = (c >> 1) | ((c&1)<<15);
|
||||
}
|
||||
dst += cur_tail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (wxUint32 y=0; y < cur_height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < cur_width; x++)
|
||||
{
|
||||
idx = (x+256*w+(y+256*h)*fb_info.width);
|
||||
if (idx >= bound)
|
||||
break;
|
||||
c32 = src32[idx];
|
||||
r = (wxUint8)((c32 >> 24)&0xFF);
|
||||
r = (wxUint8)((float)r / 255.0f * 31.0f);
|
||||
g = (wxUint8)((c32 >> 16)&0xFF);
|
||||
g = (wxUint8)((float)g / 255.0f * 63.0f);
|
||||
b = (wxUint8)((c32 >> 8)&0xFF);
|
||||
b = (wxUint8)((float)b / 255.0f * 31.0f);
|
||||
a = (c32&0xFF) ? 1 : 0;
|
||||
*(dst++) = (a<<15) | (r << 10) | (g << 5) | b;
|
||||
}
|
||||
dst += cur_tail;
|
||||
}
|
||||
}
|
||||
grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
tex_adr += tex_size;
|
||||
float ul_x = (float)(fb_info.ul_x + 256*w);
|
||||
float ul_y = (float)(fb_info.ul_y + 256*h);
|
||||
float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x;
|
||||
float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y;
|
||||
ul_x *= rdp.scale_x;
|
||||
ul_y *= rdp.scale_y;
|
||||
ul_x += rdp.offset_x;
|
||||
ul_y += rdp.offset_y;
|
||||
lr_x += rdp.offset_x;
|
||||
lr_y += rdp.offset_y;
|
||||
|
||||
float lr_u = (float)(cur_width-1);
|
||||
float lr_v = (float)(cur_height-1);
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },
|
||||
{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
if (fb_info.width < 200 || fb_info.size < 2)
|
||||
return false;
|
||||
wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;
|
||||
wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;
|
||||
wxUint32 max_size = min(voodoo.max_tex_size, 512);
|
||||
if (width > (wxUint32)max_size || height > (wxUint32)max_size)
|
||||
{
|
||||
DrawFrameBufferToScreen256(fb_info);
|
||||
return true;
|
||||
}
|
||||
FRDP("DrawFrameBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
GrTexInfo t_info;
|
||||
wxUint8 * image = gfx.RDRAM+fb_info.addr;
|
||||
wxUint32 texwidth;
|
||||
float scale;
|
||||
if (width <= 256)
|
||||
{
|
||||
texwidth = 256;
|
||||
scale = 1.0f;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;
|
||||
}
|
||||
else
|
||||
{
|
||||
texwidth = 512;
|
||||
scale = 0.5f;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512;
|
||||
}
|
||||
|
||||
if (height <= (texwidth>>1))
|
||||
{
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
}
|
||||
|
||||
if (fb_info.size == 2)
|
||||
{
|
||||
wxUint16 * tex = (wxUint16*)texture_buffer;
|
||||
wxUint16 * dst = tex;
|
||||
wxUint16 * src = (wxUint16*)image;
|
||||
src += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
wxUint16 c;
|
||||
wxUint32 idx;
|
||||
const wxUint32 bound = (BMASK+1-fb_info.addr) >> 1;
|
||||
bool empty = true;
|
||||
for (wxUint32 y=0; y < height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < width; x++)
|
||||
{
|
||||
idx = (x+y*fb_info.width)^1;
|
||||
if (idx >= bound)
|
||||
break;
|
||||
c = src[idx];
|
||||
if (c) empty = false;
|
||||
*(dst++) = (c >> 1) | ((c&1)<<15);
|
||||
}
|
||||
dst += texwidth-width;
|
||||
}
|
||||
if (empty)
|
||||
return false;
|
||||
t_info.format = GR_TEXFMT_ARGB_1555;
|
||||
t_info.data = tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxUint32 * tex = (wxUint32*)texture_buffer;
|
||||
wxUint32 * dst = tex;
|
||||
wxUint32 * src = (wxUint32*)image;
|
||||
src += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
wxUint32 col;
|
||||
wxUint32 idx;
|
||||
const wxUint32 bound = (BMASK+1-fb_info.addr) >> 2;
|
||||
for (wxUint32 y=0; y < height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < width; x++)
|
||||
{
|
||||
idx = x+y*fb_info.width;
|
||||
if (idx >= bound)
|
||||
break;
|
||||
col = src[idx];
|
||||
*(dst++) = (col >> 8) | 0xFF000000;
|
||||
}
|
||||
dst += texwidth-width;
|
||||
}
|
||||
t_info.format = GR_TEXFMT_ARGB_8888;
|
||||
t_info.data = tex;
|
||||
}
|
||||
|
||||
int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);
|
||||
grTexDownloadMipMap (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
grTexSource (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
if (settings.hacks&hack_RE2)
|
||||
{
|
||||
DrawRE2Video(fb_info, scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x;
|
||||
float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y;
|
||||
float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x;
|
||||
float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y;
|
||||
float lr_u = (width-1)*scale;
|
||||
float lr_v = (height-1)*scale;
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },
|
||||
{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DrawDepthBufferToScreen256(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
FRDP("DrawDepthBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;
|
||||
wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;
|
||||
GrTexInfo t_info;
|
||||
wxUint8 * image = gfx.RDRAM+fb_info.addr;
|
||||
wxUint32 width256 = ((width-1) >> 8) + 1;
|
||||
wxUint32 height256 = ((height-1) >> 8) + 1;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
wxUint16 * tex = (wxUint16*)texture_buffer;
|
||||
t_info.data = tex;
|
||||
wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque);
|
||||
grConstantColorValue (rdp.fog_color);
|
||||
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_CONSTANT,
|
||||
FXFALSE);
|
||||
wxUint16 * src = (wxUint16*)image;
|
||||
src += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
wxUint32 w_tail = width%256;
|
||||
wxUint32 h_tail = height%256;
|
||||
wxUint32 cur_width, cur_height, cur_tail;
|
||||
wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu];
|
||||
if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE))
|
||||
{
|
||||
tex_adr = TEXMEM_2MB_EDGE;
|
||||
}
|
||||
for (wxUint32 h = 0; h < height256; h++)
|
||||
{
|
||||
for (wxUint32 w = 0; w < width256; w++)
|
||||
{
|
||||
cur_width = (256*(w+1) < width) ? 256 : w_tail;
|
||||
cur_height = (256*(h+1) < height) ? 256 : h_tail;
|
||||
cur_tail = 256 - cur_width;
|
||||
wxUint16 * dst = tex;
|
||||
for (wxUint32 y=0; y < cur_height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < cur_width; x++)
|
||||
{
|
||||
*(dst++) = rdp.pal_8[src[(x+256*w+(y+256*h)*fb_info.width)^1]>>8];
|
||||
}
|
||||
dst += cur_tail;
|
||||
}
|
||||
grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);
|
||||
tex_adr += tex_size;
|
||||
float ul_x = (float)(fb_info.ul_x + 256*w);
|
||||
float ul_y = (float)(fb_info.ul_y + 256*h);
|
||||
float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x + rdp.offset_x;
|
||||
float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y + rdp.offset_y;
|
||||
ul_x = ul_x * rdp.scale_x + rdp.offset_x;
|
||||
ul_y = ul_y * rdp.scale_y + rdp.offset_y;
|
||||
float lr_u = (float)(cur_width-1);
|
||||
float lr_v = (float)(cur_height-1);
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },
|
||||
{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawHiresDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
FRDP("DrawHiresDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
GrTexInfo t_info;
|
||||
float scale = 0.25f;
|
||||
GrLOD_t LOD = GR_LOD_LOG2_1024;
|
||||
if (settings.scr_res_x > 1024)
|
||||
{
|
||||
scale = 0.125f;
|
||||
LOD = GR_LOD_LOG2_2048;
|
||||
}
|
||||
t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = LOD;
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
grConstantColorValue (rdp.fog_color);
|
||||
grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_LOCAL_CONSTANT,
|
||||
GR_COMBINE_OTHER_NONE,
|
||||
FXFALSE);
|
||||
grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_TEXTURE,
|
||||
FXFALSE);
|
||||
grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,
|
||||
GR_BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
GR_BLEND_ONE,
|
||||
GR_BLEND_ZERO);
|
||||
grDepthBufferFunction (GR_CMP_ALWAYS);
|
||||
grDepthMask (FXFALSE);
|
||||
grCullMode (GR_CULL_DISABLE);
|
||||
grTexCombine( GR_TMU1,
|
||||
GR_COMBINE_FUNCTION_NONE,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_FUNCTION_NONE,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
FXFALSE,
|
||||
FXFALSE );
|
||||
grTexCombine( GR_TMU0,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
GR_COMBINE_FUNCTION_LOCAL,
|
||||
GR_COMBINE_FACTOR_NONE,
|
||||
FXFALSE,
|
||||
FXFALSE);
|
||||
// grAuxBufferExt( GR_BUFFER_AUXBUFFER );
|
||||
grTexSource( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, GR_MIPMAPLEVELMASK_BOTH, &(t_info) );
|
||||
float ul_x = (float)rdp.scissor.ul_x;
|
||||
float ul_y = (float)rdp.scissor.ul_y;
|
||||
float lr_x = (float)rdp.scissor.lr_x;
|
||||
float lr_y = (float)rdp.scissor.lr_y;
|
||||
float ul_u = (float)rdp.scissor.ul_x * scale;
|
||||
float ul_v = (float)rdp.scissor.ul_y * scale;
|
||||
float lr_u = (float)rdp.scissor.lr_x * scale;
|
||||
float lr_v = (float)rdp.scissor.lr_y * scale;
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v, {ul_u, ul_v, ul_u, ul_v} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v, {lr_u, ul_v, lr_u, ul_v} },
|
||||
{ ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v, {ul_u, lr_v, ul_u, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
// grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT );
|
||||
rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;
|
||||
}
|
||||
|
||||
void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info)
|
||||
{
|
||||
wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;
|
||||
wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;
|
||||
if (width > (wxUint32)voodoo.max_tex_size || height > (wxUint32)voodoo.max_tex_size || width > 512)
|
||||
{
|
||||
DrawDepthBufferToScreen256(fb_info);
|
||||
return;
|
||||
}
|
||||
if (fb_hwfbe_enabled && !evoodoo)
|
||||
{
|
||||
DrawHiresDepthBufferToScreen(fb_info);
|
||||
return;
|
||||
}
|
||||
FRDP("DrawDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr);
|
||||
GrTexInfo t_info;
|
||||
wxUint8 * image = gfx.RDRAM+fb_info.addr;
|
||||
wxUint32 texwidth;
|
||||
float scale;
|
||||
if (width <= 256)
|
||||
{
|
||||
texwidth = 256;
|
||||
scale = 1.0f;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;
|
||||
}
|
||||
else
|
||||
{
|
||||
texwidth = 512;
|
||||
scale = 0.5f;
|
||||
t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512;
|
||||
}
|
||||
|
||||
if (height <= (texwidth>>1))
|
||||
{
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
}
|
||||
|
||||
wxUint16 * tex = (wxUint16*)texture_buffer;
|
||||
wxUint16 * dst = tex;
|
||||
wxUint16 * src = (wxUint16*)image;
|
||||
src += fb_info.ul_x + fb_info.ul_y * fb_info.width;
|
||||
for (wxUint32 y=0; y < height; y++)
|
||||
{
|
||||
for (wxUint32 x=0; x < width; x++)
|
||||
{
|
||||
*(dst++) = rdp.pal_8[src[(x+y*fb_info.width)^1]>>8];
|
||||
}
|
||||
dst += texwidth-width;
|
||||
}
|
||||
t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
t_info.data = tex;
|
||||
|
||||
int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);
|
||||
grConstantColorValue (rdp.fog_color);
|
||||
grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_CONSTANT,
|
||||
FXFALSE);
|
||||
grTexDownloadMipMap (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
grTexSource (tmu,
|
||||
voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],
|
||||
GR_MIPMAPLEVELMASK_BOTH,
|
||||
&t_info);
|
||||
float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x;
|
||||
float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y;
|
||||
float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x;
|
||||
float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y;
|
||||
float lr_u = (width-1)*scale;
|
||||
float lr_v = (height-1)*scale;
|
||||
float zero = scale*0.5f;
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },
|
||||
{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Render N64 frame buffer to screen
|
||||
// Created by Gonetz, 2007
|
||||
//
|
||||
//****************************************************************
|
||||
#ifndef FBtoSCREEN_H
|
||||
#define FBtoSCREEN_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wxUint32 addr; //color image address
|
||||
wxUint32 size;
|
||||
wxUint32 width;
|
||||
wxUint32 height;
|
||||
wxUint32 ul_x;
|
||||
wxUint32 ul_y;
|
||||
wxUint32 lr_x;
|
||||
wxUint32 lr_y;
|
||||
wxUint32 opaque;
|
||||
} FB_TO_SCREEN_INFO;
|
||||
|
||||
bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO & fb_info);
|
||||
void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info);
|
||||
|
||||
#endif // #ifndef FBtoSCREEN_H
|
|
@ -0,0 +1,681 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
/**********************************************************************************
|
||||
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 "winlnxdefs.h"
|
||||
#include "m64p.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <SDL_mutex.h>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h> // offsetof
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <glide.h>
|
||||
#include "GlideExtensions.h"
|
||||
#include "rdp.h"
|
||||
#include "Keys.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#if defined __VISUALC__
|
||||
#define GLIDE64_TRY __try
|
||||
#define GLIDE64_CATCH __except (EXCEPTION_EXECUTE_HANDLER)
|
||||
#else
|
||||
#define GLIDE64_TRY try
|
||||
#define GLIDE64_CATCH catch (...)
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
typedef int HWND;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _ENDUSER_RELEASE_
|
||||
|
||||
//********
|
||||
// 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:
|
||||
#define LOGKEY 0x11 // this key (CONTROL)
|
||||
|
||||
//#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 _ENDUSER_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",std::ios::app); extlog << x; extlog.close();
|
||||
#else
|
||||
#define EXT(x)
|
||||
#endif
|
||||
|
||||
#ifndef _ENDUSER_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 fps_last;
|
||||
extern LARGE_INTEGER fps_next;
|
||||
extern float fps;
|
||||
extern wxUint32 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 wxUint32 update_screen_count;
|
||||
extern wxUint32 resolutions[0x18][2];
|
||||
|
||||
int CheckKeyPressed(int key, int mask);
|
||||
|
||||
//#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",std::ios::app); loga << (...); loga.flush(); loga.close();
|
||||
|
||||
//#else
|
||||
#ifndef OLD_API
|
||||
#define LOG(...) WriteLog(M64MSG_INFO, __VA_ARGS__)
|
||||
#define VLOG(...) WriteLog(M64MSG_VERBOSE, __VA_ARGS__)
|
||||
#define WARNLOG(...) WriteLog(M64MSG_WARNING, __VA_ARGS__)
|
||||
#define ERRLOG(...) WriteLog(M64MSG_ERROR, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...) printf(__VA_ARGS__)
|
||||
#define VLOG(...)
|
||||
#define WARNLOG(...) printf(__VA_ARGS__)
|
||||
#define ERRLOG(X, ...) str.Printf(_T(X), __VA_ARGS__); wxMessageBox(str, _T("Error"), wxOK | wxICON_EXCLAMATION, GFXWindow)
|
||||
#define ERRLOG(X) str.Printf(_T(X)); wxMessageBox(str, _T("Error"), wxOK | wxICON_EXCLAMATION, GFXWindow)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RDP_LOGGING
|
||||
extern int log_open;
|
||||
extern std::ofstream rdp_log;
|
||||
#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 LRDP(x) EXT("RDP (...)\n"); if (settings.logging && log_open) { if (!CheckKeyPressed(LOGKEY,0x8000)) { rdp_log << x; rdp_log.flush(); } }
|
||||
#else
|
||||
#define LRDP(x) EXT("RDP (...)\n"); if (settings.logging && log_open) { rdp_log << x; rdp_log.flush(); }
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define OPEN_RDP_LOG()
|
||||
#define CLOSE_RDP_LOG()
|
||||
#define LRDP(x)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RDP_ERROR_LOG
|
||||
extern int elog_open;
|
||||
extern std::ofstream rdp_err;
|
||||
#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 (settings.elogging) { FRDP_E (x); }
|
||||
#else
|
||||
#define OPEN_RDP_E_LOG()
|
||||
#define CLOSE_RDP_E_LOG()
|
||||
#define RDP_E(x)
|
||||
#endif
|
||||
|
||||
__inline void FRDP (const char *fmt, ...)
|
||||
{
|
||||
#ifdef RDP_LOGGING
|
||||
if (!settings.logging || !log_open) return;
|
||||
|
||||
#ifdef LOGNOTKEY
|
||||
if (CheckKeyPressed(LOGKEY,0x8000)) return;
|
||||
#endif
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(out_buf, fmt, ap);
|
||||
LRDP (out_buf);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
__inline void FRDP_E (const char *fmt, ...)
|
||||
{
|
||||
#ifdef RDP_ERROR_LOG
|
||||
if (!settings.elogging || !elog_open) return;
|
||||
|
||||
#ifdef LOGNOTKEY
|
||||
if (CheckKeyPressed(LOGKEY,0x8000)) return;
|
||||
#endif
|
||||
|
||||
sprintf (out_buf, "%08lx: (%08lx, %08lx) ", 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();
|
||||
va_end(ap2);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int fullscreen;
|
||||
extern int romopen;
|
||||
extern int to_fullscreen;
|
||||
extern int debugging;
|
||||
|
||||
extern int evoodoo;
|
||||
extern int ev_fullscreen;
|
||||
|
||||
extern SDL_sem *mutexProcessDList;
|
||||
extern int exception;
|
||||
|
||||
// extern wxMutex *mutexProcessDList;
|
||||
|
||||
int InitGfx (int);
|
||||
void ReleaseGfx ();
|
||||
|
||||
// The highest 8 bits are the segment # (1-16), and the lower 24 bits are the offset to
|
||||
// add to it.
|
||||
__inline wxUint32 segoffset (wxUint32 so)
|
||||
{
|
||||
return (rdp.segment[(so>>24)&0x0f] + (so&BMASK))&BMASK;
|
||||
}
|
||||
|
||||
/* Plugin types */
|
||||
#define PLUGIN_TYPE_GFX 2
|
||||
|
||||
// this is already defined in API
|
||||
/*
|
||||
#ifdef __WINDOWS__
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#define CALL _cdecl
|
||||
#else
|
||||
#define EXPORT extern
|
||||
#define CALL
|
||||
#endif
|
||||
*/
|
||||
/***** Structures *****/
|
||||
typedef struct {
|
||||
wxUint16 Version; /* Set to 0x0103 */
|
||||
wxUint16 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 */
|
||||
int NormalMemory; /* a normal wxUint8 array */
|
||||
int MemoryBswaped; /* a normal wxUint8 array where the memory has been pre
|
||||
bswap on a dword (32 bits) boundry */
|
||||
} PLUGIN_INFO;
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
// <removed, already defined in API>
|
||||
} GFX_INFO;
|
||||
*/
|
||||
extern GFX_INFO gfx;
|
||||
// extern wxWindow * GFXWindow;
|
||||
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)(FxI32, FxI32, FxBool, FxBool);
|
||||
|
||||
typedef GrScreenResolution_t (FX_CALL *GRWRAPPERFULLSCREENRESOLUTIONEXT)(wxUint32*, wxUint32*);
|
||||
|
||||
typedef char ** (FX_CALL *GRQUERYRESOLUTIONSEXT)(FxI32*);
|
||||
|
||||
typedef int (*GETTEXADDR)(int tmu, int texsize);
|
||||
|
||||
extern GRTEXBUFFEREXT grTextureBufferExt;
|
||||
extern GRTEXBUFFEREXT grTextureAuxBufferExt;
|
||||
extern GRAUXBUFFEREXT grAuxBufferExt;
|
||||
extern GRSTIPPLE grStippleModeExt;
|
||||
extern GRSTIPPLE grStipplePatternExt;
|
||||
extern GETTEXADDR GetTexAddr;
|
||||
|
||||
#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);
|
||||
void WriteSettings (bool saveEmulationSettings = false);
|
||||
|
||||
#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 int 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 = wxUint8, 2 = wxUint16, 4 = wxUint32
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL FBWrite(wxUint32, wxUint32);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wxUint32 addr;
|
||||
wxUint32 val;
|
||||
wxUint32 size; // 1 = wxUint8, 2 = wxUint16, 4=wxUint32
|
||||
} 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, wxUint32 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 = wxUint8, 2 = wxUint16, 4 = wxUint32
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL FBRead(wxUint32 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);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif //_GFX_H_INCLUDED__
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define GR_BUFFER_TEXTUREBUFFER_EXT 0x6
|
||||
#define GR_BUFFER_TEXTUREAUXBUFFER_EXT 0x7
|
||||
|
||||
typedef FxU32 GrPixelFormat_t;
|
||||
#define GR_PIXFMT_RGB_565 0x03
|
||||
#define GR_PIXFMT_ARGB_1555 0x0004
|
||||
#define GR_PIXFMT_ARGB_8888 0x0005
|
||||
|
||||
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
|
||||
|
||||
#define GR_TEXFMT_ARGB_8888 0x12
|
||||
|
||||
#define GR_LOD_LOG2_2048 0xb
|
||||
#define GR_LOD_LOG2_1024 0xa
|
||||
#define GR_LOD_LOG2_512 0x9
|
||||
|
||||
#define GR_TEXTURE_UMA_EXT 0x06
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,615 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
#include "m64p.h"
|
||||
|
||||
#include "Ini.h"
|
||||
#include "Gfx_1.3.h"
|
||||
#include <limits.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#define stricmp _stricmp
|
||||
#endif
|
||||
|
||||
FILE *ini;
|
||||
int sectionstart;
|
||||
int last_line; // last good line
|
||||
int last_line_ret; // last line ended in return?
|
||||
wxUint16 cr = 0x0A0D;
|
||||
static char configdir[PATH_MAX] = {0};
|
||||
|
||||
|
||||
//TODO: move INI_xxxx() function code into class and clean up
|
||||
Ini *Ini::singleton = 0;
|
||||
|
||||
Ini::Ini()
|
||||
{
|
||||
if (!INI_Open())
|
||||
{
|
||||
printf("Could not find INI file!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ini *Ini::OpenIni()
|
||||
{
|
||||
if (!singleton)
|
||||
singleton = new Ini();
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void Ini::SetPath(const char *path)
|
||||
{
|
||||
if (!INI_FindSection(path, false))
|
||||
{
|
||||
printf("Could not find [%s] section in INI file!", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Ini::Read(const char *key, int *l)
|
||||
{
|
||||
int undef = 0xDEADBEEF;
|
||||
int tmpVal = INI_ReadInt(key, undef, false);
|
||||
if (tmpVal == undef)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l = tmpVal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ini::Read(const char *key, int *l, int defaultVal)
|
||||
{
|
||||
*l = INI_ReadInt(key, defaultVal, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Ini::Read(const char *key, int defaultVal)
|
||||
{
|
||||
return INI_ReadInt(key, defaultVal, false);
|
||||
}
|
||||
|
||||
|
||||
BOOL INI_Open ()
|
||||
{
|
||||
//TODO: use ConfigGetSharedDataFilepath
|
||||
|
||||
// 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 (NULL, 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, "Glide64mk2.ini", PATH_MAX - strlen(path));
|
||||
LOG("opening %s\n", path);
|
||||
// Open the file
|
||||
ini = fopen (path, "rb");
|
||||
if (ini == NULL)
|
||||
{
|
||||
ERRLOG("Could not find Glide64mk2.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)
|
||||
{
|
||||
printf("Inserting space, space to insert is %d\n", 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);
|
||||
if (ftruncate(file, t2+space) != 0)
|
||||
ERRLOG("Failed to truncate .ini file to %i bytes", 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);
|
||||
if (fread(chunk,1,len,ini) != (size_t) len)
|
||||
ERRLOG("Failed to read %i bytes from .ini file", len);
|
||||
fseek (ini,-len+space,SEEK_CUR);
|
||||
if (fwrite(chunk,1,len,ini) != (size_t) len)
|
||||
ERRLOG("Failed to write %i bytes to .ini file", len);
|
||||
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);
|
||||
if (ftruncate(file, t2+space) != 0)
|
||||
ERRLOG("Failed to truncate .ini file to %i bytes", t2+space);
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
BOOL INI_FindSection (const char *sectionname, BOOL create)
|
||||
{
|
||||
if (ini == NULL)
|
||||
return FALSE;
|
||||
printf("INI_FindSection trying to find name for %s\n", sectionname);
|
||||
|
||||
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;
|
||||
if (fgets(line,255,ini) == NULL)
|
||||
break;
|
||||
|
||||
// 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)
|
||||
if (fwrite(&cr, 1, 2, ini) != 2)
|
||||
ERRLOG("Failed to write <CR><LF> to .ini file");
|
||||
sprintf (section, "[%s]", sectionname);
|
||||
if (fwrite(&cr, 1, 2, ini) != 2 ||
|
||||
fwrite(section, 1, strlen(section), ini) != strlen(section) ||
|
||||
fwrite(&cr, 1, 2, ini) != 2)
|
||||
ERRLOG("Failed to write Section line to .ini file");
|
||||
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;
|
||||
if (fgets(line,255,ini) == NULL)
|
||||
break;
|
||||
|
||||
// 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)
|
||||
if (fwrite(&cr, 1, 2, ini) != 2)
|
||||
ERRLOG("Failed to write <CR><LF> to .ini file");
|
||||
sprintf (line, "%s = %s", itemname, def_value);
|
||||
if (fwrite(line, 1, strlen(line), ini) != strlen(line) ||
|
||||
fwrite(&cr, 1, 2, ini) != 2)
|
||||
ERRLOG("Failed to write key,value line to .ini file");
|
||||
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;
|
||||
if (fgets(line,255,ini) == NULL) break;
|
||||
|
||||
// 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);
|
||||
if (fwrite(line, 1, strlen(line), ini) != strlen(line) ||
|
||||
fwrite(&cr, 1, 2, ini) != 2)
|
||||
{
|
||||
ERRLOG("Failed to write line '%s' to .ini file", line);
|
||||
}
|
||||
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);
|
||||
sprintf (line, "%s = %s", itemname, value);
|
||||
if (!last_line_ret)
|
||||
if (fwrite(&cr, 1, 2, ini) != 2)
|
||||
ERRLOG("Failed to write <CR> to .ini file");
|
||||
if (fwrite(line, 1, strlen(line), ini) != strlen(line) ||
|
||||
fwrite(&cr, 1, 2, ini) != 2)
|
||||
{
|
||||
ERRLOG("Failed to write line '%s' to .ini file", line);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
//nmn: Fix for MAX_PATH
|
||||
#include <limits.h>
|
||||
#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 );
|
||||
|
||||
class Ini
|
||||
{
|
||||
private:
|
||||
Ini();
|
||||
static Ini *singleton;
|
||||
public:
|
||||
static Ini *OpenIni();
|
||||
void SetPath(const char *path);
|
||||
bool Read(const char *key, int *l);
|
||||
bool Read(const char *key, int *l, int defaultVal);
|
||||
int Read(const char *key, int defaultVal);
|
||||
};
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Keys, used by Glide64.
|
||||
// Since key codes are different for WinAPI and SDL, this difference is managed here
|
||||
// Created by Sergey 'Gonetz' Lipski, July 2009
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#include "Gfx_1.3.h"
|
||||
|
||||
Glide64Keys::Glide64Keys()
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
_keys[G64_VK_CONTROL] = 0x11;
|
||||
_keys[G64_VK_ALT] = 0x12;
|
||||
_keys[G64_VK_INSERT] = 0x2D;
|
||||
_keys[G64_VK_LBUTTON] = 0x01;
|
||||
_keys[G64_VK_UP] = 0x26;
|
||||
_keys[G64_VK_DOWN] = 0x28;
|
||||
_keys[G64_VK_LEFT] = 0x25;
|
||||
_keys[G64_VK_RIGHT] = 0x27;
|
||||
_keys[G64_VK_SPACE] = 0x20;
|
||||
_keys[G64_VK_BACK] = 0x08;
|
||||
_keys[G64_VK_SCROLL] = 0x91;
|
||||
_keys[G64_VK_1] = 0x31;
|
||||
_keys[G64_VK_2] = 0x32;
|
||||
_keys[G64_VK_3] = 0x33;
|
||||
_keys[G64_VK_4] = 0x34;
|
||||
_keys[G64_VK_5] = 0x35;
|
||||
_keys[G64_VK_6] = 0x36;
|
||||
_keys[G64_VK_7] = 0x37;
|
||||
_keys[G64_VK_8] = 0x38;
|
||||
_keys[G64_VK_9] = 0x39;
|
||||
_keys[G64_VK_0] = 0x30;
|
||||
_keys[G64_VK_A] = 0x41;
|
||||
_keys[G64_VK_B] = 0x42;
|
||||
_keys[G64_VK_D] = 0x44;
|
||||
_keys[G64_VK_G] = 0x47;
|
||||
_keys[G64_VK_Q] = 0x51;
|
||||
_keys[G64_VK_R] = 0x52;
|
||||
_keys[G64_VK_S] = 0x53;
|
||||
_keys[G64_VK_V] = 0x56;
|
||||
_keys[G64_VK_W] = 0x57;
|
||||
#else
|
||||
_keys[G64_VK_CONTROL] = 306;
|
||||
_keys[G64_VK_ALT] = 308;
|
||||
_keys[G64_VK_INSERT] = 277;
|
||||
_keys[G64_VK_LBUTTON] = 1;
|
||||
_keys[G64_VK_UP] = 273;
|
||||
_keys[G64_VK_DOWN] = 274;
|
||||
_keys[G64_VK_LEFT] = 276;
|
||||
_keys[G64_VK_RIGHT] = 275;
|
||||
_keys[G64_VK_SPACE] = 32;
|
||||
_keys[G64_VK_BACK] = 8;
|
||||
_keys[G64_VK_SCROLL] = 302;
|
||||
_keys[G64_VK_1] = 49;
|
||||
_keys[G64_VK_2] = 50;
|
||||
_keys[G64_VK_3] = 51;
|
||||
_keys[G64_VK_4] = 52;
|
||||
_keys[G64_VK_5] = 53;
|
||||
_keys[G64_VK_6] = 54;
|
||||
_keys[G64_VK_7] = 55;
|
||||
_keys[G64_VK_8] = 56;
|
||||
_keys[G64_VK_9] = 57;
|
||||
_keys[G64_VK_0] = 48;
|
||||
_keys[G64_VK_A] = 97;
|
||||
_keys[G64_VK_B] = 98;
|
||||
_keys[G64_VK_D] = 100;
|
||||
_keys[G64_VK_G] = 103;
|
||||
_keys[G64_VK_Q] = 113;
|
||||
_keys[G64_VK_R] = 114;
|
||||
_keys[G64_VK_S] = 115;
|
||||
_keys[G64_VK_V] = 118;
|
||||
_keys[G64_VK_W] = 119;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Keys, used by Glide64.
|
||||
// Since key codes are different for WinAPI and SDL, this difference is managed here
|
||||
// Created by Sergey 'Gonetz' Lipski, July 2009
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef Keys_H
|
||||
#define Keys_H
|
||||
|
||||
#define G64_VK_CONTROL 0
|
||||
#define G64_VK_ALT 1
|
||||
#define G64_VK_INSERT 2
|
||||
#define G64_VK_LBUTTON 3
|
||||
#define G64_VK_UP 4
|
||||
#define G64_VK_DOWN 5
|
||||
#define G64_VK_LEFT 6
|
||||
#define G64_VK_RIGHT 7
|
||||
#define G64_VK_SPACE 8
|
||||
#define G64_VK_BACK 9
|
||||
#define G64_VK_SCROLL 10
|
||||
#define G64_VK_1 11
|
||||
#define G64_VK_2 12
|
||||
#define G64_VK_3 13
|
||||
#define G64_VK_4 14
|
||||
#define G64_VK_5 15
|
||||
#define G64_VK_6 16
|
||||
#define G64_VK_7 17
|
||||
#define G64_VK_8 18
|
||||
#define G64_VK_9 19
|
||||
#define G64_VK_0 20
|
||||
#define G64_VK_A 21
|
||||
#define G64_VK_B 22
|
||||
#define G64_VK_D 23
|
||||
#define G64_VK_G 24
|
||||
#define G64_VK_Q 25
|
||||
#define G64_VK_R 26
|
||||
#define G64_VK_S 27
|
||||
#define G64_VK_V 28
|
||||
#define G64_VK_W 29
|
||||
|
||||
#define G64_NUM_KEYS 30
|
||||
|
||||
class Glide64Keys
|
||||
{
|
||||
public:
|
||||
Glide64Keys();
|
||||
~Glide64Keys(){}
|
||||
int operator[](unsigned int index){return _keys[index];}
|
||||
|
||||
private:
|
||||
int _keys[G64_NUM_KEYS];
|
||||
};
|
||||
|
||||
#endif //Keys_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static inline void mirror16bS(uint8_t *tex, uint8_t *start, int width, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint16_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
|
||||
v8 = (uint16_t *)start;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v10 = 0;
|
||||
do
|
||||
{
|
||||
if ( width & (v10 + width) )
|
||||
{
|
||||
*v8 = *(uint16_t *)(&tex[mask] - (mask & 2 * v10));
|
||||
++v8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*v8 = *(uint16_t *)&tex[mask & 2 * v10];
|
||||
++v8;
|
||||
}
|
||||
++v10;
|
||||
}
|
||||
while ( v10 != count );
|
||||
v8 = (uint16_t *)((char *)v8 + line);
|
||||
tex += full;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
}
|
||||
|
||||
static inline void wrap16bS(uint8_t *tex, uint8_t *start, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
|
||||
v7 = (uint32_t *)start;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = 0;
|
||||
do
|
||||
{
|
||||
*v7 = *(uint32_t *)&tex[4 * (mask & v9)];
|
||||
++v7;
|
||||
++v9;
|
||||
}
|
||||
while ( v9 != count );
|
||||
v7 = (uint32_t *)((char *)v7 + line);
|
||||
tex += full;
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
static inline void clamp16bS(uint8_t *tex, uint8_t *constant, int height, int line, int full, int count)
|
||||
{
|
||||
uint16_t *v6;
|
||||
uint16_t *v7;
|
||||
int v8;
|
||||
uint16_t v9;
|
||||
int v10;
|
||||
|
||||
v6 = (uint16_t *)constant;
|
||||
v7 = (uint16_t *)tex;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = *v6;
|
||||
v10 = count;
|
||||
do
|
||||
{
|
||||
*v7 = v9;
|
||||
++v7;
|
||||
--v10;
|
||||
}
|
||||
while ( v10 );
|
||||
v6 = (uint16_t *)((char *)v6 + full);
|
||||
v7 = (uint16_t *)((char *)v7 + line);
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 16-bit Horizontal Mirror
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
typedef uint32_t wxUint32;
|
||||
|
||||
void Mirror16bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 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 << 1;
|
||||
int line = line_full - (count << 1);
|
||||
if (line < 0) return;
|
||||
unsigned char *start = tex + (mask_width << 1);
|
||||
mirror16bS (tex, start, mask_width, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 16-bit Horizontal Wrap (like mirror)
|
||||
|
||||
void Wrap16bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 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);
|
||||
wrap16bS (tex, start, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 16-bit Horizontal Clamp
|
||||
|
||||
void Clamp16bS (unsigned char * tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 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;
|
||||
|
||||
clamp16bS (dest, constant, real_height, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 16-bit Vertical Mirror
|
||||
|
||||
void Mirror16bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 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 (wxUint32 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 Vertical Wrap
|
||||
|
||||
void Wrap16bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 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 (wxUint32 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 Vertical Clamp
|
||||
|
||||
void Clamp16bT (unsigned char * tex, wxUint32 height, wxUint32 real_width, wxUint32 clamp_to)
|
||||
{
|
||||
int line_full = real_width << 1;
|
||||
unsigned char * dst = tex + height * line_full;
|
||||
unsigned char * const_line = dst - line_full;
|
||||
|
||||
for (wxUint32 y=height; y<clamp_to; y++)
|
||||
{
|
||||
memcpy ((void*)dst, (void*)const_line, line_full);
|
||||
dst += line_full;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Created by Gonetz, 2007
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static inline void mirror32bS(uint8_t *tex, uint8_t *start, int width, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint32_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
|
||||
v8 = (uint32_t *)start;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v10 = 0;
|
||||
do
|
||||
{
|
||||
if ( width & (v10 + width) )
|
||||
{
|
||||
*v8 = *(uint32_t *)(&tex[mask] - (mask & 4 * v10));
|
||||
++v8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*v8 = *(uint32_t *)&tex[mask & 4 * v10];
|
||||
++v8;
|
||||
}
|
||||
++v10;
|
||||
}
|
||||
while ( v10 != count );
|
||||
v8 = (uint32_t *)((char *)v8 + line);
|
||||
tex += full;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
}
|
||||
|
||||
static inline void wrap32bS(uint8_t *tex, uint8_t *start, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
|
||||
v7 = (uint32_t *)start;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = 0;
|
||||
do
|
||||
{
|
||||
*v7 = *(uint32_t *)&tex[4 * (mask & v9)];
|
||||
++v7;
|
||||
++v9;
|
||||
}
|
||||
while ( v9 != count );
|
||||
v7 = (uint32_t *)((char *)v7 + line);
|
||||
tex += full;
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
static inline void clamp32bS(uint8_t *tex, uint8_t *constant, int height, int line, int full, int count)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
uint32_t v9;
|
||||
int v10;
|
||||
|
||||
v6 = (uint32_t *)constant;
|
||||
v7 = (uint32_t *)tex;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = *v6;
|
||||
v10 = count;
|
||||
do
|
||||
{
|
||||
*v7 = v9;
|
||||
++v7;
|
||||
--v10;
|
||||
}
|
||||
while ( v10 );
|
||||
v6 = (uint32_t *)((char *)v6 + full);
|
||||
v7 = (uint32_t *)((char *)v7 + line);
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Horizontal Mirror
|
||||
|
||||
void Mirror32bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 mask_mask = (mask_width-1) << 2;
|
||||
if (mask_width >= max_width) return;
|
||||
int count = max_width - mask_width;
|
||||
if (count <= 0) return;
|
||||
int line_full = real_width << 2;
|
||||
int line = line_full - (count << 2);
|
||||
if (line < 0) return;
|
||||
unsigned char * start = tex + (mask_width << 2);
|
||||
mirror32bS (tex, start, mask_width, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Horizontal Wrap
|
||||
|
||||
void Wrap32bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 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 << 2;
|
||||
int line = line_full - (count << 2);
|
||||
if (line < 0) return;
|
||||
unsigned char * start = tex + (mask_width << 2);
|
||||
wrap32bS (tex, start, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Horizontal Clamp
|
||||
|
||||
void Clamp32bS (unsigned char * tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 real_height)
|
||||
{
|
||||
if (real_width <= width) return;
|
||||
|
||||
unsigned char *dest = tex + (width << 2);
|
||||
unsigned char *constant = dest-4;
|
||||
|
||||
int count = clamp_to - width;
|
||||
|
||||
int line_full = real_width << 2;
|
||||
int line = width << 2;
|
||||
clamp32bS (dest, constant, real_height, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Vertical Mirror
|
||||
|
||||
void Mirror32bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 mask_mask = mask_height-1;
|
||||
if (max_height <= mask_height) return;
|
||||
int line_full = real_width << 2;
|
||||
|
||||
unsigned char *dst = tex + mask_height * line_full;
|
||||
|
||||
for (wxUint32 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;
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Vertical Wrap
|
||||
|
||||
void Wrap32bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 mask_mask = mask_height-1;
|
||||
if (max_height <= mask_height) return;
|
||||
int line_full = real_width << 2;
|
||||
|
||||
unsigned char *dst = tex + mask_height * line_full;
|
||||
|
||||
for (wxUint32 y=mask_height; y<max_height; y++)
|
||||
{
|
||||
// not mirrored
|
||||
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * (line_full>>2)), (line_full>>2));
|
||||
|
||||
dst += line_full;
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 32-bit Vertical Clamp
|
||||
|
||||
void Clamp32bT (unsigned char * tex, wxUint32 height, wxUint32 real_width, wxUint32 clamp_to)
|
||||
{
|
||||
int line_full = real_width << 2;
|
||||
unsigned char *dst = tex + height * line_full;
|
||||
unsigned char *const_line = dst - line_full;
|
||||
|
||||
for (wxUint32 y=height; y<clamp_to; y++)
|
||||
{
|
||||
memcpy ((void*)dst, (void*)const_line, line_full);
|
||||
dst += line_full;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
//****************************************************************
|
||||
// 8-bit Horizontal Mirror
|
||||
|
||||
static inline void mirror8bS(uint8_t *tex, uint8_t *start, int width, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint8_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
|
||||
v8 = start;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v10 = 0;
|
||||
do
|
||||
{
|
||||
if ( width & (v10 + width) )
|
||||
*v8++ = *(&tex[mask] - (mask & v10));
|
||||
else
|
||||
*v8++ = tex[mask & v10];
|
||||
++v10;
|
||||
}
|
||||
while ( v10 != count );
|
||||
v8 += line;
|
||||
tex += full;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
}
|
||||
|
||||
static inline void wrap8bS(uint8_t *tex, uint8_t *start, int height, int mask, int line, int full, int count)
|
||||
{
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
|
||||
v7 = (uint32_t *)start;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = 0;
|
||||
do
|
||||
{
|
||||
*v7 = *(uint32_t *)&tex[4 * (mask & v9)];
|
||||
++v7;
|
||||
++v9;
|
||||
}
|
||||
while ( v9 != count );
|
||||
v7 = (uint32_t *)((char *)v7 + line);
|
||||
tex += full;
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
static inline void clamp8bS(uint8_t *tex, uint8_t *constant, int height, int line, int full, int count)
|
||||
{
|
||||
uint8_t *v6;
|
||||
uint8_t *v7;
|
||||
int v8;
|
||||
uint8_t v9;
|
||||
int v10;
|
||||
|
||||
v6 = constant;
|
||||
v7 = tex;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v9 = *v6;
|
||||
v10 = count;
|
||||
do
|
||||
{
|
||||
*v7++ = v9;
|
||||
--v10;
|
||||
}
|
||||
while ( v10 );
|
||||
v6 += full;
|
||||
v7 += line;
|
||||
--v8;
|
||||
}
|
||||
while ( v8 );
|
||||
}
|
||||
|
||||
void Mirror8bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 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);
|
||||
mirror8bS (tex, start, mask_width, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 8-bit Horizontal Wrap (like mirror) ** UNTESTED **
|
||||
|
||||
|
||||
void Wrap8bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_width = (1 << mask);
|
||||
wxUint32 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);
|
||||
wrap8bS (tex, start, height, mask_mask, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 8-bit Horizontal Clamp
|
||||
|
||||
|
||||
void Clamp8bS (unsigned char * tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 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;
|
||||
clamp8bS (dest, constant, real_height, line, line_full, count);
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// 8-bit Vertical Mirror
|
||||
|
||||
void Mirror8bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 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 (wxUint32 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 Vertical Wrap
|
||||
|
||||
void Wrap8bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
|
||||
{
|
||||
if (mask == 0) return;
|
||||
|
||||
wxUint32 mask_height = (1 << mask);
|
||||
wxUint32 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 (wxUint32 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 Vertical Clamp
|
||||
|
||||
void Clamp8bT (unsigned char * tex, wxUint32 height, wxUint32 real_width, wxUint32 clamp_to)
|
||||
{
|
||||
int line_full = real_width;
|
||||
unsigned char * dst = tex + height * line_full;
|
||||
unsigned char * const_line = dst - line_full;
|
||||
|
||||
for (wxUint32 y=height; y<clamp_to; y++)
|
||||
{
|
||||
memcpy ((void*)dst, (void*)const_line, line_full);
|
||||
dst += line_full;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,752 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Hardware frame buffer emulation
|
||||
// Dec 2003 created by Gonetz
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#include "Gfx_1.3.h"
|
||||
#include "TexBuffer.h"
|
||||
#include "CRC.h"
|
||||
|
||||
static TBUFF_COLOR_IMAGE * AllocateTextureBuffer(COLOR_IMAGE & cimage)
|
||||
{
|
||||
TBUFF_COLOR_IMAGE texbuf;
|
||||
texbuf.addr = cimage.addr;
|
||||
texbuf.end_addr = cimage.addr + ((cimage.width*cimage.height)<<cimage.size>>1);
|
||||
texbuf.width = cimage.width;
|
||||
texbuf.height = cimage.height;
|
||||
texbuf.format = cimage.format;
|
||||
texbuf.size = cimage.size;
|
||||
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;
|
||||
// texbuf.scr_height = texbuf.height * rdp.scale_y;
|
||||
|
||||
wxUint16 max_size = max((wxUint16)texbuf.scr_width, (wxUint16)texbuf.scr_height);
|
||||
if (max_size > voodoo.max_tex_size) //texture size is too large
|
||||
return 0;
|
||||
wxUint32 tex_size;
|
||||
//calculate LOD
|
||||
switch ((max_size-1) >> 6)
|
||||
{
|
||||
case 0:
|
||||
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;
|
||||
|
||||
texbuf.lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f;
|
||||
texbuf.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.u_scale = texbuf.lr_u / (float)(texbuf.width);
|
||||
texbuf.v_scale = texbuf.lr_v / (float)(texbuf.height);
|
||||
texbuf.cache = 0;
|
||||
texbuf.crc = 0;
|
||||
texbuf.t_mem = 0;
|
||||
|
||||
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, texbuf.lr_u, texbuf.lr_v, texbuf.u_scale, texbuf.v_scale);
|
||||
|
||||
wxUint32 required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2,
|
||||
texbuf.info.aspectRatioLog2, texbuf.info.format);
|
||||
//find free space
|
||||
for (int i = 0; i < voodoo.num_tmu; i++)
|
||||
{
|
||||
wxUint32 available = 0;
|
||||
wxUint32 top = 0;
|
||||
if (rdp.texbufs[i].count)
|
||||
{
|
||||
TBUFF_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1];
|
||||
if (rdp.read_whole_frame || rdp.motionblur)
|
||||
{
|
||||
if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i))
|
||||
{
|
||||
top = 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 = 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;
|
||||
}
|
||||
if (available >= required)
|
||||
{
|
||||
rdp.texbufs[i].count++;
|
||||
rdp.texbufs[i].clear_allowed = FALSE;
|
||||
texbuf.tex_addr = top;
|
||||
rdp.cur_tex_buf = i;
|
||||
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
|
||||
return 0;
|
||||
rdp.cur_tex_buf ^= 1;
|
||||
rdp.texbufs[rdp.cur_tex_buf].count = 1;
|
||||
rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE;
|
||||
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]);
|
||||
}
|
||||
|
||||
int 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;
|
||||
|
||||
int found = FALSE, search = TRUE;
|
||||
TBUFF_COLOR_IMAGE *texbuf = 0;
|
||||
wxUint32 addr = cimage.addr;
|
||||
if ((settings.hacks&hack_Banjo2) && cimage.status == ci_copy_self)
|
||||
addr = rdp.frame_buffers[rdp.copy_ci_index].addr;
|
||||
wxUint32 end_addr = addr + ((cimage.width*cimage.height)<<cimage.size>>1);
|
||||
if (rdp.motionblur)
|
||||
{
|
||||
// if (cimage.format != 0)
|
||||
// return FALSE;
|
||||
search = FALSE;
|
||||
}
|
||||
if (rdp.read_whole_frame)
|
||||
{
|
||||
if (settings.hacks&hack_PMario) //motion blur effects in Paper Mario
|
||||
{
|
||||
rdp.cur_tex_buf = rdp.acc_tex_buf;
|
||||
FRDP("\nread_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 < voodoo.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 = (wxUint16)cimage.format;
|
||||
if ((cimage.format != 0))
|
||||
texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
else
|
||||
texbuf->info.format = GR_TEXFMT_RGB_565;
|
||||
texbuf->crc = 0;
|
||||
texbuf->t_mem = 0;
|
||||
texbuf->tile = 0;
|
||||
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
|
||||
{
|
||||
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
|
||||
grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,
|
||||
texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );
|
||||
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(TBUFF_COLOR_IMAGE)*(rdp.texbufs[i].count-j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LRDP(" not searched");
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LRDP(" not found");
|
||||
texbuf = AllocateTextureBuffer(cimage);
|
||||
}
|
||||
else
|
||||
{
|
||||
LRDP(" found");
|
||||
}
|
||||
|
||||
if (!texbuf)
|
||||
{
|
||||
LRDP(" KO\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdp.acc_tex_buf = rdp.cur_tex_buf;
|
||||
rdp.cur_image = texbuf;
|
||||
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
|
||||
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.frame_buffer&fb_hwfbe_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);
|
||||
if (!rdp.offset_x_bak)
|
||||
{
|
||||
rdp.offset_x_bak = rdp.offset_x;
|
||||
rdp.offset_x = 0;
|
||||
}
|
||||
if (!rdp.offset_y_bak)
|
||||
{
|
||||
rdp.offset_y_bak = rdp.offset_y;
|
||||
rdp.offset_y = 0;
|
||||
}
|
||||
rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GrTextureFormat_t TexBufSetupCombiner(int force_rgb = FALSE)
|
||||
{
|
||||
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_TEXTURE,
|
||||
// GR_COMBINE_OTHER_CONSTANT,
|
||||
FXFALSE);
|
||||
grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
|
||||
GR_COMBINE_FACTOR_ONE,
|
||||
GR_COMBINE_LOCAL_NONE,
|
||||
GR_COMBINE_OTHER_TEXTURE,
|
||||
FXFALSE);
|
||||
// grConstantColorValue (0xFFFFFFFF);
|
||||
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.tbuff_tex) ? rdp.tbuff_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.tbuff_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;
|
||||
}
|
||||
|
||||
int CloseTextureBuffer(int draw)
|
||||
{
|
||||
if (!fullscreen || !rdp.cur_image)
|
||||
{
|
||||
LRDP("CloseTextureBuffer KO\n");
|
||||
return FALSE;
|
||||
}
|
||||
grRenderBuffer( GR_BUFFER_BACKBUFFER );
|
||||
rdp.offset_x = rdp.offset_x_bak;
|
||||
rdp.offset_y = rdp.offset_y_bak;
|
||||
rdp.offset_x_bak = rdp.offset_y_bak = 0;
|
||||
rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR;
|
||||
if (!draw)
|
||||
{
|
||||
LRDP("CloseTextureBuffer no draw, OK\n");
|
||||
rdp.cur_image = 0;
|
||||
return TRUE;
|
||||
}
|
||||
rdp.tbuff_tex = rdp.cur_image;
|
||||
rdp.cur_image = 0;
|
||||
rdp.tbuff_tex->info.format = TexBufSetupCombiner();
|
||||
float zero = 0.0f;
|
||||
float ul_x = rdp.offset_x;
|
||||
float ul_y = rdp.offset_y;
|
||||
float lr_x = rdp.tbuff_tex->scr_width + rdp.offset_x;
|
||||
float lr_y = rdp.tbuff_tex->scr_height + rdp.offset_y;
|
||||
float lr_u = rdp.tbuff_tex->lr_u;
|
||||
float lr_v = rdp.tbuff_tex->lr_v;
|
||||
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, zero, zero, zero, zero, {zero, zero, zero, zero} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },
|
||||
{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
|
||||
grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) );
|
||||
grClipWindow (0, 0, settings.res_x, settings.res_y);
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
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);
|
||||
}
|
||||
LRDP("CloseTextureBuffer draw, OK\n");
|
||||
rdp.tbuff_tex = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to)
|
||||
{
|
||||
if (!fullscreen)
|
||||
return FALSE;
|
||||
FRDP("CopyTextureBuffer from %08x to %08x\n", fb_from.addr, fb_to.addr);
|
||||
if (rdp.cur_image)
|
||||
{
|
||||
rdp.cur_image->crc = 0;
|
||||
if (rdp.cur_image->addr == fb_to.addr)
|
||||
return CloseTextureBuffer(TRUE);
|
||||
rdp.tbuff_tex = rdp.cur_image;
|
||||
}
|
||||
else if (!FindTextureBuffer(fb_from.addr, (wxUint16)fb_from.width))
|
||||
{
|
||||
LRDP("Can't find 'from' buffer.\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (!OpenTextureBuffer(fb_to))
|
||||
{
|
||||
LRDP("Can't open new buffer.\n");
|
||||
return CloseTextureBuffer(TRUE);
|
||||
}
|
||||
rdp.tbuff_tex->crc = 0;
|
||||
GrTextureFormat_t buf_format = rdp.tbuff_tex->info.format;
|
||||
rdp.tbuff_tex->info.format = GR_TEXFMT_RGB_565;
|
||||
TexBufSetupCombiner(TRUE);
|
||||
float ul_x = 0.0f;
|
||||
float ul_y = 0.0f;
|
||||
float lr_x = rdp.tbuff_tex->scr_width;
|
||||
float lr_y = rdp.tbuff_tex->scr_height;
|
||||
float zero = 0.0f;
|
||||
float lr_u = rdp.tbuff_tex->lr_u;
|
||||
float lr_v = rdp.tbuff_tex->lr_v;
|
||||
FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);
|
||||
|
||||
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },
|
||||
{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
|
||||
grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) );
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
grRenderBuffer( GR_BUFFER_BACKBUFFER );
|
||||
rdp.offset_x = rdp.offset_x_bak;
|
||||
rdp.offset_y = rdp.offset_y_bak;
|
||||
rdp.offset_x_bak = rdp.offset_y_bak = 0;
|
||||
AddOffset(v, 4);
|
||||
grClipWindow (0, 0, settings.res_x, settings.res_y);
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
rdp.tbuff_tex->info.format = buf_format;
|
||||
|
||||
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
|
||||
rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR;
|
||||
if (settings.fog && (rdp.flags & FOG_ENABLED))
|
||||
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
|
||||
LRDP("CopyTextureBuffer draw, OK\n");
|
||||
rdp.tbuff_tex = 0;
|
||||
rdp.cur_image = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CopyDepthBuffer()
|
||||
{
|
||||
if (!fullscreen)
|
||||
return FALSE;
|
||||
LRDP("CopyDepthBuffer. ");
|
||||
float bound = 1024.0f;
|
||||
GrLOD_t LOD = GR_LOD_LOG2_1024;
|
||||
if (settings.scr_res_x > 1024)
|
||||
{
|
||||
bound = 2048.0f;
|
||||
LOD = GR_LOD_LOG2_2048;
|
||||
}
|
||||
rdp.tbuff_tex = &(rdp.texbufs[0].images[0]);
|
||||
rdp.tbuff_tex->tmu = rdp.texbufs[0].tmu;
|
||||
rdp.tbuff_tex->info.format = GR_TEXFMT_RGB_565;
|
||||
rdp.tbuff_tex->info.smallLodLog2 = rdp.tbuff_tex->info.largeLodLog2 = LOD;
|
||||
rdp.tbuff_tex->info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
||||
TexBufSetupCombiner(TRUE);
|
||||
float ul_x = 0.0f;
|
||||
float ul_y = 0.0f;
|
||||
float lr_x = bound;
|
||||
float lr_y = bound;
|
||||
float zero = 0.0f;
|
||||
float lr_u = 255.5f;
|
||||
float lr_v = 255.5f;
|
||||
FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);
|
||||
|
||||
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },
|
||||
{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
|
||||
grAuxBufferExt( GR_BUFFER_AUXBUFFER );
|
||||
grTexSource( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) );
|
||||
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
|
||||
grTextureBufferExt( rdp.texbufs[1].tmu, rdp.texbufs[1].begin, LOD, LOD,
|
||||
GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH );
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
grRenderBuffer( GR_BUFFER_BACKBUFFER );
|
||||
grTextureAuxBufferExt( rdp.texbufs[1].tmu, rdp.texbufs[1].begin, LOD, LOD,
|
||||
GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH );
|
||||
grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT );
|
||||
|
||||
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);
|
||||
LRDP("CopyDepthBuffer draw, OK\n");
|
||||
rdp.tbuff_tex = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int SwapTextureBuffer()
|
||||
{
|
||||
if (!fullscreen || !rdp.tbuff_tex)
|
||||
return FALSE;
|
||||
LRDP("SwapTextureBuffer.");
|
||||
COLOR_IMAGE ci;
|
||||
ci.addr = rdp.tbuff_tex->addr;
|
||||
ci.format = rdp.tbuff_tex->format;
|
||||
ci.width = rdp.tbuff_tex->width;
|
||||
ci.height = rdp.tbuff_tex->height;
|
||||
ci.size = 2;
|
||||
ci.status = ci_main;
|
||||
ci.changed = FALSE;
|
||||
TBUFF_COLOR_IMAGE * texbuf = AllocateTextureBuffer(ci);
|
||||
if (!texbuf)
|
||||
{
|
||||
LRDP("Failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
TexBufSetupCombiner();
|
||||
|
||||
float ul_x = 0.0f;
|
||||
float ul_y = 0.0f;
|
||||
float lr_x = rdp.tbuff_tex->scr_width;
|
||||
float lr_y = rdp.tbuff_tex->scr_height;
|
||||
float zero = 0.0f;
|
||||
float lr_u = rdp.tbuff_tex->lr_u;
|
||||
float lr_v = rdp.tbuff_tex->lr_v;
|
||||
|
||||
// Make the vertices
|
||||
VERTEX v[4] = {
|
||||
{ ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} },
|
||||
{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },
|
||||
{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },
|
||||
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }
|
||||
};
|
||||
|
||||
grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) );
|
||||
texbuf->tile_uls = rdp.tbuff_tex->tile_uls;
|
||||
texbuf->tile_ult = rdp.tbuff_tex->tile_ult;
|
||||
texbuf->v_shift = rdp.tbuff_tex->v_shift;
|
||||
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
|
||||
grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,
|
||||
texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );
|
||||
grDrawTriangle (&v[0], &v[2], &v[1]);
|
||||
grDrawTriangle (&v[2], &v[3], &v[1]);
|
||||
rdp.texbufs[rdp.tbuff_tex->tmu].clear_allowed = TRUE;
|
||||
rdp.texbufs[rdp.tbuff_tex->tmu].count = 0;
|
||||
texbuf->tile_uls = rdp.tbuff_tex->tile_uls;
|
||||
texbuf->tile_ult = rdp.tbuff_tex->tile_ult;
|
||||
texbuf->u_shift = rdp.tbuff_tex->u_shift;
|
||||
texbuf->v_shift = rdp.tbuff_tex->v_shift;
|
||||
rdp.tbuff_tex = texbuf;
|
||||
if (rdp.cur_image)
|
||||
{
|
||||
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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
grRenderBuffer( GR_BUFFER_BACKBUFFER );
|
||||
rdp.offset_x = rdp.offset_x_bak;
|
||||
rdp.offset_y = rdp.offset_y_bak;
|
||||
rdp.offset_x_bak = rdp.offset_y_bak = 0;
|
||||
rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR;
|
||||
}
|
||||
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);
|
||||
}
|
||||
LRDP("SwapTextureBuffer draw, OK\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static wxUint32 CalcCRC(TBUFF_COLOR_IMAGE * pTCI)
|
||||
{
|
||||
wxUint32 result = 0;
|
||||
if ((settings.frame_buffer&fb_ref) > 0)
|
||||
pTCI->crc = 0; //Since fb content changes each frame, crc check is meaningless.
|
||||
else if (settings.fb_crc_mode == SETTINGS::fbcrcFast)
|
||||
result = *((wxUint32*)(gfx.RDRAM + pTCI->addr + (pTCI->end_addr-pTCI->addr)/2));
|
||||
else if (settings.fb_crc_mode == SETTINGS::fbcrcSafe)
|
||||
{
|
||||
wxUint8 * pSrc = gfx.RDRAM + pTCI->addr;
|
||||
const wxUint32 nSize = pTCI->end_addr-pTCI->addr;
|
||||
result = CRC32(0xFFFFFFFF, pSrc, 32);
|
||||
result = CRC32(result, pSrc + (nSize>>1), 32);
|
||||
result = CRC32(result, pSrc + nSize - 32, 32);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int FindTextureBuffer(wxUint32 addr, wxUint16 width)
|
||||
{
|
||||
if (rdp.skip_drawing)
|
||||
return FALSE;
|
||||
FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x);
|
||||
int found = FALSE;
|
||||
wxUint32 shift = 0;
|
||||
for (int i = 0; i < voodoo.num_tmu && !found; i++)
|
||||
{
|
||||
wxUint8 index = rdp.cur_tex_buf^i;
|
||||
for (int j = 0; j < rdp.texbufs[index].count && !found; j++)
|
||||
{
|
||||
rdp.tbuff_tex = &(rdp.texbufs[index].images[j]);
|
||||
if(addr >= rdp.tbuff_tex->addr && addr < rdp.tbuff_tex->end_addr)// && rdp.timg.format == 0)
|
||||
{
|
||||
bool bCorrect;
|
||||
if (rdp.tbuff_tex->crc == 0)
|
||||
{
|
||||
rdp.tbuff_tex->crc = CalcCRC(rdp.tbuff_tex);
|
||||
bCorrect = width == 1 || rdp.tbuff_tex->width == width || (rdp.tbuff_tex->width > 320 && rdp.tbuff_tex->width == width*2);
|
||||
}
|
||||
else
|
||||
bCorrect = rdp.tbuff_tex->crc == CalcCRC(rdp.tbuff_tex);
|
||||
if (bCorrect)
|
||||
{
|
||||
shift = addr - rdp.tbuff_tex->addr;
|
||||
// if (!rdp.motionblur)
|
||||
if (!rdp.cur_image)
|
||||
rdp.cur_tex_buf = index;
|
||||
found = TRUE;
|
||||
// FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.tbuff_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(TBUFF_COLOR_IMAGE)*(rdp.texbufs[index].count-j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
rdp.tbuff_tex->tile_uls = 0;
|
||||
rdp.tbuff_tex->tile_ult = 0;
|
||||
if (shift > 0)
|
||||
{
|
||||
shift >>= 1;
|
||||
rdp.tbuff_tex->v_shift = shift / rdp.tbuff_tex->width;
|
||||
rdp.tbuff_tex->u_shift = shift % rdp.tbuff_tex->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdp.tbuff_tex->v_shift = 0;
|
||||
rdp.tbuff_tex->u_shift = 0;
|
||||
}
|
||||
FRDP("FindTextureBuffer, found, u_shift: %d, v_shift: %d, format: %s\n", rdp.tbuff_tex->u_shift, rdp.tbuff_tex->v_shift, str_format[rdp.tbuff_tex->format]);
|
||||
//FRDP("Buffer, addr=%08lx, end_addr=%08lx, width: %d, height: %d\n", rdp.tbuff_tex->addr, rdp.tbuff_tex->end_addr, rdp.tbuff_tex->width, rdp.tbuff_tex->height);
|
||||
return TRUE;
|
||||
}
|
||||
rdp.tbuff_tex = 0;
|
||||
LRDP("FindTextureBuffer, not found\n");
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Hardware frame buffer emulation
|
||||
// Dec 2003 created by Gonetz
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef TEXBUFFER_H
|
||||
#define TEXBUFFER_H
|
||||
|
||||
int OpenTextureBuffer(COLOR_IMAGE & cimage);
|
||||
|
||||
int CloseTextureBuffer(int draw = FALSE);
|
||||
|
||||
int CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to);
|
||||
|
||||
int CopyDepthBuffer();
|
||||
|
||||
int SwapTextureBuffer();
|
||||
|
||||
int FindTextureBuffer(wxUint32 addr, wxUint16 width);
|
||||
|
||||
#endif // ifndef TEXBUFFER
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef TEXCACHE_H
|
||||
#define TEXCACHE_H
|
||||
|
||||
void TexCacheInit ();
|
||||
void TexCache ();
|
||||
void ClearCache ();
|
||||
|
||||
extern wxUint8 * texture_buffer;
|
||||
|
||||
#endif //TEXCACHE_H
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static inline void texConv_ARGB1555_ARGB4444(uint8_t *src, uint8_t *dst, int size)
|
||||
{
|
||||
uint32_t *v3;
|
||||
uint32_t *v4;
|
||||
int v5;
|
||||
uint32_t v6;
|
||||
uint32_t v7;
|
||||
|
||||
v3 = (uint32_t *)src;
|
||||
v4 = (uint32_t *)dst;
|
||||
v5 = size;
|
||||
do
|
||||
{
|
||||
v6 = *v3;
|
||||
++v3;
|
||||
v7 = v6;
|
||||
*v4 = ((v7 & 0x1E001E) >> 1) | ((v6 & 0x3C003C0) >> 2) | ((v6 & 0x78007800) >> 3) | ((v6 & 0x80008000) >> 3) | ((v6 & 0x80008000) >> 2) | ((v6 & 0x80008000) >> 1) | (v6 & 0x80008000);
|
||||
++v4;
|
||||
--v5;
|
||||
}
|
||||
while ( v5 );
|
||||
}
|
||||
|
||||
static inline void texConv_AI88_ARGB4444(uint8_t *src, uint8_t *dst, int size)
|
||||
{
|
||||
uint32_t *v3;
|
||||
uint32_t *v4;
|
||||
int v5;
|
||||
uint32_t v6;
|
||||
uint32_t v7;
|
||||
|
||||
v3 = (uint32_t *)src;
|
||||
v4 = (uint32_t *)dst;
|
||||
v5 = size;
|
||||
do
|
||||
{
|
||||
v6 = *v3;
|
||||
++v3;
|
||||
v7 = v6;
|
||||
*v4 = (16 * (v7 & 0xF000F0) >> 8) | (v7 & 0xF000F0) | (16 * (v7 & 0xF000F0)) | (v6 & 0xF000F000);
|
||||
++v4;
|
||||
--v5;
|
||||
}
|
||||
while ( v5 );
|
||||
}
|
||||
|
||||
static inline void texConv_AI44_ARGB4444(uint8_t *src, uint8_t *dst, int size)
|
||||
{
|
||||
uint32_t *v3;
|
||||
uint32_t *v4;
|
||||
int v5;
|
||||
uint32_t v6;
|
||||
uint32_t *v7;
|
||||
|
||||
v3 = (uint32_t *)src;
|
||||
v4 = (uint32_t *)dst;
|
||||
v5 = size;
|
||||
do
|
||||
{
|
||||
v6 = *v3;
|
||||
++v3;
|
||||
*v4 = ((((uint16_t)v6 << 8) & 0xFF00 & 0xF00u) >> 8) | ((((uint16_t)v6 << 8) & 0xFF00 & 0xF00u) >> 4) | (uint16_t)(((uint16_t)v6 << 8) & 0xFF00) | (((v6 << 16) & 0xF000000) >> 8) | (((v6 << 16) & 0xF000000) >> 4) | ((v6 << 16) & 0xFF000000);
|
||||
v7 = v4 + 1;
|
||||
*v7 = (((v6 >> 8) & 0xF00) >> 8) | (((v6 >> 8) & 0xF00) >> 4) | ((v6 >> 8) & 0xFF00) | ((v6 & 0xF000000) >> 8) | ((v6 & 0xF000000) >> 4) | (v6 & 0xFF000000);
|
||||
v4 = v7 + 1;
|
||||
--v5;
|
||||
}
|
||||
while ( v5 );
|
||||
}
|
||||
|
||||
static inline void texConv_A8_ARGB4444(uint8_t *src, uint8_t *dst, int size)
|
||||
{
|
||||
uint32_t *v3;
|
||||
uint32_t *v4;
|
||||
int v5;
|
||||
uint32_t v6;
|
||||
uint32_t v7;
|
||||
uint32_t *v8;
|
||||
|
||||
v3 = (uint32_t *)src;
|
||||
v4 = (uint32_t *)dst;
|
||||
v5 = size;
|
||||
do
|
||||
{
|
||||
v6 = *v3;
|
||||
++v3;
|
||||
v7 = v6;
|
||||
*v4 = ((v6 & 0xF0) << 8 >> 12) | (uint8_t)(v6 & 0xF0) | (16 * (uint8_t)(v6 & 0xF0) & 0xFFFFFFF) | ((uint8_t)(v6 & 0xF0) << 8) | (16 * (uint16_t)(v6 & 0xF000) & 0xFFFFF) | (((uint16_t)(v6 & 0xF000) << 8) & 0xFFFFFF) | (((uint16_t)(v6 & 0xF000) << 12) & 0xFFFFFFF) | ((uint16_t)(v6 & 0xF000) << 16);
|
||||
v8 = v4 + 1;
|
||||
*v8 = ((v7 & 0xF00000) >> 20) | ((v7 & 0xF00000) >> 16) | ((v7 & 0xF00000) >> 12) | ((v7 & 0xF00000) >> 8) | ((v6 & 0xF0000000) >> 12) | ((v6 & 0xF0000000) >> 8) | ((v6 & 0xF0000000) >> 4) | (v6 & 0xF0000000);
|
||||
v4 = v8 + 1;
|
||||
--v5;
|
||||
}
|
||||
while ( v5 );
|
||||
}
|
||||
|
||||
void TexConv_ARGB1555_ARGB4444 (unsigned char * src, unsigned char * dst, int width, int height)
|
||||
{
|
||||
int size = (width * height) >> 1; // Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
// 2 pixels are converted in one loop
|
||||
// NOTE: width * height must be a multiple of 2
|
||||
texConv_ARGB1555_ARGB4444(src, dst, size);
|
||||
}
|
||||
|
||||
void TexConv_AI88_ARGB4444 (unsigned char * src, unsigned char * dst, int width, int height)
|
||||
{
|
||||
int size = (width * height) >> 1; // Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
// 2 pixels are converted in one loop
|
||||
// NOTE: width * height must be a multiple of 2
|
||||
texConv_AI88_ARGB4444(src, dst, size);
|
||||
}
|
||||
|
||||
void TexConv_AI44_ARGB4444 (unsigned char * src, unsigned char * dst, int width, int height)
|
||||
{
|
||||
int size = (width * height) >> 2; // Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
// 4 pixels are converted in one loop
|
||||
// NOTE: width * height must be a multiple of 4
|
||||
texConv_AI44_ARGB4444(src, dst, size);
|
||||
}
|
||||
|
||||
void TexConv_A8_ARGB4444 (unsigned char * src, unsigned char * dst, int width, int height)
|
||||
{
|
||||
int size = (width * height) >> 2; // Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
// 4 pixels are converted in one loop
|
||||
// NOTE: width * height must be a multiple of 4
|
||||
texConv_A8_ARGB4444(src, dst, size);
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#include "TexLoad4b.h"
|
||||
#include "TexLoad8b.h"
|
||||
#include "TexLoad16b.h"
|
||||
#include "TexLoad32b.h"
|
||||
|
||||
wxUint32 LoadNone (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
memset (texture, 0, 4096*4);
|
||||
return (1 << 16) | GR_TEXFMT_ARGB_1555;
|
||||
}
|
||||
|
||||
typedef wxUint32 (*texfunc)(wxUIntPtr, wxUIntPtr, int, int, int, int, int);
|
||||
texfunc load_table [4][5] = { // [size][format]
|
||||
{ Load4bSelect,
|
||||
LoadNone,
|
||||
Load4bCI,
|
||||
Load4bIA,
|
||||
Load4bI },
|
||||
|
||||
{ Load8bCI,
|
||||
LoadNone,
|
||||
Load8bCI,
|
||||
Load8bIA,
|
||||
Load8bI },
|
||||
|
||||
{ Load16bRGBA,
|
||||
Load16bYUV,
|
||||
Load16bRGBA,
|
||||
Load16bIA,
|
||||
LoadNone },
|
||||
|
||||
{ Load32bRGBA,
|
||||
LoadNone,
|
||||
LoadNone,
|
||||
LoadNone,
|
||||
LoadNone }
|
||||
};
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static inline void load16bRGBA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
uint32_t v10;
|
||||
uint32_t v11;
|
||||
uint32_t *v12;
|
||||
uint32_t *v13;
|
||||
int v14;
|
||||
uint32_t v15;
|
||||
uint32_t v16;
|
||||
int v17;
|
||||
int v18;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v17 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = bswap32(*v6);
|
||||
v11 = bswap32(v6[1]);
|
||||
ALOWORD(v10) = __ROR__((uint16_t)v10, 1);
|
||||
ALOWORD(v11) = __ROR__((uint16_t)v11, 1);
|
||||
v10 = __ROR__(v10, 16);
|
||||
v11 = __ROR__(v11, 16);
|
||||
ALOWORD(v10) = __ROR__((uint16_t)v10, 1);
|
||||
ALOWORD(v11) = __ROR__((uint16_t)v11, 1);
|
||||
*v7 = v10;
|
||||
v7[1] = v11;
|
||||
v6 += 2;
|
||||
v7 += 2;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
if ( v17 == 1 )
|
||||
break;
|
||||
v18 = v17 - 1;
|
||||
v12 = (uint32_t *)&src[(line + (uintptr_t)v6 - (uintptr_t)src) & 0xFFF];
|
||||
v13 = (uint32_t *)((char *)v7 + ext);
|
||||
v14 = wid_64;
|
||||
do
|
||||
{
|
||||
v15 = bswap32(v12[1]);
|
||||
v16 = bswap32(*v12);
|
||||
ALOWORD(v15) = __ROR__((uint16_t)v15, 1);
|
||||
ALOWORD(v16) = __ROR__((uint16_t)v16, 1);
|
||||
v15 = __ROR__(v15, 16);
|
||||
v16 = __ROR__(v16, 16);
|
||||
ALOWORD(v15) = __ROR__((uint16_t)v15, 1);
|
||||
ALOWORD(v16) = __ROR__((uint16_t)v16, 1);
|
||||
*v13 = v15;
|
||||
v13[1] = v16;
|
||||
v12 += 2;
|
||||
v13 += 2;
|
||||
--v14;
|
||||
}
|
||||
while ( v14 );
|
||||
v6 = (uint32_t *)&src[(line + (uintptr_t)v12 - (uintptr_t)src) & 0xFFF];
|
||||
v7 = (uint32_t *)((char *)v13 + ext);
|
||||
v8 = v18 - 1;
|
||||
}
|
||||
while ( v18 != 1 );
|
||||
}
|
||||
|
||||
static inline void load16bIA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
uint32_t v10;
|
||||
uint32_t *v11;
|
||||
uint32_t *v12;
|
||||
int v13;
|
||||
uint32_t v14;
|
||||
int v15;
|
||||
int v16;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v15 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = v6[1];
|
||||
*v7 = *v6;
|
||||
v7[1] = v10;
|
||||
v6 += 2;
|
||||
v7 += 2;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
if ( v15 == 1 )
|
||||
break;
|
||||
v16 = v15 - 1;
|
||||
v11 = (uint32_t *)((char *)v6 + line);
|
||||
v12 = (uint32_t *)((char *)v7 + ext);
|
||||
v13 = wid_64;
|
||||
do
|
||||
{
|
||||
v14 = *v11;
|
||||
*v12 = v11[1];
|
||||
v12[1] = v14;
|
||||
v11 += 2;
|
||||
v12 += 2;
|
||||
--v13;
|
||||
}
|
||||
while ( v13 );
|
||||
v6 = (uint32_t *)((char *)v11 + line);
|
||||
v7 = (uint32_t *)((char *)v12 + ext);
|
||||
v8 = v16 - 1;
|
||||
}
|
||||
while ( v16 != 1 );
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************
|
||||
// Size: 2, Format: 0
|
||||
//
|
||||
|
||||
wxUint32 Load16bRGBA (wxUIntPtr dst, wxUIntPtr 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;
|
||||
|
||||
load16bRGBA((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
|
||||
return (1 << 16) | GR_TEXFMT_ARGB_1555;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 2, Format: 3
|
||||
//
|
||||
// ** by Gugaman/Dave2001 **
|
||||
|
||||
wxUint32 Load16bIA (wxUIntPtr dst, wxUIntPtr 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;
|
||||
|
||||
load16bIA((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
|
||||
return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 2, Format: 1
|
||||
//
|
||||
|
||||
wxUint16 yuv_to_rgb565(wxUint8 y, wxUint8 u, wxUint8 v)
|
||||
{
|
||||
//*
|
||||
float r = y + (1.370705f * (v-128));
|
||||
float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128));
|
||||
float b = y + (1.732446f * (u-128));
|
||||
r *= 0.125f;
|
||||
g *= 0.25f;
|
||||
b *= 0.125f;
|
||||
//clipping the result
|
||||
if (r > 31) r = 31;
|
||||
if (g > 63) g = 63;
|
||||
if (b > 31) b = 31;
|
||||
if (r < 0) r = 0;
|
||||
if (g < 0) g = 0;
|
||||
if (b < 0) b = 0;
|
||||
wxUint16 c = (wxUint16)(((wxUint16)(r) << 11) |
|
||||
((wxUint16)(g) << 5) |
|
||||
(wxUint16)(b) );
|
||||
return c;
|
||||
//*/
|
||||
/*
|
||||
const wxUint32 c = y - 16;
|
||||
const wxUint32 d = u - 128;
|
||||
const wxUint32 e = v - 128;
|
||||
|
||||
wxUint32 r = (298 * c + 409 * e + 128) & 0xf800;
|
||||
wxUint32 g = ((298 * c - 100 * d - 208 * e + 128) >> 5) & 0x7e0;
|
||||
wxUint32 b = ((298 * c + 516 * d + 128) >> 11) & 0x1f;
|
||||
|
||||
WORD texel = (WORD)(r | g | b);
|
||||
|
||||
return texel;
|
||||
*/
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 2, Format: 1
|
||||
//
|
||||
|
||||
wxUint32 Load16bYUV (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
wxUint32 * mb = (wxUint32*)(gfx.RDRAM+rdp.addr[rdp.tiles[tile].t_mem]); //pointer to the macro block
|
||||
wxUint16 * tex = (wxUint16*)dst;
|
||||
wxUint16 i;
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
wxUint32 t = mb[i]; //each wxUint32 contains 2 pixels
|
||||
wxUint8 y1 = (wxUint8)t&0xFF;
|
||||
wxUint8 v = (wxUint8)(t>>8)&0xFF;
|
||||
wxUint8 y0 = (wxUint8)(t>>16)&0xFF;
|
||||
wxUint8 u = (wxUint8)(t>>24)&0xFF;
|
||||
wxUint16 c = yuv_to_rgb565(y0, u, v);
|
||||
*(tex++) = c;
|
||||
c = yuv_to_rgb565(y1, u, v);
|
||||
*(tex++) = c;
|
||||
}
|
||||
return (1 << 16) | GR_TEXFMT_RGB_565;
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
#include "Gfx_1.3.h"
|
||||
|
||||
//****************************************************************
|
||||
// Size: 2, Format: 0
|
||||
//
|
||||
// Load 32bit RGBA texture
|
||||
// Based on sources of angrylion's software plugin.
|
||||
//
|
||||
wxUint32 Load32bRGBA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (height < 1) height = 1;
|
||||
const wxUint16 *tmem16 = (wxUint16*)rdp.tmem;
|
||||
const wxUint32 tbase = (src - (wxUIntPtr)rdp.tmem) >> 1;
|
||||
const wxUint32 width = max(1, wid_64 << 1);
|
||||
const int ext = real_width - width;
|
||||
line = width + (line>>2);
|
||||
wxUint32 s, t, c;
|
||||
wxUint32 * tex = (wxUint32*)dst;
|
||||
wxUint16 rg, ba;
|
||||
for (t = 0; t < (wxUint32)height; t++)
|
||||
{
|
||||
wxUint32 tline = tbase + line * t;
|
||||
wxUint32 xorval = (t & 1) ? 3 : 1;
|
||||
for (s = 0; s < width; s++)
|
||||
{
|
||||
wxUint32 taddr = ((tline + s) ^ xorval) & 0x3ff;
|
||||
rg = tmem16[taddr];
|
||||
ba = tmem16[taddr|0x400];
|
||||
c = ((ba&0xFF)<<24) | (rg << 8) | (ba>>8);
|
||||
*tex++ = c;
|
||||
}
|
||||
tex += ext;
|
||||
}
|
||||
int id = tile - rdp.cur_tile;
|
||||
wxUint32 mod = (id == 0) ? cmb.mod_0 : cmb.mod_1;
|
||||
if (mod || !voodoo.sup_32bit_tex)
|
||||
{
|
||||
//convert to ARGB_4444
|
||||
const wxUint32 tex_size = real_width * height;
|
||||
tex = (wxUint32 *)dst;
|
||||
wxUint16 *tex16 = (wxUint16*)dst;
|
||||
wxUint16 a, r, g, b;
|
||||
for (wxUint32 i = 0; i < tex_size; i++) {
|
||||
c = tex[i];
|
||||
a = (c >> 28) & 0xF;
|
||||
r = (c >> 20) & 0xF;
|
||||
g = (c >> 12) & 0xF;
|
||||
b = (c >> 4) & 0xF;
|
||||
tex16[i] = (a <<12) | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
return (1 << 16) | GR_TEXFMT_ARGB_4444;
|
||||
}
|
||||
return (2 << 16) | GR_TEXFMT_ARGB_8888;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// LoadTile for 32bit RGBA texture
|
||||
// Based on sources of angrylion's software plugin.
|
||||
//
|
||||
void LoadTile32b (wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 width, wxUint32 height)
|
||||
{
|
||||
const wxUint32 line = rdp.tiles[tile].line << 2;
|
||||
const wxUint32 tbase = rdp.tiles[tile].t_mem << 2;
|
||||
const wxUint32 addr = rdp.timg.addr >> 2;
|
||||
const wxUint32* src = (const wxUint32*)gfx.RDRAM;
|
||||
wxUint16 *tmem16 = (wxUint16*)rdp.tmem;
|
||||
wxUint32 c, ptr, tline, s, xorval;
|
||||
|
||||
for (wxUint32 j = 0; j < height; j++)
|
||||
{
|
||||
tline = tbase + line * j;
|
||||
s = ((j + ul_t) * rdp.timg.width) + ul_s;
|
||||
xorval = (j & 1) ? 3 : 1;
|
||||
for (wxUint32 i = 0; i < width; i++)
|
||||
{
|
||||
c = src[addr + s + i];
|
||||
ptr = ((tline + i) ^ xorval) & 0x3ff;
|
||||
tmem16[ptr] = c >> 16;
|
||||
tmem16[ptr|0x400] = c & 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// LoadBlock for 32bit RGBA texture
|
||||
// Based on sources of angrylion's software plugin.
|
||||
//
|
||||
void LoadBlock32b(wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 lr_s, wxUint32 dxt)
|
||||
{
|
||||
const wxUint32 * src = (const wxUint32*)gfx.RDRAM;
|
||||
const wxUint32 tb = rdp.tiles[tile].t_mem << 2;
|
||||
const wxUint32 tiwindwords = rdp.timg.width;
|
||||
const wxUint32 slindwords = ul_s;
|
||||
const wxUint32 line = rdp.tiles[tile].line << 2;
|
||||
|
||||
wxUint16 *tmem16 = (wxUint16*)rdp.tmem;
|
||||
wxUint32 addr = rdp.timg.addr >> 2;
|
||||
wxUint32 width = (lr_s - ul_s + 1) << 2;
|
||||
if (width & 7)
|
||||
width = (width & (~7)) + 8;
|
||||
|
||||
if (dxt != 0)
|
||||
{
|
||||
wxUint32 j= 0;
|
||||
wxUint32 t = 0;
|
||||
wxUint32 oldt = 0;
|
||||
wxUint32 ptr;
|
||||
|
||||
addr += (ul_t * tiwindwords) + slindwords;
|
||||
wxUint32 c = 0;
|
||||
for (wxUint32 i = 0; i < width; i += 2)
|
||||
{
|
||||
oldt = t;
|
||||
t = ((j >> 11) & 1) ? 3 : 1;
|
||||
if (t != oldt)
|
||||
i += line;
|
||||
ptr = ((tb + i) ^ t) & 0x3ff;
|
||||
c = src[addr + i];
|
||||
tmem16[ptr] = c >> 16;
|
||||
tmem16[ptr|0x400] = c & 0xffff;
|
||||
ptr = ((tb+ i + 1) ^ t) & 0x3ff;
|
||||
c = src[addr + i + 1];
|
||||
tmem16[ptr] = c >> 16;
|
||||
tmem16[ptr|0x400] = c & 0xffff;
|
||||
j += dxt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addr += (ul_t * tiwindwords) + slindwords;
|
||||
wxUint32 c, ptr;
|
||||
for (wxUint32 i = 0; i < width; i ++)
|
||||
{
|
||||
ptr = ((tb + i) ^ 1) & 0x3ff;
|
||||
c = src[addr + i];
|
||||
tmem16[ptr] = c >> 16;
|
||||
tmem16[ptr|0x400] = c & 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,663 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void load4bCI(uint8_t *src, uint8_t *dst, int wid_64, int height, uint16_t line, int ext, uint16_t *pal)
|
||||
{
|
||||
uint8_t *v7;
|
||||
uint8_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
int v11;
|
||||
uint32_t v12;
|
||||
uint8_t *v13;
|
||||
uint32_t v14;
|
||||
uint32_t *v15;
|
||||
uint32_t v16;
|
||||
uint8_t *v17;
|
||||
uint32_t *v18;
|
||||
int v19;
|
||||
int v20;
|
||||
uint32_t v21;
|
||||
uint32_t v22;
|
||||
uint32_t *v23;
|
||||
uint32_t v24;
|
||||
int v25;
|
||||
int v26;
|
||||
|
||||
v7 = src;
|
||||
v8 = dst;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v25 = v9;
|
||||
v10 = wid_64;
|
||||
do
|
||||
{
|
||||
v11 = v10;
|
||||
v12 = bswap32(*(uint32_t *)v7);
|
||||
v13 = v7 + 4;
|
||||
ALOWORD(v10) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 23) & 0x1E)), 1);
|
||||
v14 = v10 << 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 27) & 0x1E)), 1);
|
||||
*(uint32_t *)v8 = v14;
|
||||
v15 = (uint32_t *)(v8 + 4);
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 15) & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 19) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 7) & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 11) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v12 & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 3) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
v16 = bswap32(*(uint32_t *)v13);
|
||||
v7 = v13 + 4;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 23) & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 27) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 15) & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 19) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 7) & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 11) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v16 & 0x1E)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 3) & 0x1E)), 1);
|
||||
*v15 = v14;
|
||||
v8 = (uint8_t *)(v15 + 1);
|
||||
v10 = v11 - 1;
|
||||
}
|
||||
while ( v11 != 1 );
|
||||
if ( v25 == 1 )
|
||||
break;
|
||||
v26 = v25 - 1;
|
||||
v17 = &src[(line + (uintptr_t)v7 - (uintptr_t)src) & 0x7FF];
|
||||
v18 = (uint32_t *)&v8[ext];
|
||||
v19 = wid_64;
|
||||
do
|
||||
{
|
||||
v20 = v19;
|
||||
v21 = bswap32(*((uint32_t *)v17 + 1));
|
||||
ALOWORD(v19) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 23) & 0x1E)), 1);
|
||||
v22 = v19 << 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 27) & 0x1E)), 1);
|
||||
*v18 = v22;
|
||||
v23 = v18 + 1;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 15) & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 19) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 7) & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 11) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v21 & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 3) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
v24 = bswap32(*(uint32_t *)v17);
|
||||
v17 = &src[((uintptr_t)v17 + 8 - (uintptr_t)src) & 0x7FF];
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 23) & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 27) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 15) & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 19) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 7) & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 11) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v24 & 0x1E)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 3) & 0x1E)), 1);
|
||||
*v23 = v22;
|
||||
v18 = v23 + 1;
|
||||
v19 = v20 - 1;
|
||||
}
|
||||
while ( v20 != 1 );
|
||||
v7 = &src[(line + (uintptr_t)v17 - (uintptr_t)src) & 0x7FF];
|
||||
v8 = (uint8_t *)((char *)v18 + ext);
|
||||
v9 = v26 - 1;
|
||||
}
|
||||
while ( v26 != 1 );
|
||||
}
|
||||
|
||||
static inline void load4bIAPal(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal)
|
||||
{
|
||||
uint8_t *v7;
|
||||
uint32_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
int v11;
|
||||
uint32_t v12;
|
||||
uint32_t *v13;
|
||||
uint32_t v14;
|
||||
uint32_t *v15;
|
||||
uint32_t v16;
|
||||
uint8_t *v17;
|
||||
uint32_t *v18;
|
||||
int v19;
|
||||
int v20;
|
||||
uint32_t v21;
|
||||
uint32_t v22;
|
||||
uint32_t *v23;
|
||||
uint32_t v24;
|
||||
int v25;
|
||||
int v26;
|
||||
|
||||
v7 = src;
|
||||
v8 = (uint32_t *)dst;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v25 = v9;
|
||||
v10 = wid_64;
|
||||
do
|
||||
{
|
||||
v11 = v10;
|
||||
v12 = bswap32(*(uint32_t *)v7);
|
||||
v13 = (uint32_t *)(v7 + 4);
|
||||
ALOWORD(v10) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 23) & 0x1E)), 8);
|
||||
v14 = v10 << 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 27) & 0x1E)), 8);
|
||||
*v8 = v14;
|
||||
v15 = v8 + 1;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 15) & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 19) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 7) & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 11) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v12 & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 3) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
v16 = bswap32(*v13);
|
||||
v7 = (uint8_t *)(v13 + 1);
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 23) & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 27) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 15) & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 19) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 7) & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 11) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v16 & 0x1E)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 3) & 0x1E)), 8);
|
||||
*v15 = v14;
|
||||
v8 = v15 + 1;
|
||||
v10 = v11 - 1;
|
||||
}
|
||||
while ( v11 != 1 );
|
||||
if ( v25 == 1 )
|
||||
break;
|
||||
v26 = v25 - 1;
|
||||
v17 = &src[(line + (uintptr_t)v7 - (uintptr_t)src) & 0x7FF];
|
||||
v18 = (uint32_t *)((char *)v8 + ext);
|
||||
v19 = wid_64;
|
||||
do
|
||||
{
|
||||
v20 = v19;
|
||||
v21 = bswap32(*((uint32_t *)v17 + 1));
|
||||
ALOWORD(v19) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 23) & 0x1E)), 8);
|
||||
v22 = v19 << 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 27) & 0x1E)), 8);
|
||||
*v18 = v22;
|
||||
v23 = v18 + 1;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 15) & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 19) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 7) & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 11) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v21 & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 3) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
v24 = bswap32(*(uint32_t *)v17);
|
||||
v17 = &src[((uintptr_t)v17 + 8 - (uintptr_t)src) & 0x7FF];
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 23) & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 27) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 15) & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 19) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 7) & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 11) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint8_t)v24 & 0x1E)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 3) & 0x1E)), 8);
|
||||
*v23 = v22;
|
||||
v18 = v23 + 1;
|
||||
v19 = v20 - 1;
|
||||
}
|
||||
while ( v20 != 1 );
|
||||
v7 = &src[(line + (uintptr_t)v17 - (uintptr_t)src) & 0x7FF];
|
||||
v8 = (uint32_t *)((char *)v18 + ext);
|
||||
v9 = v26 - 1;
|
||||
}
|
||||
while ( v26 != 1 );
|
||||
}
|
||||
|
||||
static inline void load4bIA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
int v10;
|
||||
uint32_t v11;
|
||||
uint32_t *v12;
|
||||
uint32_t v13;
|
||||
uint32_t v14;
|
||||
uint32_t v15;
|
||||
uint32_t *v16;
|
||||
uint32_t v17;
|
||||
uint32_t v18;
|
||||
uint32_t v19;
|
||||
uint32_t v20;
|
||||
uint32_t v21;
|
||||
uint32_t v22;
|
||||
uint32_t v23;
|
||||
uint32_t v24;
|
||||
uint32_t v25;
|
||||
uint32_t v26;
|
||||
uint32_t v27;
|
||||
uint32_t v28;
|
||||
uint32_t v29;
|
||||
uint32_t v30;
|
||||
uint32_t v31;
|
||||
uint32_t v32;
|
||||
uint32_t *v33;
|
||||
uint32_t *v34;
|
||||
int v35;
|
||||
int v36;
|
||||
uint32_t v37;
|
||||
uint32_t v38;
|
||||
uint32_t v39;
|
||||
uint32_t *v40;
|
||||
uint32_t v41;
|
||||
uint32_t v42;
|
||||
uint32_t v43;
|
||||
uint32_t v44;
|
||||
uint32_t v45;
|
||||
uint32_t v46;
|
||||
uint32_t v47;
|
||||
uint32_t v48;
|
||||
uint32_t v49;
|
||||
uint32_t v50;
|
||||
uint32_t v51;
|
||||
uint32_t v52;
|
||||
uint32_t v53;
|
||||
uint32_t v54;
|
||||
uint32_t v55;
|
||||
uint32_t v56;
|
||||
int v57;
|
||||
int v58;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v57 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = v9;
|
||||
v11 = bswap32(*v6);
|
||||
v12 = v6 + 1;
|
||||
v13 = v11;
|
||||
v14 = (8 * (v11 & 0x100000)) | (4 * (v11 & 0x100000)) | (2 * (v11 & 0x100000)) | (v11 & 0x100000) | ((((v11 >> 16) & 0xE00) >> 3) & 0x100) | ((v11 >> 16) & 0xE00) | (8 * ((v11 >> 12) & 0x1000)) | (4 * ((v11 >> 12) & 0x1000)) | (2 * ((v11 >> 12) & 0x1000)) | ((v11 >> 12) & 0x1000) | ((((v11 >> 28) & 0xE) >> 3)) | ((v11 >> 28) & 0xE) | (8 * ((v11 >> 24) & 0x10)) | (4 * ((v11 >> 24) & 0x10)) | (2 * ((v11 >> 24) & 0x10)) | ((v11 >> 24) & 0x10);
|
||||
v11 >>= 4;
|
||||
v11 &= 0xE0000u;
|
||||
v15 = v11 | v14;
|
||||
v11 >>= 3;
|
||||
*v7 = ((((v13 << 8) & 0xE000000) >> 3) & 0x1000000) | ((v13 << 8) & 0xE000000) | (8 * ((v13 << 12) & 0x10000000)) | (4 * ((v13 << 12) & 0x10000000)) | (2 * ((v13 << 12) & 0x10000000)) | ((v13 << 12) & 0x10000000) | (v11 & 0x10000) | v15;
|
||||
v16 = v7 + 1;
|
||||
v17 = 16 * (uint16_t)v13 & 0x1000;
|
||||
v18 = (((v13 & 0xE00) >> 3) & 0x100) | (v13 & 0xE00) | (8 * v17) | (4 * v17) | (2 * v17) | (v17) | ((((v13 >> 12) & 0xE) >> 3)) | ((v13 >> 12) & 0xE) | (8 * ((v13 >> 8) & 0x10)) | (4 * ((v13 >> 8) & 0x10)) | (2 * ((v13 >> 8) & 0x10)) | ((v13 >> 8) & 0x10);
|
||||
v19 = v13 << 16;
|
||||
v20 = (8 * (v19 & 0x100000)) | (4 * (v19 & 0x100000)) | (2 * (v19 & 0x100000)) | (v19 & 0x100000) | v18;
|
||||
v21 = v13 << 12;
|
||||
v21 &= 0xE0000u;
|
||||
v22 = v21 | v20;
|
||||
v21 >>= 3;
|
||||
*v16 = ((((v13 << 24) & 0xE000000) >> 3) & 0x1000000) | ((v13 << 24) & 0xE000000) | (8 * ((v13 << 28) & 0x10000000)) | (4 * ((v13 << 28) & 0x10000000)) | (2 * ((v13 << 28) & 0x10000000)) | ((v13 << 28) & 0x10000000) | (v21 & 0x10000) | v22;
|
||||
++v16;
|
||||
v23 = bswap32(*v12);
|
||||
v6 = v12 + 1;
|
||||
v24 = v23;
|
||||
v25 = (8 * (v23 & 0x100000)) | (4 * (v23 & 0x100000)) | (2 * (v23 & 0x100000)) | (v23 & 0x100000) | ((((v23 >> 16) & 0xE00) >> 3) & 0x100) | ((v23 >> 16) & 0xE00) | (8 * ((v23 >> 12) & 0x1000)) | (4 * ((v23 >> 12) & 0x1000)) | (2 * ((v23 >> 12) & 0x1000)) | ((v23 >> 12) & 0x1000) | (((v23 >> 28) & 0xE) >> 3) | ((v23 >> 28) & 0xE) | (8 * ((v23 >> 24) & 0x10)) | (4 * ((v23 >> 24) & 0x10)) | (2 * ((v23 >> 24) & 0x10)) | ((v23 >> 24) & 0x10);
|
||||
v23 >>= 4;
|
||||
v23 &= 0xE0000u;
|
||||
v26 = v23 | v25;
|
||||
v23 >>= 3;
|
||||
*v16 = ((((v24 << 8) & 0xE000000) >> 3) & 0x1000000) | ((v24 << 8) & 0xE000000) | (8 * ((v24 << 12) & 0x10000000)) | (4 * ((v24 << 12) & 0x10000000)) | (2 * ((v24 << 12) & 0x10000000)) | ((v24 << 12) & 0x10000000) | (v23 & 0x10000) | (v26);
|
||||
++v16;
|
||||
v27 = 16 * (uint16_t)v24 & 0x1000;
|
||||
v28 = (((v24 & 0xE00) >> 3) & 0x100) | (v24 & 0xE00) | (8 * v27) | (4 * v27) | (2 * v27) | (v27) | ((((v24 >> 12) & 0xE) >> 3)) | ((v24 >> 12) & 0xE) | (8 * ((v24 >> 8) & 0x10)) | (4 * ((v24 >> 8) & 0x10)) | (2 * ((v24 >> 8) & 0x10)) | ((v24 >> 8) & 0x10);
|
||||
v29 = v24 << 16;
|
||||
v30 = (8 * (v29 & 0x100000)) | (4 * (v29 & 0x100000)) | (2 * (v29 & 0x100000)) | (v29 & 0x100000) | v28;
|
||||
v31 = v24 << 12;
|
||||
v31 &= 0xE0000u;
|
||||
v32 = v31 | v30;
|
||||
v31 >>= 3;
|
||||
*v16 = ((((v24 << 24) & 0xE000000) >> 3) & 0x1000000) | ((v24 << 24) & 0xE000000) | (8 * ((v24 << 28) & 0x10000000)) | (4 * ((v24 << 28) & 0x10000000)) | (2 * ((v24 << 28) & 0x10000000)) | ((v24 << 28) & 0x10000000) | (v31 & 0x10000) | v32;
|
||||
v7 = v16 + 1;
|
||||
v9 = v10 - 1;
|
||||
}
|
||||
while ( v10 != 1 );
|
||||
if ( v57 == 1 )
|
||||
break;
|
||||
v58 = v57 - 1;
|
||||
v33 = (uint32_t *)((char *)v6 + line);
|
||||
v34 = (uint32_t *)((char *)v7 + ext);
|
||||
v35 = wid_64;
|
||||
do
|
||||
{
|
||||
v36 = v35;
|
||||
v37 = bswap32(v33[1]);
|
||||
v38 = v37 >> 4;
|
||||
v38 &= 0xE0000u;
|
||||
v39 = v38 | (8 * (v37 & 0x100000)) | (4 * (v37 & 0x100000)) | (2 * (v37 & 0x100000)) | (v37 & 0x100000) | ((((v37 >> 16) & 0xE00) >> 3) & 0x100) | ((v37 >> 16) & 0xE00) | (8 * ((v37 >> 12) & 0x1000)) | (4 * ((v37 >> 12) & 0x1000)) | (2 * ((v37 >> 12) & 0x1000)) | ((v37 >> 12) & 0x1000) | (((v37 >> 28) & 0xE) >> 3) | ((v37 >> 28) & 0xE) | (8 * ((v37 >> 24) & 0x10)) | (4 * ((v37 >> 24) & 0x10)) | (2 * ((v37 >> 24) & 0x10)) | ((v37 >> 24) & 0x10);
|
||||
v38 >>= 3;
|
||||
*v34 = ((((v37 << 8) & 0xE000000) >> 3) & 0x1000000) | ((v37 << 8) & 0xE000000) | (8 * ((v37 << 12) & 0x10000000)) | (4 * ((v37 << 12) & 0x10000000)) | (2 * ((v37 << 12) & 0x10000000)) | ((v37 << 12) & 0x10000000) | (v38 & 0x10000) | v39;
|
||||
v40 = v34 + 1;
|
||||
v41 = 16 * (uint16_t)v37 & 0x1000;
|
||||
v42 = (((v37 & 0xE00) >> 3) & 0x100) | (v37 & 0xE00) | (8 * v41) | (4 * v41) | (2 * v41) | v41 | (((v37 >> 12) & 0xE) >> 3) | ((v37 >> 12) & 0xE) | (8 * ((v37 >> 8) & 0x10)) | (4 * ((v37 >> 8) & 0x10)) | (2 * ((v37 >> 8) & 0x10)) | ((v37 >> 8) & 0x10);
|
||||
v43 = v37 << 16;
|
||||
v44 = (8 * (v43 & 0x100000)) | (4 * (v43 & 0x100000)) | (2 * (v43 & 0x100000)) | (v43 & 0x100000) | v42;
|
||||
v45 = v37 << 12;
|
||||
v45 &= 0xE0000u;
|
||||
v46 = v45 | v44;
|
||||
v45 >>= 3;
|
||||
*v40 = ((((v37 << 24) & 0xE000000) >> 3) & 0x1000000) | ((v37 << 24) & 0xE000000) | (8 * ((v37 << 28) & 0x10000000)) | (4 * ((v37 << 28) & 0x10000000)) | (2 * ((v37 << 28) & 0x10000000)) | ((v37 << 28) & 0x10000000) | (v45 & 0x10000) | v46;
|
||||
++v40;
|
||||
v47 = bswap32(*v33);
|
||||
v33 += 2;
|
||||
v48 = v47;
|
||||
v49 = (8 * (v47 & 0x100000)) | (4 * (v47 & 0x100000)) | (2 * (v47 & 0x100000)) | (v47 & 0x100000) | ((((v47 >> 16) & 0xE00) >> 3) & 0x100) | ((v47 >> 16) & 0xE00) | (8 * ((v47 >> 12) & 0x1000)) | (4 * ((v47 >> 12) & 0x1000)) | (2 * ((v47 >> 12) & 0x1000)) | ((v47 >> 12) & 0x1000) | (((v47 >> 28) & 0xE) >> 3) | ((v47 >> 28) & 0xE) | (8 * ((v47 >> 24) & 0x10)) | (4 * ((v47 >> 24) & 0x10)) | (2 * ((v47 >> 24) & 0x10)) | ((v47 >> 24) & 0x10);
|
||||
v47 >>= 4;
|
||||
v47 &= 0xE0000u;
|
||||
v50 = v47 | v49;
|
||||
v47 >>= 3;
|
||||
*v40 = ((((v48 << 8) & 0xE000000) >> 3) & 0x1000000) | ((v48 << 8) & 0xE000000) | (8 * ((v48 << 12) & 0x10000000)) | (4 * ((v48 << 12) & 0x10000000)) | (2 * ((v48 << 12) & 0x10000000)) | ((v48 << 12) & 0x10000000) | (v47 & 0x10000) | v50;
|
||||
++v40;
|
||||
v51 = 16 * (uint16_t)v48 & 0x1000;
|
||||
v52 = (((v48 & 0xE00) >> 3) & 0x100) | (v48 & 0xE00) | (8 * v51) | (4 * v51) | (2 * v51) | v51 | (((v48 >> 12) & 0xE) >> 3) | ((v48 >> 12) & 0xE) | (8 * ((v48 >> 8) & 0x10)) | (4 * ((v48 >> 8) & 0x10)) | (2 * ((v48 >> 8) & 0x10)) | ((v48 >> 8) & 0x10);
|
||||
v53 = v48 << 16;
|
||||
v54 = (8 * (v53 & 0x100000)) | (4 * (v53 & 0x100000)) | (2 * (v53 & 0x100000)) | (v53 & 0x100000) | v52;
|
||||
v55 = v48 << 12;
|
||||
v55 &= 0xE0000u;
|
||||
v56 = v55 | v54;
|
||||
v55 >>= 3;
|
||||
*v40 = ((((v48 << 24) & 0xE000000) >> 3) & 0x1000000) | ((v48 << 24) & 0xE000000) | (8 * ((v48 << 28) & 0x10000000)) | (4 * ((v48 << 28) & 0x10000000)) | (2 * ((v48 << 28) & 0x10000000)) | ((v48 << 28) & 0x10000000) | (v55 & 0x10000) | v56;
|
||||
v34 = v40 + 1;
|
||||
v35 = v36 - 1;
|
||||
}
|
||||
while ( v36 != 1 );
|
||||
v6 = (uint32_t *)((char *)v33 + line);
|
||||
v7 = (uint32_t *)((char *)v34 + ext);
|
||||
v8 = v58 - 1;
|
||||
}
|
||||
while ( v58 != 1 );
|
||||
}
|
||||
|
||||
static inline void load4bI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
int v10;
|
||||
uint32_t v11;
|
||||
uint32_t *v12;
|
||||
uint32_t v13;
|
||||
uint32_t v14;
|
||||
uint32_t *v15;
|
||||
uint32_t v16;
|
||||
unsigned int v17;
|
||||
unsigned int v18;
|
||||
uint32_t v19;
|
||||
uint32_t v20;
|
||||
uint32_t *v21;
|
||||
uint32_t *v22;
|
||||
int v23;
|
||||
int v24;
|
||||
uint32_t v25;
|
||||
uint32_t v26;
|
||||
uint32_t *v27;
|
||||
uint32_t v28;
|
||||
uint32_t v29;
|
||||
uint32_t v30;
|
||||
uint32_t v31;
|
||||
uint32_t v32;
|
||||
int v33;
|
||||
int v34;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v33 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = v9;
|
||||
v11 = bswap32(*v6);
|
||||
v12 = v6 + 1;
|
||||
v13 = v11;
|
||||
v14 = (16 * ((v11 >> 16) & 0xF00)) | ((v11 >> 16) & 0xF00) | (16 * (v11 >> 28)) | (v11 >> 28);
|
||||
v11 >>= 4;
|
||||
*v7 = (16 * ((v13 << 8) & 0xF000000)) | ((v13 << 8) & 0xF000000) | (16 * (v11 & 0xF0000)) | (v11 & 0xF0000) | v14;
|
||||
v15 = v7 + 1;
|
||||
v16 = v13 << 12;
|
||||
*v15 = (16 * ((v13 << 24) & 0xF000000)) | ((v13 << 24) & 0xF000000) | (16 * (v16 & 0xF0000)) | (v16 & 0xF0000) | (16 * (v13 & 0xF00)) | (v13 & 0xF00) | (16 * ((uint16_t)v13 >> 12)) | ((uint16_t)v13 >> 12);
|
||||
++v15;
|
||||
v17 = bswap32(*v12);
|
||||
v6 = v12 + 1;
|
||||
v18 = v17;
|
||||
v19 = (16 * ((v17 >> 16) & 0xF00)) | ((v17 >> 16) & 0xF00) | (16 * (v17 >> 28)) | (v17 >> 28);
|
||||
v17 >>= 4;
|
||||
*v15 = (16 * ((v18 << 8) & 0xF000000)) | ((v18 << 8) & 0xF000000) | (16 * (v17 & 0xF0000)) | (v17 & 0xF0000) | v19;
|
||||
++v15;
|
||||
v20 = v18 << 12;
|
||||
*v15 = (16 * ((v18 << 24) & 0xF000000)) | ((v18 << 24) & 0xF000000) | (16 * (v20 & 0xF0000)) | (v20 & 0xF0000) | (16 * (v18 & 0xF00)) | (v18 & 0xF00) | (16 * ((uint16_t)v18 >> 12)) | ((uint16_t)v18 >> 12);
|
||||
v7 = v15 + 1;
|
||||
v9 = v10 - 1;
|
||||
}
|
||||
while ( v10 != 1 );
|
||||
if ( v33 == 1 )
|
||||
break;
|
||||
v34 = v33 - 1;
|
||||
v21 = (uint32_t *)((char *)v6 + line);
|
||||
v22 = (uint32_t *)((char *)v7 + ext);
|
||||
v23 = wid_64;
|
||||
do
|
||||
{
|
||||
v24 = v23;
|
||||
v25 = bswap32(v21[1]);
|
||||
v26 = v25 >> 4;
|
||||
*v22 = (16 * ((v25 << 8) & 0xF000000)) | ((v25 << 8) & 0xF000000) | (16 * (v26 & 0xF0000)) | (v26 & 0xF0000) | (16 * ((v25 >> 16) & 0xF00)) | ((v25 >> 16) & 0xF00) | (16 * (v25 >> 28)) | (v25 >> 28);
|
||||
v27 = v22 + 1;
|
||||
v28 = v25 << 12;
|
||||
*v27 = (16 * ((v25 << 24) & 0xF000000)) | ((v25 << 24) & 0xF000000) | (16 * (v28 & 0xF0000)) | (v28 & 0xF0000) | (16 * (v25 & 0xF00)) | (v25 & 0xF00) | (16 * ((uint16_t)v25 >> 12)) | ((uint16_t)v25 >> 12);
|
||||
++v27;
|
||||
v29 = bswap32(*v21);
|
||||
v21 += 2;
|
||||
v30 = v29;
|
||||
v31 = (16 * ((v29 >> 16) & 0xF00)) | ((v29 >> 16) & 0xF00) | (16 * (v29 >> 28)) | (v29 >> 28);
|
||||
v29 >>= 4;
|
||||
*v27 = (16 * ((v30 << 8) & 0xF000000)) | ((v30 << 8) & 0xF000000) | (16 * (v29 & 0xF0000)) | (v29 & 0xF0000) | v31;
|
||||
++v27;
|
||||
v32 = v30 << 12;
|
||||
*v27 = (16 * ((v30 << 24) & 0xF000000)) | ((v30 << 24) & 0xF000000) | (16 * (v32 & 0xF0000)) | (v32 & 0xF0000) | (16 * (v30 & 0xF00)) | (v30 & 0xF00) | (16 * ((uint16_t)v30 >> 12)) | ((uint16_t)v30 >> 12);
|
||||
v22 = v27 + 1;
|
||||
v23 = v24 - 1;
|
||||
}
|
||||
while ( v24 != 1 );
|
||||
v6 = (uint32_t *)((char *)v21 + line);
|
||||
v7 = (uint32_t *)((char *)v22 + ext);
|
||||
v8 = v34 - 1;
|
||||
}
|
||||
while ( v34 != 1 );
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 0, Format: 2
|
||||
|
||||
wxUint32 Load4bCI (wxUIntPtr dst, wxUIntPtr 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 << 4)) << 1;
|
||||
|
||||
if (rdp.tlut_mode == 0)
|
||||
{
|
||||
//in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference.
|
||||
//Thanks to angrylion for the advice
|
||||
load4bI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44;
|
||||
}
|
||||
|
||||
wxUIntPtr pal = wxPtrToUInt(rdp.pal_8 + (rdp.tiles[tile].palette << 4));
|
||||
if (rdp.tlut_mode == 2)
|
||||
{
|
||||
load4bCI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext, (uint16_t *)pal);
|
||||
|
||||
return (1 << 16) | GR_TEXFMT_ARGB_1555;
|
||||
}
|
||||
|
||||
load4bIAPal ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext, (uint16_t *)pal);
|
||||
return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 0, Format: 3
|
||||
//
|
||||
// ** BY GUGAMAN **
|
||||
|
||||
wxUint32 Load4bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (rdp.tlut_mode != 0)
|
||||
return Load4bCI (dst, src, wid_64, height, line, real_width, tile);
|
||||
|
||||
if (wid_64 < 1) wid_64 = 1;
|
||||
if (height < 1) height = 1;
|
||||
int ext = (real_width - (wid_64 << 4));
|
||||
load4bIA ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 0, Format: 4
|
||||
|
||||
wxUint32 Load4bI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (rdp.tlut_mode != 0)
|
||||
return Load4bCI (dst, src, wid_64, height, line, real_width, tile);
|
||||
|
||||
if (wid_64 < 1) wid_64 = 1;
|
||||
if (height < 1) height = 1;
|
||||
int ext = (real_width - (wid_64 << 4));
|
||||
load4bI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 0, Format: 0
|
||||
|
||||
wxUint32 Load4bSelect (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (rdp.tlut_mode == 0)
|
||||
return Load4bI (dst, src, wid_64, height, line, real_width, tile);
|
||||
|
||||
return Load4bCI (dst, src, wid_64, height, line, real_width, tile);
|
||||
}
|
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void load8bCI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal)
|
||||
{
|
||||
uint8_t *v7;
|
||||
uint32_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
int v11;
|
||||
uint32_t v12;
|
||||
uint32_t *v13;
|
||||
uint32_t v14;
|
||||
uint32_t *v15;
|
||||
uint32_t v16;
|
||||
uint32_t *v17;
|
||||
uint32_t *v18;
|
||||
int v19;
|
||||
int v20;
|
||||
uint32_t v21;
|
||||
uint32_t v22;
|
||||
uint32_t *v23;
|
||||
uint32_t v24;
|
||||
int v25;
|
||||
int v26;
|
||||
|
||||
v7 = src;
|
||||
v8 = (uint32_t *)dst;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v25 = v9;
|
||||
v10 = wid_64;
|
||||
do
|
||||
{
|
||||
v11 = v10;
|
||||
v12 = bswap32(*(uint32_t *)v7);
|
||||
v13 = (uint32_t *)(v7 + 4);
|
||||
ALOWORD(v10) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 15) & 0x1FE)), 1);
|
||||
v14 = v10 << 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 23) & 0x1FE)), 1);
|
||||
*v8 = v14;
|
||||
v15 = v8 + 1;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v12 & 0x1FE)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 7) & 0x1FE)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
v16 = bswap32(*v13);
|
||||
v7 = (uint8_t *)(v13 + 1);
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 15) & 0x1FE)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 23) & 0x1FE)), 1);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v16 & 0x1FE)), 1);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 7) & 0x1FE)), 1);
|
||||
*v15 = v14;
|
||||
v8 = v15 + 1;
|
||||
v10 = v11 - 1;
|
||||
}
|
||||
while ( v11 != 1 );
|
||||
if ( v25 == 1 )
|
||||
break;
|
||||
v26 = v25 - 1;
|
||||
v17 = (uint32_t *)&src[(line + (uintptr_t)v7 - (uintptr_t)src) & 0x7FF];
|
||||
v18 = (uint32_t *)((char *)v8 + ext);
|
||||
v19 = wid_64;
|
||||
do
|
||||
{
|
||||
v20 = v19;
|
||||
v21 = bswap32(v17[1]);
|
||||
ALOWORD(v19) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 15) & 0x1FE)), 1);
|
||||
v22 = v19 << 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 23) & 0x1FE)), 1);
|
||||
*v18 = v22;
|
||||
v23 = v18 + 1;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v21 & 0x1FE)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 7) & 0x1FE)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
v24 = bswap32(*v17);
|
||||
v17 = (uint32_t *)&src[((uintptr_t)v17 + 8 - (uintptr_t)src) & 0x7FF];
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 15) & 0x1FE)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 23) & 0x1FE)), 1);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v24 & 0x1FE)), 1);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 7) & 0x1FE)), 1);
|
||||
*v23 = v22;
|
||||
v18 = v23 + 1;
|
||||
v19 = v20 - 1;
|
||||
}
|
||||
while ( v20 != 1 );
|
||||
v7 = &src[(line + (uintptr_t)v17 - (uintptr_t)src) & 0x7FF];
|
||||
v8 = (uint32_t *)((char *)v18 + ext);
|
||||
v9 = v26 - 1;
|
||||
}
|
||||
while ( v26 != 1 );
|
||||
}
|
||||
|
||||
static inline void load8bIA8(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext, uint16_t *pal)
|
||||
{
|
||||
uint32_t *v7;
|
||||
uint32_t *v8;
|
||||
int v9;
|
||||
int v10;
|
||||
int v11;
|
||||
uint32_t v12;
|
||||
uint32_t *v13;
|
||||
uint32_t v14;
|
||||
uint32_t *v15;
|
||||
uint32_t v16;
|
||||
uint32_t *v17;
|
||||
uint32_t *v18;
|
||||
int v19;
|
||||
int v20;
|
||||
uint32_t v21;
|
||||
uint32_t v22;
|
||||
uint32_t *v23;
|
||||
uint32_t v24;
|
||||
int v25;
|
||||
int v26;
|
||||
|
||||
v7 = (uint32_t *)src;
|
||||
v8 = (uint32_t *)dst;
|
||||
v9 = height;
|
||||
do
|
||||
{
|
||||
v25 = v9;
|
||||
v10 = wid_64;
|
||||
do
|
||||
{
|
||||
v11 = v10;
|
||||
v12 = bswap32(*v7);
|
||||
v13 = v7 + 1;
|
||||
ALOWORD(v10) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 15) & 0x1FE)), 8);
|
||||
v14 = v10 << 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 23) & 0x1FE)), 8);
|
||||
*v8 = v14;
|
||||
v15 = v8 + 1;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v12 & 0x1FE)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v12 >> 7) & 0x1FE)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
v16 = bswap32(*v13);
|
||||
v7 = v13 + 1;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 15) & 0x1FE)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 23) & 0x1FE)), 8);
|
||||
*v15 = v14;
|
||||
++v15;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v16 & 0x1FE)), 8);
|
||||
v14 <<= 16;
|
||||
ALOWORD(v14) = __ROR__(*(uint16_t *)((char *)pal + ((v16 >> 7) & 0x1FE)), 8);
|
||||
*v15 = v14;
|
||||
v8 = v15 + 1;
|
||||
v10 = v11 - 1;
|
||||
}
|
||||
while ( v11 != 1 );
|
||||
if ( v25 == 1 )
|
||||
break;
|
||||
v26 = v25 - 1;
|
||||
v17 = (uint32_t *)((char *)v7 + line);
|
||||
v18 = (uint32_t *)((char *)v8 + ext);
|
||||
v19 = wid_64;
|
||||
do
|
||||
{
|
||||
v20 = v19;
|
||||
v21 = bswap32(v17[1]);
|
||||
ALOWORD(v19) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 15) & 0x1FE)), 8);
|
||||
v22 = v19 << 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 23) & 0x1FE)), 8);
|
||||
*v18 = v22;
|
||||
v23 = v18 + 1;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v21 & 0x1FE)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v21 >> 7) & 0x1FE)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
v24 = bswap32(*v17);
|
||||
v17 += 2;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 15) & 0x1FE)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 23) & 0x1FE)), 8);
|
||||
*v23 = v22;
|
||||
++v23;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + (2 * (uint16_t)v24 & 0x1FE)), 8);
|
||||
v22 <<= 16;
|
||||
ALOWORD(v22) = __ROR__(*(uint16_t *)((char *)pal + ((v24 >> 7) & 0x1FE)), 8);
|
||||
*v23 = v22;
|
||||
v18 = v23 + 1;
|
||||
v19 = v20 - 1;
|
||||
}
|
||||
while ( v20 != 1 );
|
||||
v7 = (uint32_t *)((char *)v17 + line);
|
||||
v8 = (uint32_t *)((char *)v18 + ext);
|
||||
v9 = v26 - 1;
|
||||
}
|
||||
while ( v26 != 1 );
|
||||
}
|
||||
|
||||
static inline void load8bIA4(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
uint32_t v10;
|
||||
uint32_t v11;
|
||||
uint32_t *v12;
|
||||
uint32_t *v13;
|
||||
uint32_t v14;
|
||||
uint32_t v15;
|
||||
uint32_t *v16;
|
||||
uint32_t *v17;
|
||||
int v18;
|
||||
uint32_t *v19;
|
||||
uint32_t v20;
|
||||
int v21;
|
||||
int v22;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v21 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = *v6;
|
||||
v11 = (*v6 >> 4) & 0xF0F0F0F;
|
||||
v12 = v6 + 1;
|
||||
*v7 = (16 * v10 & 0xF0F0F0F0) | v11;
|
||||
v13 = v7 + 1;
|
||||
v14 = (*v12 >> 4) & 0xF0F0F0F;
|
||||
v15 = 16 * *v12 & 0xF0F0F0F0;
|
||||
v6 = v12 + 1;
|
||||
*v13 = v15 | v14;
|
||||
v7 = v13 + 1;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
if ( v21 == 1 )
|
||||
break;
|
||||
v22 = v21 - 1;
|
||||
v16 = (uint32_t *)((char *)v6 + line);
|
||||
v17 = (uint32_t *)((char *)v7 + ext);
|
||||
v18 = wid_64;
|
||||
do
|
||||
{
|
||||
*v17 = (16 * v16[1] & 0xF0F0F0F0) | ((v16[1] >> 4) & 0xF0F0F0F);
|
||||
v19 = v17 + 1;
|
||||
v20 = *v16;
|
||||
v16 += 2;
|
||||
*v19 = (16 * v20 & 0xF0F0F0F0) | ((v20 >> 4) & 0xF0F0F0F);
|
||||
v17 = v19 + 1;
|
||||
--v18;
|
||||
}
|
||||
while ( v18 );
|
||||
v6 = (uint32_t *)((char *)v16 + line);
|
||||
v7 = (uint32_t *)((char *)v17 + ext);
|
||||
v8 = v22 - 1;
|
||||
}
|
||||
while ( v22 != 1 );
|
||||
}
|
||||
|
||||
static inline void load8bI(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
|
||||
{
|
||||
uint32_t *v6;
|
||||
uint32_t *v7;
|
||||
int v8;
|
||||
int v9;
|
||||
uint32_t v10;
|
||||
uint32_t *v11;
|
||||
uint32_t *v12;
|
||||
uint32_t v13;
|
||||
uint32_t *v14;
|
||||
uint32_t *v15;
|
||||
int v16;
|
||||
uint32_t *v17;
|
||||
uint32_t v18;
|
||||
int v19;
|
||||
int v20;
|
||||
|
||||
v6 = (uint32_t *)src;
|
||||
v7 = (uint32_t *)dst;
|
||||
v8 = height;
|
||||
do
|
||||
{
|
||||
v19 = v8;
|
||||
v9 = wid_64;
|
||||
do
|
||||
{
|
||||
v10 = *v6;
|
||||
v11 = v6 + 1;
|
||||
*v7 = v10;
|
||||
v12 = v7 + 1;
|
||||
v13 = *v11;
|
||||
v6 = v11 + 1;
|
||||
*v12 = v13;
|
||||
v7 = v12 + 1;
|
||||
--v9;
|
||||
}
|
||||
while ( v9 );
|
||||
if ( v19 == 1 )
|
||||
break;
|
||||
v20 = v19 - 1;
|
||||
v14 = (uint32_t *)((char *)v6 + line);
|
||||
v15 = (uint32_t *)((char *)v7 + ext);
|
||||
v16 = wid_64;
|
||||
do
|
||||
{
|
||||
*v15 = v14[1];
|
||||
v17 = v15 + 1;
|
||||
v18 = *v14;
|
||||
v14 += 2;
|
||||
*v17 = v18;
|
||||
v15 = v17 + 1;
|
||||
--v16;
|
||||
}
|
||||
while ( v16 );
|
||||
v6 = (uint32_t *)((char *)v14 + line);
|
||||
v7 = (uint32_t *)((char *)v15 + ext);
|
||||
v8 = v20 - 1;
|
||||
}
|
||||
while ( v20 != 1 );
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 1, Format: 2
|
||||
//
|
||||
|
||||
wxUint32 Load8bCI (wxUIntPtr dst, wxUIntPtr 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 << 3));
|
||||
unsigned short * pal = rdp.pal_8;
|
||||
|
||||
switch (rdp.tlut_mode) {
|
||||
case 0: //palette is not used
|
||||
//in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference.
|
||||
//Thanks to angrylion for the advice
|
||||
load8bI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_8;
|
||||
case 2: //color palette
|
||||
ext <<= 1;
|
||||
load8bCI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext, pal);
|
||||
return (1 << 16) | GR_TEXFMT_ARGB_1555;
|
||||
default: //IA palette
|
||||
ext <<= 1;
|
||||
load8bIA8 ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext, pal);
|
||||
return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88;
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 1, Format: 3
|
||||
//
|
||||
// ** by Gugaman **
|
||||
|
||||
wxUint32 Load8bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (rdp.tlut_mode != 0)
|
||||
return Load8bCI (dst, src, wid_64, height, line, real_width, tile);
|
||||
|
||||
if (wid_64 < 1) wid_64 = 1;
|
||||
if (height < 1) height = 1;
|
||||
int ext = (real_width - (wid_64 << 3));
|
||||
load8bIA4 ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44;
|
||||
}
|
||||
|
||||
//****************************************************************
|
||||
// Size: 1, Format: 4
|
||||
//
|
||||
// ** by Gugaman **
|
||||
|
||||
wxUint32 Load8bI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
|
||||
{
|
||||
if (rdp.tlut_mode != 0)
|
||||
return Load8bCI (dst, src, wid_64, height, line, real_width, tile);
|
||||
|
||||
if (wid_64 < 1) wid_64 = 1;
|
||||
if (height < 1) height = 1;
|
||||
int ext = (real_width - (wid_64 << 3));
|
||||
load8bI ((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
|
||||
return /*(0 << 16) | */GR_TEXFMT_ALPHA_8;
|
||||
}
|
||||
|
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static void mod_tex_inter_color_using_factor (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
float percent_i = 1 - percent;
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col, a;
|
||||
wxUint8 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 = (wxUint8)(percent_i * ((col >> 8) & 0xF) + percent * cr);
|
||||
g = (wxUint8)(percent_i * ((col >> 4) & 0xF) + percent * cg);
|
||||
b = (wxUint8)(percent_i * (col & 0xF) + percent * cb);
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_inter_col_using_col1 (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col, a;
|
||||
wxUint8 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 = (wxUint8)(percent_r_i * ((col >> 8) & 0xF) + percent_r * cr);
|
||||
g = (wxUint8)(percent_g_i * ((col >> 4) & 0xF) + percent_g * cg);
|
||||
b = (wxUint8)(percent_b_i * (col & 0xF) + percent_b * cb);
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_full_color_sub_tex (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb, ca;
|
||||
wxUint16 col;
|
||||
wxUint8 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 = (wxUint8)(ca - ((col >> 12) & 0xF));
|
||||
r = (wxUint8)(cr - ((col >> 8) & 0xF));
|
||||
g = (wxUint8)(cg - ((col >> 4) & 0xF));
|
||||
b = (wxUint8)(cb - (col & 0xF));
|
||||
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_col1_using_tex (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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, (wxUint8)((1.0f-percent_r) * cr0 + percent_r * cr1 + 0.0001f));
|
||||
g = min(15, (wxUint8)((1.0f-percent_g) * cg0 + percent_g * cg1 + 0.0001f));
|
||||
b = min(15, (wxUint8)((1.0f-percent_b) * cb0 + percent_b * cb1 + 0.0001f));
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_col1_using_texa (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(percent_i * cr0 + percent * cr1);
|
||||
g = (wxUint8)(percent_i * cg0 + percent * cg1);
|
||||
b = (wxUint8)(percent_i * cb0 + percent * cb1);
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_col1_using_texa__mul_tex (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(((percent_i * cr0 + percent * cr1) / 15.0f) * (((col & 0x0F00) >> 8) / 15.0f) * 15.0f);
|
||||
g = (wxUint8)(((percent_i * cg0 + percent * cg1) / 15.0f) * (((col & 0x00F0) >> 4) / 15.0f) * 15.0f);
|
||||
b = (wxUint8)(((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 (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)((1.0f-percent_r) * cr + percent_r * ((col & 0x0F00) >> 8));
|
||||
g = (wxUint8)((1.0f-percent_g) * cg + percent_g * ((col & 0x00F0) >> 4));
|
||||
b = (wxUint8)((1.0f-percent_b) * cb + percent_b * (col & 0x000F));
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_tex_using_texa (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(percent_i * cr + percent * ((col & 0x0F00) >> 8));
|
||||
g = (wxUint8)(percent_i * cg + percent * ((col & 0x00F0) >> 4));
|
||||
b = (wxUint8)(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 (wxUint16 *dst, int size,
|
||||
wxUint32 color0, wxUint32 color1,
|
||||
wxUint32 color2)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1, cr2, cg2, cb2;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(((1.0f-percent_r) * cr0 + percent_r * cr1) * percent_a + cr2 * (1.0f-percent_a));
|
||||
g = (wxUint8)(((1.0f-percent_g) * cg0 + percent_g * cg1) * percent_a + cg2 * (1.0f-percent_a));
|
||||
b = (wxUint8)(((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 (wxUint16 *dst, int size, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint16 col;
|
||||
wxUint8 a;
|
||||
float base_a = (1.0f - percent) * 15.0f;
|
||||
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
col = *dst;
|
||||
a = (wxUint8)(base_a + percent * (col>>12));
|
||||
*(dst++) = (a<<12) | (col & 0x0FFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_sub_col_mul_fac_add_tex (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 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 | ((wxUint16)r << 8) | ((wxUint16)g << 4) | (wxUint16)b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_scale_col_add_col (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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, (wxUint8)(percent_r * cr0 + cr1 + 0.0001f));
|
||||
g = min(15, (wxUint8)(percent_g * cg0 + cg1 + 0.0001f));
|
||||
b = min(15, (wxUint8)(percent_b * cb0 + cb1 + 0.0001f));
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_add_col (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 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 = (wxUint8)((col >> 12) & 0xF);
|
||||
// a = col & 0xF000;
|
||||
r = (wxUint8)(cr + ((col >> 8) & 0xF))&0xF;
|
||||
g = (wxUint8)(cg + ((col >> 4) & 0xF))&0xF;
|
||||
b = (wxUint8)(cb + (col & 0xF))&0xF;
|
||||
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_mul_texa_add_tex (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(cr*factor + ((col >> 8) & 0xF))&0xF;
|
||||
g = (wxUint8)(cg*factor + ((col >> 4) & 0xF))&0xF;
|
||||
b = (wxUint8)(cb*factor + (col & 0xF))&0xF;
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_sub_col (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
int cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 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 = (wxUint8)(col & 0xF000);
|
||||
r = (wxUint8)max((((col >> 8) & 0xF) - cr), 0);
|
||||
g = (wxUint8)max((((col >> 4) & 0xF) - cg), 0);
|
||||
b = (wxUint8)max(((col & 0xF) - cb), 0);
|
||||
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_sub_col_mul_fac (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 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 = (wxUint8)((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) | ((wxUint16)r << 8) | ((wxUint16)g << 4) | (wxUint16)b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_tex_using_col1 (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col, a;
|
||||
wxUint8 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 = (wxUint8)((col >> 12) & 0xF);
|
||||
r = (wxUint8)(percent_r * ((col >> 8) & 0xF) + percent_r_i * cr);
|
||||
g = (wxUint8)(percent_g * ((col >> 4) & 0xF) + percent_g_i * cg);
|
||||
b = (wxUint8)(percent_b * (col & 0xF) + percent_b_i * cb);
|
||||
*(dst++) = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_inter_noise_using_col (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint16 col, a;
|
||||
wxUint8 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 = (wxUint8)(percent_r_i * ((col >> 8) & 0xF) + percent_r * noise);
|
||||
g = (wxUint8)(percent_g_i * ((col >> 4) & 0xF) + percent_g * noise);
|
||||
b = (wxUint8)(percent_b_i * (col & 0xF) + percent_b * noise);
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_inter_col_using_texa (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(percent * cr + percent_i * ((col & 0x0F00) >> 8));
|
||||
g = (wxUint8)(percent * cg + percent_i * ((col & 0x00F0) >> 4));
|
||||
b = (wxUint8)(percent * cb + percent_i * (col & 0x000F));
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_mul_col (wxUint16 *dst, int size, wxUint32 color)
|
||||
{
|
||||
float cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 r, g, b;
|
||||
wxUint16 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 = (wxUint8)(cr * ((col & 0x0F00) >> 8));
|
||||
g = (wxUint8)(cg * ((col & 0x00F0) >> 4));
|
||||
b = (wxUint8)(cb * (col & 0x000F));
|
||||
*(dst++) = a | (r << 8) | (g << 4) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_scale_fac_add_col (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint32 cr, cg, cb;
|
||||
wxUint16 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) | ((wxUint8)r << 8) | ((wxUint8)g << 4) | (wxUint8)b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
static void mod_tex_inter_color_using_factor_CI (wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
float percent_i = 1 - percent;
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
|
||||
r = (wxUint8)(min(255, percent_i * r + percent * cr));
|
||||
g = (wxUint8)(min(255, percent_i * g + percent * cg));
|
||||
b = (wxUint8)(min(255, percent_i * b + percent * cb));
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_inter_col_using_col1_CI (wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 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 = (wxUint8)((color0 >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color0 >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color0 >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
|
||||
r = (wxUint8)(min(255, percent_r_i * r + percent_r * cr));
|
||||
g = (wxUint8)(min(255, percent_g_i * g + percent_g * cg));
|
||||
b = (wxUint8)(min(255, percent_b_i * b + percent_b * cb));
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_full_color_sub_tex_CI (wxUint32 color)
|
||||
{
|
||||
wxUint8 cr, cg, cb, ca;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
ca = (wxUint8)(color & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((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] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_col1_using_tex_CI (wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint32 cr0, cg0, cb0, cr1, cg1, cb1;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
float percent_r, percent_g, percent_b;
|
||||
|
||||
cr0 = (wxUint8)((color0 >> 24) & 0xFF);
|
||||
cg0 = (wxUint8)((color0 >> 16) & 0xFF);
|
||||
cb0 = (wxUint8)((color0 >> 8) & 0xFF);
|
||||
cr1 = (wxUint8)((color1 >> 24) & 0xFF);
|
||||
cg1 = (wxUint8)((color1 >> 16) & 0xFF);
|
||||
cb1 = (wxUint8)((color1 >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
percent_r = ((col&0xF800) >> 11) / 31.0f;
|
||||
percent_g = ((col&0x07C0) >> 6) / 31.0f;
|
||||
percent_b = ((col&0x003E) >> 1) / 31.0f;
|
||||
r = (wxUint8)(min((1.0f-percent_r) * cr0 + percent_r * cr1, 255));
|
||||
g = (wxUint8)(min((1.0f-percent_g) * cg0 + percent_g * cg1, 255));
|
||||
b = (wxUint8)(min((1.0f-percent_b) * cb0 + percent_b * cb1, 255));
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void mod_tex_sub_col_mul_fac_add_tex_CI (wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint8 cr, cg, cb, a;
|
||||
wxUint16 col;
|
||||
float r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((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] = (wxUint16)(((wxUint16)((wxUint8)(r) >> 3) << 11) |
|
||||
((wxUint16)((wxUint8)(g) >> 3) << 6) |
|
||||
((wxUint16)((wxUint8)(b) >> 3) << 1) |
|
||||
(wxUint16)(a) );
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_scale_col_add_col_CI (wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
float percent_r = ((color0 >> 24) & 0xFF) / 255.0f;
|
||||
float percent_g = ((color0 >> 16) & 0xFF) / 255.0f;
|
||||
float percent_b = ((color0 >> 8) & 0xFF) / 255.0f;
|
||||
cr = (wxUint8)((color1 >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color1 >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color1 >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
|
||||
r = (wxUint8)(min(255, percent_r * r + cr));
|
||||
g = (wxUint8)(min(255, percent_g * g + cg));
|
||||
b = (wxUint8)(min(255, percent_b * b + cb));
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_add_col_CI (wxUint32 color)
|
||||
{
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((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] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_sub_col_CI (wxUint32 color)
|
||||
{
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((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] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_sub_col_mul_fac_CI (wxUint32 color, wxUint32 factor)
|
||||
{
|
||||
float percent = factor / 255.0f;
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 a;
|
||||
float r, g, b;
|
||||
|
||||
cr = (wxUint8)((color >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(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] = (wxUint16)(((wxUint16)((wxUint8)(r) >> 3) << 11) |
|
||||
((wxUint16)((wxUint8)(g) >> 3) << 6) |
|
||||
((wxUint16)((wxUint8)(b) >> 3) << 1) |
|
||||
(wxUint16)(a) );
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_col_inter_tex_using_col1_CI (wxUint32 color0, wxUint32 color1)
|
||||
{
|
||||
wxUint8 cr, cg, cb;
|
||||
wxUint16 col;
|
||||
wxUint8 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 = (wxUint8)((color0 >> 24) & 0xFF);
|
||||
cg = (wxUint8)((color0 >> 16) & 0xFF);
|
||||
cb = (wxUint8)((color0 >> 8) & 0xFF);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
col = rdp.pal_8[i];
|
||||
a = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f);
|
||||
b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f);
|
||||
r = (wxUint8)(min(255, percent_r * r + percent_r_i * cr));
|
||||
g = (wxUint8)(min(255, percent_g * g + percent_g_i * cg));
|
||||
b = (wxUint8)(min(255, percent_b * b + percent_b_i * cb));
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_tex_inter_col_using_texa_CI (wxUint32 color)
|
||||
{
|
||||
wxUint8 a, r, g, b;
|
||||
|
||||
r = (wxUint8)((float)((color >> 24) & 0xFF) / 255.0f * 31.0f);
|
||||
g = (wxUint8)((float)((color >> 16) & 0xFF) / 255.0f * 31.0f);
|
||||
b = (wxUint8)((float)((color >> 8) & 0xFF) / 255.0f * 31.0f);
|
||||
a = (color&0xFF) ? 1 : 0;
|
||||
wxUint16 col16 = (wxUint16)((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 (wxUint32 color)
|
||||
{
|
||||
wxUint8 a, r, g, b;
|
||||
wxUint16 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 = (wxUint8)(col&0x0001);;
|
||||
r = (wxUint8)((float)((col&0xF800) >> 11) * cr);
|
||||
g = (wxUint8)((float)((col&0x07C0) >> 6) * cg);
|
||||
b = (wxUint8)((float)((col&0x003E) >> 1) * cb);
|
||||
rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) |
|
||||
((wxUint16)(g >> 3) << 6) |
|
||||
((wxUint16)(b >> 3) << 1) |
|
||||
((wxUint16)(a ) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void ModifyPalette(wxUint32 mod, wxUint32 modcolor, wxUint32 modcolor1, wxUint32 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, modcolor1);
|
||||
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:
|
||||
;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef Util_H
|
||||
#define Util_H
|
||||
|
||||
#define NOT_TMU0 0x00
|
||||
#define NOT_TMU1 0x01
|
||||
#define NOT_TMU2 0x02
|
||||
|
||||
void util_init ();
|
||||
void render_tri (wxUint16 linew = 0);
|
||||
|
||||
int cull_tri (VERTEX **v);
|
||||
void draw_tri (VERTEX **v, wxUint16 linew = 0);
|
||||
void do_triangle_stuff (wxUint16 linew = 0, int old_interpolate = TRUE);
|
||||
void do_triangle_stuff_2 (wxUint16 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 ();
|
||||
|
||||
float ScaleZ(float z);
|
||||
|
||||
// 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; \
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define bswap32(x) __builtin_bswap32(x)
|
||||
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#include <stdlib.h>
|
||||
#define bswap32(x) _byteswap_ulong(x)
|
||||
#else
|
||||
static inline uint32_t bswap32(uint32_t val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) |
|
||||
((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) |
|
||||
((val & 0x000000ff) << 24));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ALOWORD(x) (*((uint16_t*)&(x))) // low word
|
||||
|
||||
template<class T> static inline T __ROR__(T value, unsigned int count)
|
||||
{
|
||||
const unsigned int nbits = sizeof(T) * 8;
|
||||
count %= nbits;
|
||||
|
||||
T low = value << (nbits - count);
|
||||
value >>= count;
|
||||
value |= low;
|
||||
return value;
|
||||
}
|
||||
|
||||
// rotate left
|
||||
template<class T> static T __ROL__(T value, unsigned int count)
|
||||
{
|
||||
const unsigned int nbits = sizeof(T) * 8;
|
||||
count %= nbits;
|
||||
|
||||
T high = value >> (nbits - count);
|
||||
value <<= count;
|
||||
value |= high;
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif // ifndef Util_H
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,98 @@
|
|||
/******************************************************************************
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* http://bitbucket.org/richard42/mupen64plus-video-glide64mk2/
|
||||
*
|
||||
* 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
|
||||
|
||||
#ifndef OLDAPI
|
||||
|
||||
#include "m64p_types.h"
|
||||
#include "m64p_plugin.h"
|
||||
#include "m64p_common.h"
|
||||
#include "m64p_config.h"
|
||||
#include "m64p_vidext.h"
|
||||
#include "winlnxdefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define PLUGIN_NAME "Glide64mk2 Video Plugin"
|
||||
#define PLUGIN_VERSION 0x020000
|
||||
#define VIDEO_PLUGIN_API_VERSION 0x020200
|
||||
#define CONFIG_API_VERSION 0x020000
|
||||
#define VIDEXT_API_VERSION 0x030000
|
||||
|
||||
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_ResizeWindow CoreVideo_ResizeWindow;
|
||||
extern ptr_VidExt_GL_GetProcAddress CoreVideo_GL_GetProcAddress;
|
||||
extern ptr_VidExt_GL_SetAttribute CoreVideo_GL_SetAttribute;
|
||||
extern ptr_VidExt_GL_SwapBuffers CoreVideo_GL_SwapBuffers;
|
||||
|
||||
#else
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/fileconf.h>
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
@ -0,0 +1,914 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
#ifndef RDP_H
|
||||
#define RDP_H
|
||||
|
||||
extern char out_buf[2048];
|
||||
|
||||
extern wxUint32 frame_count; // frame counter
|
||||
|
||||
//GlideHQ support
|
||||
#ifdef TEXTURE_FILTER
|
||||
#include "../GlideHQ/Ext_TxFilter.h"
|
||||
#endif
|
||||
|
||||
#define MAX_CACHE 1024*4
|
||||
#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_WMIN 0x00000010
|
||||
#define CLIP_ZMAX 0x00000020
|
||||
#define CLIP_ZMIN 0x00000040
|
||||
|
||||
// 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]
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define DECLAREALIGN16VAR(var) __declspec(align(16)) float var
|
||||
#elif defined(__GNUG__)
|
||||
#define DECLAREALIGN16VAR(var) float (var) __attribute__ ((aligned(16)))
|
||||
#endif
|
||||
|
||||
// Vertex structure
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z, q;
|
||||
float u0, v0, u1, v1;
|
||||
float coord[4];
|
||||
float w;
|
||||
wxUint16 flags;
|
||||
|
||||
wxUint8 b; // These values are arranged like this so that *(wxUint32*)(VERTEX+?) is
|
||||
wxUint8 g; // ARGB format that glide can use.
|
||||
wxUint8 r;
|
||||
wxUint8 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;
|
||||
wxUint8 not_zclipped;
|
||||
wxUint8 screen_translated;
|
||||
wxUint8 uv_scaled;
|
||||
wxUint32 uv_calculated; // like crc
|
||||
wxUint32 shade_mod;
|
||||
wxUint32 color_backup;
|
||||
|
||||
float ou, ov;
|
||||
|
||||
int number; // way to identify it
|
||||
int scr_off, z_off; // off the screen?
|
||||
} VERTEX;
|
||||
|
||||
// Clipping (scissors)
|
||||
typedef struct {
|
||||
wxUint32 ul_x;
|
||||
wxUint32 ul_y;
|
||||
wxUint32 lr_x;
|
||||
wxUint32 lr_y;
|
||||
} SCISSOR;
|
||||
|
||||
#ifdef TEXTURE_FILTER
|
||||
extern wxUint32 texfltr[];
|
||||
extern wxUint32 texenht[];
|
||||
extern wxUint32 texcmpr[];
|
||||
extern wxUint32 texhirs[];
|
||||
|
||||
typedef struct {
|
||||
wxUint16 tile_ul_s;
|
||||
wxUint16 tile_ul_t;
|
||||
wxUint16 tile_width;
|
||||
wxUint16 tile_height;
|
||||
wxUint16 tex_width;
|
||||
wxUint16 tex_size;
|
||||
wxUint32 dxt;
|
||||
} LOAD_TILE_INFO;
|
||||
#endif
|
||||
|
||||
// #warning no screenshot support
|
||||
/*
|
||||
typedef struct {
|
||||
const wxChar * format;
|
||||
const wxChar * extension;
|
||||
wxBitmapType type;
|
||||
} SCREEN_SHOT_FORMAT;
|
||||
|
||||
extern const int NumOfFormats;
|
||||
extern SCREEN_SHOT_FORMAT ScreenShotFormats[];
|
||||
*/
|
||||
typedef struct {
|
||||
int card_id;
|
||||
int lang_id;
|
||||
|
||||
wxUint32 res_x, scr_res_x;
|
||||
wxUint32 res_y, scr_res_y;
|
||||
wxUint32 res_data, res_data_org;
|
||||
|
||||
int advanced_options;
|
||||
int texenh_options;
|
||||
int ssformat;
|
||||
int vsync;
|
||||
|
||||
int show_fps;
|
||||
int clock;
|
||||
int clock_24_hr;
|
||||
|
||||
int filtering;
|
||||
int fog;
|
||||
int buff_clear;
|
||||
int swapmode;
|
||||
int lodmode;
|
||||
int aspectmode;
|
||||
int use_hotkeys;
|
||||
|
||||
//Frame buffer emulation options
|
||||
#define fb_emulation (1<<0) //frame buffer emulation
|
||||
#define fb_hwfbe (1<<1) //hardware frame buffer emualtion
|
||||
#define fb_motionblur (1<<2) //emulate motion blur
|
||||
#define fb_ref (1<<3) //read every frame
|
||||
#define fb_read_alpha (1<<4) //read alpha
|
||||
#define fb_hwfbe_buf_clear (1<<5) //clear auxiliary texture frame buffers
|
||||
#define fb_depth_render (1<<6) //enable software depth render
|
||||
#define fb_optimize_texrect (1<<7) //fast texrect rendering with hwfbe
|
||||
#define fb_ignore_aux_copy (1<<8) //do not copy auxiliary frame buffers
|
||||
#define fb_useless_is_useless (1<<10) //
|
||||
#define fb_get_info (1<<11) //get frame buffer info
|
||||
#define fb_read_back_to_screen (1<<12) //render N64 frame buffer to screen
|
||||
#define fb_read_back_to_screen2 (1<<13) //render N64 frame buffer to screen
|
||||
#define fb_cpu_write_hack (1<<14) //show images writed directly by CPU
|
||||
|
||||
#define fb_emulation_enabled ((settings.frame_buffer&fb_emulation)>0)
|
||||
#define fb_hwfbe_enabled ((settings.frame_buffer&(fb_emulation|fb_hwfbe))==(fb_emulation|fb_hwfbe))
|
||||
#define fb_depth_render_enabled ((settings.frame_buffer&fb_depth_render)>0)
|
||||
|
||||
wxUint32 frame_buffer;
|
||||
enum FBCRCMODE {
|
||||
fbcrcNone = 0,
|
||||
fbcrcFast = 1,
|
||||
fbcrcSafe = 2} fb_crc_mode;
|
||||
|
||||
#ifdef TEXTURE_FILTER
|
||||
//Texture filtering options
|
||||
int ghq_fltr;
|
||||
int ghq_enht;
|
||||
int ghq_cmpr;
|
||||
int ghq_hirs;
|
||||
int ghq_use;
|
||||
int ghq_enht_cmpr;
|
||||
int ghq_enht_tile;
|
||||
int ghq_enht_f16bpp;
|
||||
int ghq_enht_gz;
|
||||
int ghq_enht_nobg;
|
||||
int ghq_hirs_cmpr;
|
||||
int ghq_hirs_tile;
|
||||
int ghq_hirs_f16bpp;
|
||||
int ghq_hirs_gz;
|
||||
int ghq_hirs_altcrc;
|
||||
int ghq_cache_save;
|
||||
int ghq_cache_size;
|
||||
int ghq_hirs_let_texartists_fly;
|
||||
int ghq_hirs_dump;
|
||||
#endif
|
||||
|
||||
//Debug
|
||||
int autodetect_ucode;
|
||||
int ucode;
|
||||
int logging;
|
||||
int elogging;
|
||||
int log_clear;
|
||||
int run_in_window;
|
||||
int filter_cache;
|
||||
int unk_as_red;
|
||||
int log_unk;
|
||||
int unk_clear;
|
||||
int wireframe;
|
||||
int wfmode;
|
||||
|
||||
// Special fixes
|
||||
int offset_x, offset_y;
|
||||
int scale_x, scale_y;
|
||||
int fast_crc;
|
||||
int alt_tex_size;
|
||||
int use_sts1_only;
|
||||
int flame_corona; //hack for zeldas flame's corona
|
||||
int increase_texrect_edge; // add 1 to lower right corner coordinates of texrect
|
||||
int decrease_fillrect_edge; // sub 1 from lower right corner coordinates of fillrect
|
||||
int texture_correction; // enable perspective texture correction emulation. is on by default
|
||||
int stipple_mode; //used for dithered alpha emulation
|
||||
wxUint32 stipple_pattern; //used for dithered alpha emulation
|
||||
int force_microcheck; //check microcode each frame, for mixed F3DEX-S2DEX games
|
||||
int force_quad3d; //force 0xb5 command to be quad, not line 3d
|
||||
int clip_zmin; //enable near z clipping
|
||||
int clip_zmax; //enable far plane clipping;
|
||||
int adjust_aspect; //adjust screen aspect for wide screen mode
|
||||
int force_calc_sphere; //use spheric mapping only, Ridge Racer 64
|
||||
int pal230; //set special scale for PAL games
|
||||
int correct_viewport; //correct viewport values
|
||||
int zmode_compare_less; //force GR_CMP_LESS for zmode=0 (opaque)and zmode=1 (interpenetrating)
|
||||
int old_style_adither; //apply alpha dither regardless of alpha_dither_mode
|
||||
int n64_z_scale; //scale vertex z value before writing to depth buffer, as N64 does.
|
||||
|
||||
//Special game hacks
|
||||
#define hack_ASB (1<<0) //All-Star Baseball games
|
||||
#define hack_Banjo2 (1<<1) //Banjo Tooie
|
||||
#define hack_BAR (1<<2) //Beetle Adventure Racing
|
||||
#define hack_Chopper (1<<3) //Chopper Attack
|
||||
#define hack_Diddy (1<<4) //diddy kong racing
|
||||
#define hack_Fifa98 (1<<5) //FIFA - Road to World Cup 98
|
||||
#define hack_Fzero (1<<6) //F-Zero
|
||||
#define hack_GoldenEye (1<<7) //Golden Eye
|
||||
#define hack_Hyperbike (1<<8) //Top Gear Hyper Bike
|
||||
#define hack_ISS64 (1<<9) //International Superstar Soccer 64
|
||||
#define hack_KI (1<<10) //Killer Instinct
|
||||
#define hack_Knockout (1<<11) //Knockout Kings 2000
|
||||
#define hack_Lego (1<<12) //LEGO Racers
|
||||
#define hack_MK64 (1<<13) //Mario Kart
|
||||
#define hack_Megaman (1<<14) //Megaman64
|
||||
#define hack_Makers (1<<15) //Mischief-makers
|
||||
#define hack_WCWnitro (1<<16) //WCW Nitro
|
||||
#define hack_Ogre64 (1<<17) //Ogre Battle 64
|
||||
#define hack_Pilotwings (1<<18) //Pilotwings
|
||||
#define hack_PMario (1<<19) //Paper Mario
|
||||
#define hack_PPL (1<<20) //pokemon puzzle league requires many special fixes
|
||||
#define hack_RE2 (1<<21) //Resident Evil 2
|
||||
#define hack_Starcraft (1<<22) //StarCraft64
|
||||
#define hack_Supercross (1<<23) //Supercross 2000
|
||||
#define hack_TGR (1<<24) //Top Gear Rally
|
||||
#define hack_TGR2 (1<<25) //Top Gear Rally 2
|
||||
#define hack_Tonic (1<<26) //tonic trouble
|
||||
#define hack_Yoshi (1<<27) //Yoshi Story
|
||||
#define hack_Zelda (1<<28) //zeldas hacks
|
||||
wxUint32 hacks;
|
||||
|
||||
//wrapper settings
|
||||
int wrpResolution;
|
||||
int wrpVRAM;
|
||||
int wrpFBO;
|
||||
int wrpAnisotropic;
|
||||
|
||||
} SETTINGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wxUint8 hk_ref;
|
||||
wxUint8 hk_motionblur;
|
||||
wxUint8 hk_filtering;
|
||||
} HOTKEY_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num_tmu;
|
||||
int max_tex_size;
|
||||
int sup_large_tex;
|
||||
int sup_mirroring;
|
||||
int sup_32bit_tex;
|
||||
int has_2mb_tex_boundary;
|
||||
int tex_UMA;
|
||||
int gamma_correction;
|
||||
FxI32 gamma_table_size;
|
||||
FxU32 *gamma_table_r;
|
||||
FxU32 *gamma_table_g;
|
||||
FxU32 *gamma_table_b;
|
||||
wxUint32 tmem_ptr[MAX_TMU];
|
||||
wxUint32 tex_min_addr[MAX_TMU];
|
||||
wxUint32 tex_max_addr[MAX_TMU];
|
||||
} VOODOO;
|
||||
|
||||
// This structure is what is passed in by rdp:settextureimage
|
||||
typedef struct {
|
||||
wxUint8 format; // format: ARGB, IA, ...
|
||||
wxUint8 size; // size: 4,8,16, or 32 bit
|
||||
wxUint16 width; // used in settextureimage
|
||||
wxUint32 addr; // address in RDRAM to load the texture from
|
||||
int 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
|
||||
wxUint8 format; // format: ARGB, IA, ...
|
||||
wxUint8 size; // size: 4,8,16, or 32 bit
|
||||
wxUint16 line; // size of one row (x axis) in 64 bit words
|
||||
wxUint16 t_mem; // location in texture memory (in 64 bit words, max 512 (4MB))
|
||||
wxUint8 palette; // palette # to use
|
||||
wxUint8 clamp_t; // clamp or wrap (y axis)?
|
||||
wxUint8 mirror_t; // mirroring on (y axis)?
|
||||
wxUint8 mask_t; // mask to wrap around (ex: 5 would wrap around 32) (y axis)
|
||||
wxUint8 shift_t; // ??? (scaling)
|
||||
wxUint8 clamp_s; // clamp or wrap (x axis)?
|
||||
wxUint8 mirror_s; // mirroring on (x axis)?
|
||||
wxUint8 mask_s; // mask to wrap around (x axis)
|
||||
wxUint8 shift_s; // ??? (scaling)
|
||||
|
||||
// rdp:settilesize
|
||||
wxUint16 ul_s; // upper left s coordinate
|
||||
wxUint16 ul_t; // upper left t coordinate
|
||||
wxUint16 lr_s; // lower right s coordinate
|
||||
wxUint16 lr_t; // lower right t coordinate
|
||||
|
||||
float f_ul_s;
|
||||
float f_ul_t;
|
||||
|
||||
// these are set by loadtile
|
||||
wxUint16 t_ul_s; // upper left s coordinate
|
||||
wxUint16 t_ul_t; // upper left t coordinate
|
||||
wxUint16 t_lr_s; // lower right s coordinate
|
||||
wxUint16 t_lr_t; // lower right t coordinate
|
||||
|
||||
wxUint32 width;
|
||||
wxUint32 height;
|
||||
|
||||
// uc0:texture
|
||||
wxUint8 on;
|
||||
float s_scale;
|
||||
float t_scale;
|
||||
|
||||
wxUint16 org_s_scale;
|
||||
wxUint16 org_t_scale;
|
||||
} TILE;
|
||||
|
||||
// This structure forms the lookup table for cached textures
|
||||
typedef struct {
|
||||
wxUint32 addr; // address in RDRAM
|
||||
wxUint32 crc; // CRC check
|
||||
wxUint32 palette; // Palette #
|
||||
wxUint32 width; // width
|
||||
wxUint32 height; // height
|
||||
wxUint32 format; // format
|
||||
wxUint32 size; // size
|
||||
wxUint32 last_used; // what frame # was this texture last used (used for replacing)
|
||||
|
||||
wxUint32 line;
|
||||
|
||||
wxUint32 flags; // clamp/wrap/mirror flags
|
||||
|
||||
wxUint32 realwidth; // width of actual texture
|
||||
wxUint32 realheight; // height of actual texture
|
||||
wxUint32 lod;
|
||||
wxUint32 aspect;
|
||||
|
||||
wxUint8 set_by;
|
||||
wxUint8 texrecting;
|
||||
|
||||
int f_mirror_s;
|
||||
int f_mirror_t;
|
||||
int f_wrap_s;
|
||||
int f_wrap_t;
|
||||
|
||||
float scale_x; // texture scaling
|
||||
float scale_y;
|
||||
float scale; // general scale to 256
|
||||
|
||||
GrTexInfo t_info; // texture info (glide)
|
||||
wxUint32 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
|
||||
|
||||
wxUint32 mod, mod_color, mod_color1, mod_color2, mod_factor;
|
||||
#ifdef TEXTURE_FILTER
|
||||
uint64 ricecrc;
|
||||
int is_hires_tex;
|
||||
#endif
|
||||
} 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;
|
||||
wxUint32 nonblack;
|
||||
wxUint32 nonzero;
|
||||
} LIGHT;
|
||||
|
||||
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, auxiliary color image, copy of last color image from previous frame
|
||||
ci_copy, //5, auxiliary 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, auxiliary color image, copy of depth image
|
||||
ci_aux, //8, auxiliary color image
|
||||
ci_aux_copy //9, auxiliary color image, partial copy of previous color image
|
||||
} CI_STATUS;
|
||||
|
||||
// Frame buffers
|
||||
typedef struct
|
||||
{
|
||||
wxUint32 addr; //color image address
|
||||
wxUint8 format;
|
||||
wxUint8 size;
|
||||
wxUint16 width;
|
||||
wxUint16 height;
|
||||
CI_STATUS status;
|
||||
int changed;
|
||||
} COLOR_IMAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GrChipID_t tmu;
|
||||
wxUint32 addr; //address of color image
|
||||
wxUint32 end_addr;
|
||||
wxUint32 tex_addr; //address in video memory
|
||||
wxUint32 width; //width of color image
|
||||
wxUint32 height; //height of color image
|
||||
wxUint8 format; //format of color image
|
||||
wxUint8 size; //format of color image
|
||||
wxUint8 clear; //flag. texture buffer must be cleared
|
||||
wxUint8 drawn; //flag. if equal to 1, this image was already drawn in current frame
|
||||
wxUint32 crc; //checksum of the color image
|
||||
float scr_width; //width of rendered image
|
||||
float scr_height; //height of rendered image
|
||||
wxUint32 tex_width; //width of texture buffer
|
||||
wxUint32 tex_height; //height of texture buffer
|
||||
int tile; //
|
||||
wxUint16 tile_uls; //shift from left bound of the texture
|
||||
wxUint16 tile_ult; //shift from top of the texture
|
||||
wxUint32 v_shift; //shift from top of the texture
|
||||
wxUint32 u_shift; //shift from left of the texture
|
||||
float lr_u;
|
||||
float lr_v;
|
||||
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
|
||||
CACHE_LUT * cache; //pointer to texture cache item
|
||||
GrTexInfo info;
|
||||
wxUint16 t_mem;
|
||||
} TBUFF_COLOR_IMAGE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GrChipID_t tmu;
|
||||
wxUint32 begin; //start of the block in video memory
|
||||
wxUint32 end; //end of the block in video memory
|
||||
wxUint8 count; //number of allocated texture buffers
|
||||
int clear_allowed; //stack of buffers can be cleared
|
||||
TBUFF_COLOR_IMAGE images[256];
|
||||
} TEXTURE_BUFFER;
|
||||
|
||||
#define NUMTEXBUF 92
|
||||
|
||||
struct RDP_Base{
|
||||
float vi_width;
|
||||
float vi_height;
|
||||
|
||||
int window_changed;
|
||||
|
||||
float offset_x, offset_y, offset_x_bak, offset_y_bak;
|
||||
|
||||
float scale_x, scale_1024, scale_x_bak;
|
||||
float scale_y, scale_768, scale_y_bak;
|
||||
|
||||
float view_scale[3];
|
||||
float view_trans[3];
|
||||
float clip_min_x, clip_max_x, clip_min_y, clip_max_y;
|
||||
float clip_ratio;
|
||||
|
||||
int updatescreen;
|
||||
|
||||
wxUint32 tri_n; // triangle counter
|
||||
wxUint32 debug_n;
|
||||
|
||||
// Program counter
|
||||
wxUint32 pc[10]; // DList PC stack
|
||||
wxUint32 pc_i; // current PC index in the stack
|
||||
int dl_count; // number of instructions before returning
|
||||
int LLE;
|
||||
|
||||
// Segments
|
||||
wxUint32 segment[16]; // Segment pointer
|
||||
|
||||
// Marks the end of DList execution (done in uc?:enddl)
|
||||
int halt;
|
||||
|
||||
// Next command
|
||||
wxUint32 cmd0;
|
||||
wxUint32 cmd1;
|
||||
wxUint32 cmd2;
|
||||
wxUint32 cmd3;
|
||||
|
||||
// Clipping
|
||||
SCISSOR scissor_o;
|
||||
SCISSOR scissor;
|
||||
int scissor_set;
|
||||
|
||||
// Colors
|
||||
wxUint32 fog_color;
|
||||
wxUint32 fill_color;
|
||||
wxUint32 prim_color;
|
||||
wxUint32 blend_color;
|
||||
wxUint32 env_color;
|
||||
wxUint32 SCALE;
|
||||
wxUint32 CENTER;
|
||||
wxUint32 prim_lodmin, prim_lodfrac;
|
||||
wxUint16 prim_depth;
|
||||
wxUint16 prim_dz;
|
||||
wxUint8 K4;
|
||||
wxUint8 K5;
|
||||
enum {
|
||||
noise_none,
|
||||
noise_combine,
|
||||
noise_texture
|
||||
} noise;
|
||||
|
||||
float col[4]; // color multiplier
|
||||
float coladd[4]; // color add/subtract
|
||||
float shade_factor;
|
||||
|
||||
float col_2[4];
|
||||
|
||||
wxUint32 cmb_flags, cmb_flags_2;
|
||||
|
||||
// othermode_l flags
|
||||
int acmp; // 0 = none, 1 = threshold, 2 = dither
|
||||
int zsrc; // 0 = pixel, 1 = prim
|
||||
wxUint8 alpha_dither_mode;
|
||||
|
||||
// Matrices
|
||||
DECLAREALIGN16VAR(model[4][4]);
|
||||
DECLAREALIGN16VAR(proj[4][4]);
|
||||
DECLAREALIGN16VAR(combined[4][4]);
|
||||
DECLAREALIGN16VAR(dkrproj[3][4][4]);
|
||||
|
||||
DECLAREALIGN16VAR(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
|
||||
wxUint8 tmem[4096]; // 4k tmem
|
||||
wxUint32 addr[512]; // 512 addresses (used to determine address loaded from)
|
||||
#ifdef TEXTURE_FILTER
|
||||
LOAD_TILE_INFO load_info[512]; // 512 addresses. inforamation about tile loading.
|
||||
#endif
|
||||
|
||||
int cur_tile; // current tile
|
||||
int mipmap_level;
|
||||
int last_tile; // last tile set
|
||||
int last_tile_size; // last tile size set
|
||||
|
||||
int t0, t1;
|
||||
int best_tex; // if no 2-tmus, which texture? (0 or 1)
|
||||
int tex;
|
||||
int filter_mode;
|
||||
|
||||
// Texture palette
|
||||
wxUint16 pal_8[256];
|
||||
wxUint32 pal_8_crc[16];
|
||||
wxUint32 pal_256_crc;
|
||||
wxUint8 tlut_mode;
|
||||
int LOD_en;
|
||||
int Persp_en;
|
||||
int persp_supported;
|
||||
int force_wrap;
|
||||
#ifdef TEXTURE_FILTER
|
||||
wxUint16 pal_8_rice[512];
|
||||
#endif
|
||||
|
||||
// Lighting
|
||||
wxUint32 num_lights;
|
||||
LIGHT light[12];
|
||||
float light_vector[12][3];
|
||||
float lookat[2][3];
|
||||
int use_lookat;
|
||||
|
||||
// Combine modes
|
||||
wxUint32 cycle1, cycle2, cycle_mode;
|
||||
wxUint8 c_a0, c_b0, c_c0, c_d0, c_Aa0, c_Ab0, c_Ac0, c_Ad0;
|
||||
wxUint8 c_a1, c_b1, c_c1, c_d1, c_Aa1, c_Ab1, c_Ac1, c_Ad1;
|
||||
|
||||
wxUint8 fbl_a0, fbl_b0, fbl_c0, fbl_d0;
|
||||
wxUint8 fbl_a1, fbl_b1, fbl_c1, fbl_d1;
|
||||
|
||||
wxUint8 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
|
||||
|
||||
// What needs updating
|
||||
wxUint32 update;
|
||||
wxUint32 flags;
|
||||
|
||||
int first;
|
||||
|
||||
wxUint32 tex_ctr; // incremented every time textures are updated
|
||||
|
||||
int allow_combine; // allow combine updating?
|
||||
|
||||
int s2dex_tex_loaded;
|
||||
wxUint16 bg_image_height;
|
||||
|
||||
// Debug stuff
|
||||
wxUint32 rm; // use othermode_l instead, this just as a check for changes
|
||||
wxUint32 render_mode_changed;
|
||||
wxUint32 geom_mode;
|
||||
|
||||
wxUint32 othermode_h;
|
||||
wxUint32 othermode_l;
|
||||
|
||||
// used to check if in texrect while loading texture
|
||||
wxUint8 texrecting;
|
||||
|
||||
//frame buffer related slots. Added by Gonetz
|
||||
wxUint32 cimg, ocimg, zimg, tmpzimg, vi_org_reg;
|
||||
COLOR_IMAGE maincimg[2];
|
||||
wxUint32 last_drawn_ci_addr;
|
||||
wxUint32 main_ci, main_ci_end, main_ci_bg, main_ci_last_tex_addr, zimg_end, last_bg;
|
||||
wxUint32 ci_width, ci_height, ci_size, ci_end;
|
||||
wxUint32 zi_width;
|
||||
int zi_lrx, zi_lry;
|
||||
wxUint8 ci_count, num_of_ci, main_ci_index, copy_ci_index, copy_zi_index;
|
||||
int swap_ci_index, black_ci_index;
|
||||
wxUint32 ci_upper_bound, ci_lower_bound;
|
||||
int motionblur, fb_drawn, fb_drawn_front, read_previous_ci, read_whole_frame;
|
||||
CI_STATUS ci_status;
|
||||
TBUFF_COLOR_IMAGE * cur_image; //image currently being drawn
|
||||
TBUFF_COLOR_IMAGE * tbuff_tex; //image, which corresponds to currently selected texture
|
||||
TBUFF_COLOR_IMAGE * aTBuffTex[2];
|
||||
wxUint8 cur_tex_buf;
|
||||
wxUint8 acc_tex_buf;
|
||||
int skip_drawing; //rendering is not required. used for frame buffer emulation
|
||||
|
||||
//fog related slots. Added by Gonetz
|
||||
float fog_multiplier, fog_offset;
|
||||
enum {
|
||||
fog_disabled,
|
||||
fog_enabled,
|
||||
fog_blend,
|
||||
fog_blend_inverse
|
||||
}
|
||||
fog_mode;
|
||||
};
|
||||
|
||||
struct RDP : public RDP_Base
|
||||
{
|
||||
// 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;
|
||||
|
||||
CACHE_LUT *cache[MAX_TMU]; //[MAX_CACHE]
|
||||
CACHE_LUT *cur_cache[MAX_TMU];
|
||||
wxUint32 cur_cache_n[MAX_TMU];
|
||||
int n_cached[MAX_TMU];
|
||||
|
||||
// Vertices
|
||||
VERTEX *vtx; //[MAX_VTX]
|
||||
int v0, vn;
|
||||
|
||||
COLOR_IMAGE *frame_buffers; //[NUMTEXBUF+2]
|
||||
TEXTURE_BUFFER texbufs[2];
|
||||
|
||||
char RomName[21];
|
||||
|
||||
RDP();
|
||||
~RDP();
|
||||
void Reset();
|
||||
};
|
||||
|
||||
|
||||
void SetWireframeCol ();
|
||||
void ChangeSize ();
|
||||
void GoToFullScreen();
|
||||
|
||||
extern RDP rdp;
|
||||
extern SETTINGS settings;
|
||||
extern HOTKEY_INFO hotkey_info;
|
||||
extern VOODOO voodoo;
|
||||
|
||||
extern GrTexInfo fontTex;
|
||||
extern GrTexInfo cursorTex;
|
||||
extern wxUint32 offset_font;
|
||||
extern wxUint32 offset_cursor;
|
||||
extern wxUint32 offset_textures;
|
||||
extern wxUint32 offset_texbuf1;
|
||||
|
||||
extern int ucode_error_report;
|
||||
|
||||
/*
|
||||
extern wxString pluginPath;
|
||||
extern wxString iniPath;
|
||||
*/
|
||||
// RDP functions
|
||||
void rdp_reset ();
|
||||
|
||||
extern const char *ACmp[];
|
||||
extern const char *Mode0[];
|
||||
extern const char *Mode1[];
|
||||
extern const char *Mode2[];
|
||||
extern const char *Mode3[];
|
||||
extern const char *Alpha0[];
|
||||
#define Alpha1 Alpha0
|
||||
extern const char *Alpha2[];
|
||||
#define Alpha3 Alpha0
|
||||
extern const char *FBLa[];
|
||||
extern const char *FBLb[];
|
||||
extern const char *FBLc[];
|
||||
extern const char *FBLd[];
|
||||
extern const char *str_zs[];
|
||||
extern const char *str_yn[];
|
||||
extern const char *str_offon[];
|
||||
extern const char *str_cull[];
|
||||
// I=intensity probably
|
||||
extern const char *str_format[];
|
||||
extern const char *str_size[];
|
||||
extern const char *str_cm[];
|
||||
extern const char *str_lod[];
|
||||
extern const char *str_aspect[];
|
||||
extern const char *str_filter[];
|
||||
extern const char *str_tlut[];
|
||||
extern const char *CIStatus[];
|
||||
|
||||
#define FBL_D_1 2
|
||||
#define FBL_D_0 3
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef HIWORD
|
||||
#define HIWORD(a) ((unsigned int)(a) >> 16)
|
||||
#endif
|
||||
#ifndef LOWORD
|
||||
#define LOWORD(a) ((a) & 0xFFFF)
|
||||
#endif
|
||||
|
||||
// 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)
|
||||
{
|
||||
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_mod = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__inline void AddOffset (VERTEX *v, int n)
|
||||
{
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
v[i].x += rdp.offset_x;
|
||||
v[i].y += rdp.offset_y;
|
||||
}
|
||||
}
|
||||
|
||||
__inline void CalculateFog (VERTEX *v)
|
||||
{
|
||||
if (rdp.flags & FOG_ENABLED)
|
||||
{
|
||||
if (v->w < 0.0f)
|
||||
v->f = 0.0f;
|
||||
else
|
||||
v->f = min(255.0f, max(0.0f, v->z_w * rdp.fog_multiplier + rdp.fog_offset));
|
||||
v->a = (wxUint8)v->f;
|
||||
}
|
||||
else
|
||||
{
|
||||
v->f = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void newSwapBuffers();
|
||||
extern int SwapOK;
|
||||
|
||||
// ** utility functions
|
||||
void load_palette (wxUint32 addr, wxUint16 start, wxUint16 count);
|
||||
void setTBufTex(wxUint16 t_mem, wxUint32 cnt);
|
||||
|
||||
#endif // ifndef RDP_H
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// Created by Gonetz, 2008
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
/******************Turbo3D microcode*************************/
|
||||
|
||||
struct t3dGlobState {
|
||||
wxUint16 pad0;
|
||||
wxUint16 perspNorm;
|
||||
wxUint32 flag;
|
||||
wxUint32 othermode0;
|
||||
wxUint32 othermode1;
|
||||
wxUint32 segBases[16];
|
||||
/* the viewport to use */
|
||||
short vsacle1;
|
||||
short vsacle0;
|
||||
short vsacle3;
|
||||
short vsacle2;
|
||||
short vtrans1;
|
||||
short vtrans0;
|
||||
short vtrans3;
|
||||
short vtrans2;
|
||||
wxUint32 rdpCmds;
|
||||
};
|
||||
|
||||
struct t3dState {
|
||||
wxUint32 renderState; /* render state */
|
||||
wxUint32 textureState; /* texture state */
|
||||
wxUint8 flag;
|
||||
wxUint8 triCount; /* how many tris? */
|
||||
wxUint8 vtxV0; /* where to load verts? */
|
||||
wxUint8 vtxCount; /* how many verts? */
|
||||
wxUint32 rdpCmds; /* ptr (segment address) to RDP DL */
|
||||
wxUint32 othermode0;
|
||||
wxUint32 othermode1;
|
||||
};
|
||||
|
||||
|
||||
struct t3dTriN{
|
||||
wxUint8 flag, v2, v1, v0; /* flag is which one for flat shade */
|
||||
};
|
||||
|
||||
|
||||
static void t3dProcessRDP(wxUint32 a)
|
||||
{
|
||||
if (a)
|
||||
{
|
||||
rdp.LLE = 1;
|
||||
rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
while (rdp.cmd0 + rdp.cmd1) {
|
||||
gfx_instruction[0][rdp.cmd0>>24] ();
|
||||
rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
wxUint32 cmd = rdp.cmd0>>24;
|
||||
if (cmd == 0xE4 || cmd == 0xE5)
|
||||
{
|
||||
rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
}
|
||||
}
|
||||
rdp.LLE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void t3dLoadGlobState(wxUint32 pgstate)
|
||||
{
|
||||
t3dGlobState *gstate = (t3dGlobState*)&gfx.RDRAM[segoffset(pgstate)];
|
||||
FRDP ("Global state. pad0: %04lx, perspNorm: %04lx, flag: %08lx\n", gstate->pad0, gstate->perspNorm, gstate->flag);
|
||||
rdp.cmd0 = gstate->othermode0;
|
||||
rdp.cmd1 = gstate->othermode1;
|
||||
rdp_setothermode();
|
||||
|
||||
for (int s = 0; s < 16; s++)
|
||||
{
|
||||
rdp.segment[s] = gstate->segBases[s];
|
||||
FRDP ("segment: %08lx -> seg%d\n", rdp.segment[s], s);
|
||||
}
|
||||
|
||||
short scale_x = gstate->vsacle0 / 4;
|
||||
short scale_y = gstate->vsacle1 / 4;;
|
||||
short scale_z = gstate->vsacle2;
|
||||
short trans_x = gstate->vtrans0 / 4;
|
||||
short trans_y = gstate->vtrans1 / 4;
|
||||
short trans_z = gstate->vtrans2;
|
||||
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)\n", scale_x, scale_y, scale_z,
|
||||
trans_x, trans_y, trans_z);
|
||||
|
||||
t3dProcessRDP(segoffset(gstate->rdpCmds) >> 2);
|
||||
}
|
||||
|
||||
static void t3d_vertex(wxUint32 addr, wxUint32 v0, wxUint32 n)
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
rdp.v0 = v0; // Current vertex
|
||||
rdp.vn = n; // Number of vertices to copy
|
||||
n <<= 4;
|
||||
|
||||
for (wxUint32 i=0; i < n; 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 = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
|
||||
v->ou = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1];
|
||||
v->ov = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1];
|
||||
v->uv_scaled = 0;
|
||||
v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3];
|
||||
v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3];
|
||||
v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3];
|
||||
v->a = ((wxUint8*)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];
|
||||
|
||||
if (fabs(v->w) < 0.001) v->w = 0.001f;
|
||||
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_mod = 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;
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void t3dLoadObject(wxUint32 pstate, wxUint32 pvtx, wxUint32 ptri)
|
||||
{
|
||||
LRDP("Loading Turbo3D object\n");
|
||||
t3dState *ostate = (t3dState*)&gfx.RDRAM[segoffset(pstate)];
|
||||
rdp.cur_tile = (ostate->textureState)&7;
|
||||
FRDP("tile: %d\n", rdp.cur_tile);
|
||||
if (rdp.tiles[rdp.cur_tile].s_scale < 0.001f)
|
||||
rdp.tiles[rdp.cur_tile].s_scale = 0.015625;
|
||||
if (rdp.tiles[rdp.cur_tile].t_scale < 0.001f)
|
||||
rdp.tiles[rdp.cur_tile].t_scale = 0.015625;
|
||||
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP("renderState: %08lx, textureState: %08lx, othermode0: %08lx, othermode1: %08lx, rdpCmds: %08lx, triCount : %d, v0: %d, vn: %d\n", ostate->renderState, ostate->textureState,
|
||||
ostate->othermode0, ostate->othermode1, ostate->rdpCmds, ostate->triCount, ostate->vtxV0, ostate->vtxCount);
|
||||
#endif
|
||||
|
||||
rdp.cmd0 = ostate->othermode0;
|
||||
rdp.cmd1 = ostate->othermode1;
|
||||
rdp_setothermode();
|
||||
|
||||
rdp.cmd1 = ostate->renderState;
|
||||
uc0_setgeometrymode();
|
||||
|
||||
if (!(ostate->flag&1)) //load matrix
|
||||
{
|
||||
wxUint32 addr = segoffset(pstate+sizeof(t3dState)) & BMASK;
|
||||
load_matrix(rdp.combined, addr);
|
||||
#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
|
||||
}
|
||||
|
||||
rdp.geom_mode &= ~0x00020000;
|
||||
rdp.geom_mode |= 0x00000200;
|
||||
if (pvtx) //load vtx
|
||||
t3d_vertex(segoffset(pvtx) & BMASK, ostate->vtxV0, ostate->vtxCount);
|
||||
|
||||
t3dProcessRDP(segoffset(ostate->rdpCmds) >> 2);
|
||||
|
||||
if (ptri)
|
||||
{
|
||||
update ();
|
||||
wxUint32 a = segoffset(ptri);
|
||||
for (int t=0; t < ostate->triCount; t++)
|
||||
{
|
||||
t3dTriN * tri = (t3dTriN*)&gfx.RDRAM[a];
|
||||
a += 4;
|
||||
FRDP("tri #%d - %d, %d, %d\n", t, tri->v0, tri->v1, tri->v2);
|
||||
VERTEX *v[3] = { &rdp.vtx[tri->v0], &rdp.vtx[tri->v1], &rdp.vtx[tri->v2] };
|
||||
if (cull_tri(v))
|
||||
rdp.tri_n ++;
|
||||
else
|
||||
{
|
||||
draw_tri (v);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Turbo3D()
|
||||
{
|
||||
LRDP("Start Turbo3D microcode\n");
|
||||
settings.ucode = ucode_Fast3D;
|
||||
wxUint32 a = 0, pgstate = 0, pstate = 0, pvtx = 0, ptri = 0;
|
||||
do {
|
||||
a = rdp.pc[rdp.pc_i] & BMASK;
|
||||
pgstate = ((wxUint32*)gfx.RDRAM)[a>>2];
|
||||
pstate = ((wxUint32*)gfx.RDRAM)[(a>>2)+1];
|
||||
pvtx = ((wxUint32*)gfx.RDRAM)[(a>>2)+2];
|
||||
ptri = ((wxUint32*)gfx.RDRAM)[(a>>2)+3];
|
||||
FRDP("GlobalState: %08lx, Object: %08lx, Vertices: %08lx, Triangles: %08lx\n", pgstate, pstate, pvtx, ptri);
|
||||
if (!pstate)
|
||||
{
|
||||
rdp.halt = 1;
|
||||
break;
|
||||
}
|
||||
if (pgstate)
|
||||
t3dLoadGlobState(pgstate);
|
||||
t3dLoadObject(pstate, pvtx, ptri);
|
||||
// Go to the next instruction
|
||||
rdp.pc[rdp.pc_i] += 16;
|
||||
} while (pstate);
|
||||
// rdp_fullsync();
|
||||
settings.ucode = ucode_Turbo3d;
|
||||
}
|
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
typedef void (*rdp_instr)();
|
||||
|
||||
// RDP graphic instructions pointer table
|
||||
|
||||
static rdp_instr gfx_instruction[10][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, rdphalf_cont, rdphalf_2,
|
||||
rdphalf_1, uc0_line3d, 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, 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, rdphalf_cont, rdphalf_2,
|
||||
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, rdphalf_cont, rdphalf_2,
|
||||
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, rdphalf_cont, rdphalf_2,
|
||||
rdphalf_1, uc0_line3d, 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, rdphalf_2,
|
||||
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, rdphalf_cont, rdphalf_2,
|
||||
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, 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, 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 9 - gzsort
|
||||
// games: Telefoot Soccer
|
||||
// 00-3f
|
||||
spnoop, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
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
|
||||
uc9_object, uc9_rpdcmd, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
undef, undef, undef, undef,
|
||||
rdphalf_1, undef, uc0_cleargeometrymode, uc0_setgeometrymode,
|
||||
uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture,
|
||||
uc0_moveword, undef, uc0_culldl, undef,
|
||||
// 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,
|
||||
|
||||
uc9_mix, uc9_fmlight, uc9_light, undef,
|
||||
uc9_mtxtrnsp, uc9_mtxcat, uc9_mult_mpmtx, uc9_link_subdl,
|
||||
uc9_set_subdl, uc9_wait_signal, uc9_send_signal, uc0_moveword,
|
||||
uc9_movemem, undef, uc0_displaylist, uc0_enddl,
|
||||
|
||||
undef, undef, uc0_setothermode_l, uc0_setothermode_h,
|
||||
rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync,
|
||||
rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr,
|
||||
rdp_setconvert, uc9_setscissor, rdp_setprimdepth, rdp_setothermode,
|
||||
|
||||
rdp_loadtlut, 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
|
||||
},
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
//
|
||||
// vertex - loads vertices
|
||||
//
|
||||
|
||||
static void uc1_vertex()
|
||||
{
|
||||
int v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex
|
||||
int n = (rdp.cmd0 >> 10) & 0x3F; // Number to copy
|
||||
rsp_vertex(v0, n);
|
||||
}
|
||||
|
||||
//
|
||||
// tri1 - renders a triangle
|
||||
//
|
||||
|
||||
static void uc1_tri1()
|
||||
{
|
||||
if (rdp.skip_drawing)
|
||||
{
|
||||
LRDP("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]
|
||||
};
|
||||
|
||||
rsp_tri1(v);
|
||||
}
|
||||
|
||||
static void uc1_tri2 ()
|
||||
{
|
||||
if (rdp.skip_drawing)
|
||||
{
|
||||
LRDP("uc1:tri2. skipped\n");
|
||||
return;
|
||||
}
|
||||
LRDP("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]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
||||
|
||||
static void uc1_line3d()
|
||||
{
|
||||
if (!settings.force_quad3d && ((rdp.cmd1&0xFF000000) == 0) && ((rdp.cmd0&0x00FFFFFF) == 0))
|
||||
{
|
||||
wxUint16 width = (wxUint16)(rdp.cmd1&0xFF) + 3;
|
||||
|
||||
FRDP("uc1:line3d width: %d #%d, #%d - %d, %d\n", width, 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]
|
||||
};
|
||||
wxUint32 cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT;
|
||||
rdp.flags |= CULLMASK;
|
||||
rdp.update |= UPDATE_CULL_MODE;
|
||||
rsp_tri1(v, width);
|
||||
rdp.flags ^= CULLMASK;
|
||||
rdp.flags |= cull_mode << CULLSHIFT;
|
||||
rdp.update |= UPDATE_CULL_MODE;
|
||||
}
|
||||
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]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
||||
}
|
||||
|
||||
wxUint32 branch_dl = 0;
|
||||
|
||||
static void uc1_rdphalf_1()
|
||||
{
|
||||
LRDP("uc1:rdphalf_1\n");
|
||||
branch_dl = rdp.cmd1;
|
||||
rdphalf_1();
|
||||
}
|
||||
|
||||
static void uc1_branch_z()
|
||||
{
|
||||
wxUint32 addr = segoffset(branch_dl);
|
||||
FRDP ("uc1:branch_less_z, addr: %08lx\n", addr);
|
||||
wxUint32 vtx = (rdp.cmd0 & 0xFFF) >> 1;
|
||||
if( fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/) )
|
||||
{
|
||||
rdp.pc[rdp.pc_i] = addr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,812 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
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 (wxUint32 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 = (wxUint8)(color[0]*255.0f);
|
||||
v->g = (wxUint8)(color[1]*255.0f);
|
||||
v->b = (wxUint8)(color[2]*255.0f);
|
||||
}
|
||||
|
||||
static void uc6_obj_rectangle();
|
||||
|
||||
static void uc2_vertex ()
|
||||
{
|
||||
if (!(rdp.cmd0 & 0x00FFFFFF))
|
||||
{
|
||||
uc6_obj_rectangle();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 (wxUint32 l=0; l<rdp.num_lights; l++)
|
||||
{
|
||||
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
|
||||
NormalizeVector (rdp.light_vector[l]);
|
||||
}
|
||||
}
|
||||
|
||||
wxUint32 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");
|
||||
LRDP("** ERROR: uc2:vertex v0 < 0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wxUint32 geom_mode = rdp.geom_mode;
|
||||
if ((settings.hacks&hack_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 = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
|
||||
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1];
|
||||
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1];
|
||||
v->uv_scaled = 0;
|
||||
v->a = ((wxUint8*)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];
|
||||
|
||||
if (fabs(v->w) < 0.001) v->w = 0.001f;
|
||||
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_mod = 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 (v->z_w > 1.0f) v->scr_off |= 32;
|
||||
|
||||
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 & 0x40000)
|
||||
{
|
||||
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
|
||||
{
|
||||
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 = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3];
|
||||
v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3];
|
||||
v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3];
|
||||
}
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a);
|
||||
#endif
|
||||
}
|
||||
rdp.geom_mode = geom_mode;
|
||||
}
|
||||
|
||||
static void uc2_modifyvtx ()
|
||||
{
|
||||
wxUint8 where = (wxUint8)((rdp.cmd0 >> 16) & 0xFF);
|
||||
wxUint16 vtx = (wxUint16)((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 ()
|
||||
{
|
||||
wxUint16 vStart = (wxUint16)(rdp.cmd0 & 0xFFFF) >> 1;
|
||||
wxUint16 vEnd = (wxUint16)(rdp.cmd1 & 0xFFFF) >> 1;
|
||||
wxUint32 cond = 0;
|
||||
FRDP ("uc2:culldl start: %d, end: %d\n", vStart, vEnd);
|
||||
|
||||
if (vEnd < vStart) return;
|
||||
for (wxUint16 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;
|
||||
}
|
||||
|
||||
LRDP(" - "); // specify that the enddl is not a real command
|
||||
uc0_enddl ();
|
||||
}
|
||||
|
||||
static void uc6_obj_loadtxtr ();
|
||||
|
||||
static void uc2_tri1()
|
||||
{
|
||||
if ((rdp.cmd0 & 0x00FFFFFF) == 0x17)
|
||||
{
|
||||
uc6_obj_loadtxtr ();
|
||||
return;
|
||||
}
|
||||
if (rdp.skip_drawing)
|
||||
{
|
||||
LRDP("uc2:tri1. skipped\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FRDP("uc2: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]
|
||||
};
|
||||
|
||||
rsp_tri1(v);
|
||||
}
|
||||
|
||||
static void uc6_obj_ldtx_sprite ();
|
||||
static void uc6_obj_ldtx_rect ();
|
||||
|
||||
static void uc2_quad ()
|
||||
{
|
||||
if ((rdp.cmd0 & 0x00FFFFFF) == 0x2F)
|
||||
{
|
||||
wxUint32 command = rdp.cmd0>>24;
|
||||
if (command == 0x6)
|
||||
{
|
||||
uc6_obj_ldtx_sprite ();
|
||||
return;
|
||||
}
|
||||
if (command == 0x7)
|
||||
{
|
||||
uc6_obj_ldtx_rect ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rdp.skip_drawing)
|
||||
{
|
||||
LRDP("uc2_quad. skipped\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LRDP("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]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
||||
|
||||
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]
|
||||
};
|
||||
wxUint16 width = (wxUint16)(rdp.cmd0 + 3)&0xFF;
|
||||
wxUint32 cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT;
|
||||
rdp.flags |= CULLMASK;
|
||||
rdp.update |= UPDATE_CULL_MODE;
|
||||
rsp_tri1(v, width);
|
||||
rdp.flags ^= CULLMASK;
|
||||
rdp.flags |= cull_mode << CULLSHIFT;
|
||||
rdp.update |= UPDATE_CULL_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
static void uc2_special3 ()
|
||||
{
|
||||
LRDP("uc2:special3\n");
|
||||
}
|
||||
|
||||
static void uc2_special2 ()
|
||||
{
|
||||
LRDP("uc2:special2\n");
|
||||
}
|
||||
|
||||
static void uc2_dma_io ()
|
||||
{
|
||||
LRDP("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
|
||||
wxUint32 clr_mode = (rdp.cmd0 & 0x00DFC9FF) |
|
||||
((rdp.cmd0 & 0x00000600) << 3) |
|
||||
((rdp.cmd0 & 0x00200000) >> 12) | 0xFF000000;
|
||||
wxUint32 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uc6_obj_rectangle_r ();
|
||||
|
||||
static void uc2_matrix ()
|
||||
{
|
||||
if (!(rdp.cmd0 & 0x00FFFFFF))
|
||||
{
|
||||
uc6_obj_rectangle_r();
|
||||
return;
|
||||
}
|
||||
LRDP("uc2:matrix\n");
|
||||
|
||||
DECLAREALIGN16VAR(m[4][4]);
|
||||
load_matrix(m, segoffset(rdp.cmd1));
|
||||
|
||||
wxUint8 command = (wxUint8)((rdp.cmd0 ^ 1) & 0xFF);
|
||||
switch (command)
|
||||
{
|
||||
case 0: // modelview mul nopush
|
||||
LRDP("modelview mul\n");
|
||||
modelview_mul (m);
|
||||
break;
|
||||
|
||||
case 1: // modelview mul push
|
||||
LRDP("modelview mul push\n");
|
||||
modelview_mul_push (m);
|
||||
break;
|
||||
|
||||
case 2: // modelview load nopush
|
||||
LRDP("modelview load\n");
|
||||
modelview_load (m);
|
||||
break;
|
||||
|
||||
case 3: // modelview load push
|
||||
LRDP("modelview load push\n");
|
||||
modelview_load_push (m);
|
||||
break;
|
||||
|
||||
case 4: // projection mul nopush
|
||||
case 5: // projection mul push, can't push projection
|
||||
LRDP("projection mul\n");
|
||||
projection_mul (m);
|
||||
break;
|
||||
|
||||
case 6: // projection load nopush
|
||||
case 7: // projection load push, can't push projection
|
||||
LRDP("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 ()
|
||||
{
|
||||
wxUint8 index = (wxUint8)((rdp.cmd0 >> 16) & 0xFF);
|
||||
wxUint16 offset = (wxUint16)(rdp.cmd0 & 0xFFFF);
|
||||
wxUint32 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);
|
||||
}
|
||||
|
||||
LRDP("matrix\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
rdp.num_lights = data / 24;
|
||||
rdp.update |= UPDATE_LIGHTS;
|
||||
FRDP ("numlights: %d\n", rdp.num_lights);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
if (offset == 0x04)
|
||||
{
|
||||
rdp.clip_ratio = sqrt((float)rdp.cmd1);
|
||||
rdp.update |= UPDATE_VIEWPORT;
|
||||
}
|
||||
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);
|
||||
|
||||
//offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte
|
||||
//low-level display list has setothermode commands in this place, so this is obviously not move_fog.
|
||||
if (offset == 0x04)
|
||||
rdp.tlut_mode = (data == 0xffffffff) ? 0 : 2;
|
||||
}
|
||||
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");
|
||||
LRDP("forcemtx - IGNORED\n");
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
LRDP("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);
|
||||
}
|
||||
}
|
||||
|
||||
static void uc6_obj_movemem ();
|
||||
|
||||
static void uc2_movemem ()
|
||||
{
|
||||
int idx = rdp.cmd0 & 0xFF;
|
||||
wxUint32 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
|
||||
{
|
||||
wxUint32 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
|
||||
wxUint8 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;
|
||||
wxUint32 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;
|
||||
load_matrix(rdp.combined, segoffset(rdp.cmd1));
|
||||
|
||||
#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 ()
|
||||
{
|
||||
LRDP("uc2:load_ucode\n");
|
||||
}
|
||||
|
||||
static void uc2_rdphalf_2 ()
|
||||
{
|
||||
LRDP("uc2:rdphalf_2\n");
|
||||
}
|
||||
|
||||
static void uc2_dlist_cnt ()
|
||||
{
|
||||
wxUint32 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");
|
||||
LRDP("** 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;
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
//
|
||||
// vertex - loads vertices
|
||||
//
|
||||
|
||||
static void uc3_vertex()
|
||||
{
|
||||
int v0 = ((rdp.cmd0 >> 16) & 0xFF)/5; // Current vertex
|
||||
int n = (wxUint16)((rdp.cmd0&0xFFFF) + 1)/0x210; // Number to copy
|
||||
|
||||
if (v0 >= 32)
|
||||
v0 = 31;
|
||||
|
||||
if ((v0 + n) > 32)
|
||||
n = 32 - v0;
|
||||
|
||||
rsp_vertex(v0, n);
|
||||
}
|
||||
|
||||
//
|
||||
// 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]
|
||||
};
|
||||
|
||||
rsp_tri1(v);
|
||||
}
|
||||
|
||||
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]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
||||
|
||||
static void uc3_quad3d()
|
||||
{
|
||||
FRDP("uc3: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 & 0xFF)/5],
|
||||
&rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5],
|
||||
&rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
//****************************************************************
|
||||
// uCode 4 - RSP SW 2.0D EXT
|
||||
//****************************************************************
|
||||
|
||||
static void uc4_vertex()
|
||||
{
|
||||
int v0 = 0; // Current vertex
|
||||
int n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy
|
||||
rsp_vertex(v0, n);
|
||||
}
|
||||
|
||||
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]
|
||||
};
|
||||
|
||||
rsp_tri1(v);
|
||||
}
|
||||
|
||||
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]
|
||||
};
|
||||
|
||||
rsp_tri2(v);
|
||||
}
|
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
int cur_mtx = 0;
|
||||
int billboarding = 0;
|
||||
int vtx_last = 0;
|
||||
wxUint32 dma_offset_mtx = 0;
|
||||
wxUint32 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
|
||||
wxUint32 addr = dma_offset_mtx + (segoffset(rdp.cmd1) & BMASK);
|
||||
|
||||
wxUint8 n = (wxUint8)((rdp.cmd0 >> 16) & 0xF);
|
||||
wxUint8 multiply;
|
||||
|
||||
if (n == 0) //DKR
|
||||
{
|
||||
n = (wxUint8)((rdp.cmd0 >> 22) & 0x3);
|
||||
multiply = 0;
|
||||
}
|
||||
else //JF
|
||||
{
|
||||
multiply = (wxUint8)((rdp.cmd0 >> 23) & 0x1);
|
||||
}
|
||||
|
||||
cur_mtx = n;
|
||||
|
||||
FRDP("uc5:matrix - #%d, addr: %08lx\n", n, addr);
|
||||
|
||||
if (multiply)
|
||||
{
|
||||
DECLAREALIGN16VAR(m[4][4]);
|
||||
load_matrix(m, addr);
|
||||
DECLAREALIGN16VAR(m_src[4][4]);
|
||||
memcpy (m_src, rdp.dkrproj[0], 64);
|
||||
MulMatrices(m, m_src, rdp.dkrproj[n]);
|
||||
}
|
||||
else
|
||||
{
|
||||
load_matrix(rdp.dkrproj[n], addr);
|
||||
}
|
||||
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 ()
|
||||
{
|
||||
wxUint32 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.hacks&hack_Diddy)
|
||||
n++;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (fabs(v->w) < 0.001) v->w = 0.001f;
|
||||
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_mod = 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 (fabs(v->z_w) > 1.0) v->scr_off |= 32;
|
||||
|
||||
v->r = ((wxUint8*)gfx.RDRAM)[(addr+start + 6)^3];
|
||||
v->g = ((wxUint8*)gfx.RDRAM)[(addr+start + 7)^3];
|
||||
v->b = ((wxUint8*)gfx.RDRAM)[(addr+start + 8)^3];
|
||||
v->a = ((wxUint8*)gfx.RDRAM)[(addr+start + 9)^3];
|
||||
CalculateFog (v);
|
||||
|
||||
#ifdef EXTREME_LOGGING
|
||||
FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v->x, v->y, v->z, v->w, v->z_w, v->r, v->g, v->b, v->a);
|
||||
#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
|
||||
|
||||
wxUint32 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 ();
|
||||
|
||||
draw_tri (v);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uc5_dl_in_mem ()
|
||||
{
|
||||
wxUint32 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");
|
||||
LRDP("** 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()
|
||||
{
|
||||
LRDP("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)
|
||||
if (((rdp.cmd0>>8)&0xFFFF) == 0x04)
|
||||
{
|
||||
rdp.clip_ratio = sqrt((float)rdp.cmd1);
|
||||
rdp.update |= UPDATE_VIEWPORT;
|
||||
}
|
||||
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
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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!
|
||||
//****************************************************************
|
||||
|
||||
wxUint32 pd_col_addr = 0;
|
||||
|
||||
static void uc7_colorbase ()
|
||||
{
|
||||
LRDP("uc7_colorbase\n");
|
||||
pd_col_addr = segoffset(rdp.cmd1);
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short y;
|
||||
short x;
|
||||
wxUint16 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 (wxUint32 l=0; l<rdp.num_lights; l++)
|
||||
{
|
||||
InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
|
||||
NormalizeVector (rdp.light_vector[l]);
|
||||
}
|
||||
}
|
||||
|
||||
wxUint32 addr = segoffset(rdp.cmd1);
|
||||
wxUint32 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;
|
||||
v->ov = (float)vertex->t;
|
||||
v->uv_scaled = 0;
|
||||
|
||||
#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];
|
||||
|
||||
|
||||
if (fabs(v->w) < 0.001) v->w = 0.001f;
|
||||
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;
|
||||
|
||||
wxUint8 *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++;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// January 2004 Created by Gonetz (Gonetz@ngs.ru)
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
wxUint32 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);
|
||||
}
|
||||
|
||||
wxUint32 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");
|
||||
LRDP("** 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 (wxUint32 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 = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
|
||||
v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1];
|
||||
v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1];
|
||||
v->uv_scaled = 0;
|
||||
v->a = ((wxUint8*)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
|
||||
|
||||
if (fabs(v->w) < 0.001) v->w = 0.001f;
|
||||
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_mod = 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;
|
||||
///*
|
||||
v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3];
|
||||
v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3];
|
||||
v->b = ((wxUint8*)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))
|
||||
{
|
||||
wxUint32 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;
|
||||
wxUint32 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 = (wxUint8)(((float)v->r)*color[0]);
|
||||
v->g = (wxUint8)(((float)v->g)*color[1]);
|
||||
v->b = (wxUint8)(((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 ()
|
||||
{
|
||||
wxUint8 index = (wxUint8)((rdp.cmd0 >> 16) & 0xFF);
|
||||
wxUint16 offset = (wxUint16)(rdp.cmd0 & 0xFFFF);
|
||||
wxUint32 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:
|
||||
if (offset == 0x04)
|
||||
{
|
||||
rdp.clip_ratio = sqrt((float)rdp.cmd1);
|
||||
rdp.update |= UPDATE_VIEWPORT;
|
||||
}
|
||||
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");
|
||||
LRDP("forcemtx - IGNORED\n");
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
LRDP("perspnorm - IGNORED\n");
|
||||
break;
|
||||
|
||||
case 0x10: // moveword coord mod
|
||||
{
|
||||
wxUint8 n = offset >> 2;
|
||||
|
||||
FRDP ("coord mod:%d, %08lx\n", n, data);
|
||||
if (rdp.cmd0&8)
|
||||
return;
|
||||
wxUint32 idx = (rdp.cmd0>>1)&3;
|
||||
wxUint32 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;
|
||||
wxUint32 addr = segoffset(rdp.cmd1);
|
||||
int ofs = (rdp.cmd0 >> 5) & 0x3FFF;
|
||||
|
||||
FRDP ("uc8:movemem ofs:%d ", ofs);
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case 8: // VIEWPORT
|
||||
{
|
||||
wxUint32 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;
|
||||
wxUint8 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;
|
||||
// **
|
||||
wxUint32 a = addr >> 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, ((wxUint16*)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
|
||||
int i;
|
||||
for (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);
|
||||
}
|
||||
wxUint32 a = uc8_normale_addr >> 1;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
FRDP ("n[%d] = 0x%04lx \n", i, ((wxUint16*)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)
|
||||
{
|
||||
LRDP("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]
|
||||
};
|
||||
|
||||
int updated = 0;
|
||||
|
||||
if (cull_tri(v))
|
||||
rdp.tri_n ++;
|
||||
else
|
||||
{
|
||||
updated = 1;
|
||||
update ();
|
||||
|
||||
draw_tri (v);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
|
||||
if (cull_tri(v+3))
|
||||
rdp.tri_n ++;
|
||||
else
|
||||
{
|
||||
if (!updated)
|
||||
{
|
||||
updated = 1;
|
||||
update ();
|
||||
}
|
||||
|
||||
draw_tri (v+3);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
|
||||
if (cull_tri(v+6))
|
||||
rdp.tri_n ++;
|
||||
else
|
||||
{
|
||||
if (!updated)
|
||||
{
|
||||
updated = 1;
|
||||
update ();
|
||||
}
|
||||
|
||||
draw_tri (v+6);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
|
||||
if (cull_tri(v+9))
|
||||
rdp.tri_n ++;
|
||||
else
|
||||
{
|
||||
if (!updated)
|
||||
{
|
||||
updated = 1;
|
||||
update ();
|
||||
}
|
||||
|
||||
draw_tri (v+9);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,688 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// December 2008 Created by Gonetz (Gonetz@ngs.ru)
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
void uc9_rpdcmd ();
|
||||
|
||||
typedef float M44[4][4];
|
||||
|
||||
struct ZSORTRDP {
|
||||
float view_scale[2];
|
||||
float view_trans[2];
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
} zSortRdp = {{0, 0}, {0, 0}, 0, 0};
|
||||
|
||||
//RSP command VRCPL
|
||||
static int Calc_invw (int w) {
|
||||
int count, neg;
|
||||
union {
|
||||
wxInt32 W;
|
||||
wxUint32 UW;
|
||||
wxInt16 HW[2];
|
||||
wxUint16 UHW[2];
|
||||
} Result;
|
||||
Result.W = w;
|
||||
if (Result.UW == 0) {
|
||||
Result.UW = 0x7FFFFFFF;
|
||||
} else {
|
||||
if (Result.W < 0) {
|
||||
neg = TRUE;
|
||||
if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) {
|
||||
Result.W = ~Result.W + 1;
|
||||
} else {
|
||||
Result.W = ~Result.W;
|
||||
}
|
||||
} else {
|
||||
neg = FALSE;
|
||||
}
|
||||
for (count = 31; count > 0; count--) {
|
||||
if ((Result.W & (1 << count))) {
|
||||
Result.W &= (0xFFC00000 >> (31 - count) );
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
Result.W = 0x7FFFFFFF / Result.W;
|
||||
for (count = 31; count > 0; count--) {
|
||||
if ((Result.W & (1 << count))) {
|
||||
Result.W &= (0xFFFF8000 >> (31 - count) );
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
if (neg == TRUE) {
|
||||
Result.W = ~Result.W;
|
||||
}
|
||||
}
|
||||
return Result.W;
|
||||
}
|
||||
|
||||
static void uc9_draw_object (wxUint8 * addr, wxUint32 type)
|
||||
{
|
||||
wxUint32 textured, vnum, vsize;
|
||||
switch (type) {
|
||||
case 1: //sh tri
|
||||
textured = 0;
|
||||
vnum = 3;
|
||||
vsize = 8;
|
||||
break;
|
||||
case 2: //tx tri
|
||||
textured = 1;
|
||||
vnum = 3;
|
||||
vsize = 16;
|
||||
break;
|
||||
case 3: //sh quad
|
||||
textured = 0;
|
||||
vnum = 4;
|
||||
vsize = 8;
|
||||
break;
|
||||
case 4: //tx quad
|
||||
textured = 1;
|
||||
vnum = 4;
|
||||
vsize = 16;
|
||||
break;
|
||||
case 0: //null
|
||||
default:
|
||||
textured = vnum = vsize = 0;
|
||||
break;
|
||||
}
|
||||
VERTEX vtx[4];
|
||||
for (wxUint32 i = 0; i < vnum; i++)
|
||||
{
|
||||
VERTEX &v = vtx[i];
|
||||
v.sx = zSortRdp.scale_x * ((short*)addr)[0^1];
|
||||
v.sy = zSortRdp.scale_y * ((short*)addr)[1^1];
|
||||
v.sz = 1.0f;
|
||||
v.r = addr[4^3];
|
||||
v.g = addr[5^3];
|
||||
v.b = addr[6^3];
|
||||
v.a = addr[7^3];
|
||||
v.flags = 0;
|
||||
v.uv_scaled = 0;
|
||||
v.uv_calculated = 0xFFFFFFFF;
|
||||
v.shade_mod = 0;
|
||||
v.scr_off = 0;
|
||||
v.screen_translated = 2;
|
||||
if (textured)
|
||||
{
|
||||
v.ou = ((short*)addr)[4^1];
|
||||
v.ov = ((short*)addr)[5^1];
|
||||
v.w = Calc_invw(((int*)addr)[3]) / 31.0f;
|
||||
v.oow = 1.0f / v.w;
|
||||
FRDP ("v%d - sx: %f, sy: %f ou: %f, ov: %f, w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.ou*rdp.tiles[rdp.cur_tile].s_scale, v.ov*rdp.tiles[rdp.cur_tile].t_scale, v.w, v.r, v.g, v.b, v.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
v.oow = v.w = 1.0f;
|
||||
FRDP ("v%d - sx: %f, sy: %f r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.r, v.g, v.b, v.a);
|
||||
}
|
||||
addr += vsize;
|
||||
}
|
||||
//*
|
||||
VERTEX *pV[4] = {
|
||||
&vtx[0],
|
||||
&vtx[1],
|
||||
&vtx[2],
|
||||
&vtx[3]
|
||||
};
|
||||
if (vnum == 3)
|
||||
{
|
||||
FRDP("uc9:Tri #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
|
||||
draw_tri (pV, 0);
|
||||
rdp.tri_n ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
FRDP("uc9:Quad #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
|
||||
draw_tri (pV, 0);
|
||||
draw_tri (pV+1, 0);
|
||||
rdp.tri_n += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static wxUint32 uc9_load_object (wxUint32 zHeader, wxUint32 * rdpcmds)
|
||||
{
|
||||
wxUint32 type = zHeader & 7;
|
||||
wxUint8 * addr = gfx.RDRAM + (zHeader&0xFFFFFFF8);
|
||||
switch (type) {
|
||||
case 1: //sh tri
|
||||
case 3: //sh quad
|
||||
{
|
||||
rdp.cmd1 = ((wxUint32*)addr)[1];
|
||||
if (rdp.cmd1 != rdpcmds[0])
|
||||
{
|
||||
rdpcmds[0] = rdp.cmd1;
|
||||
uc9_rpdcmd ();
|
||||
}
|
||||
update ();
|
||||
uc9_draw_object(addr + 8, type);
|
||||
}
|
||||
break;
|
||||
case 0: //null
|
||||
case 2: //tx tri
|
||||
case 4: //tx quad
|
||||
{
|
||||
rdp.cmd1 = ((wxUint32*)addr)[1];
|
||||
if (rdp.cmd1 != rdpcmds[0])
|
||||
{
|
||||
rdpcmds[0] = rdp.cmd1;
|
||||
uc9_rpdcmd ();
|
||||
}
|
||||
rdp.cmd1 = ((wxUint32*)addr)[2];
|
||||
if (rdp.cmd1 != rdpcmds[1])
|
||||
{
|
||||
uc9_rpdcmd ();
|
||||
rdpcmds[1] = rdp.cmd1;
|
||||
}
|
||||
rdp.cmd1 = ((wxUint32*)addr)[3];
|
||||
if (rdp.cmd1 != rdpcmds[2])
|
||||
{
|
||||
uc9_rpdcmd ();
|
||||
rdpcmds[2] = rdp.cmd1;
|
||||
}
|
||||
if (type)
|
||||
{
|
||||
update ();
|
||||
uc9_draw_object(addr + 16, type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return segoffset(((wxUint32*)addr)[0]);
|
||||
}
|
||||
|
||||
static void uc9_object ()
|
||||
{
|
||||
LRDP("uc9:object\n");
|
||||
wxUint32 rdpcmds[3] = {0, 0, 0};
|
||||
wxUint32 cmd1 = rdp.cmd1;
|
||||
wxUint32 zHeader = segoffset(rdp.cmd0);
|
||||
while (zHeader)
|
||||
zHeader = uc9_load_object(zHeader, rdpcmds);
|
||||
zHeader = segoffset(cmd1);
|
||||
while (zHeader)
|
||||
zHeader = uc9_load_object(zHeader, rdpcmds);
|
||||
}
|
||||
|
||||
static void uc9_mix ()
|
||||
{
|
||||
LRDP("uc9:mix IGNORED\n");
|
||||
}
|
||||
|
||||
static void uc9_fmlight ()
|
||||
{
|
||||
int mid = rdp.cmd0&0xFF;
|
||||
rdp.num_lights = 1 + ((rdp.cmd1>>12)&0xFF);
|
||||
wxUint32 a = -1024 + (rdp.cmd1&0xFFF);
|
||||
FRDP ("uc9:fmlight matrix: %d, num: %d, dmem: %04lx\n", mid, rdp.num_lights, a);
|
||||
|
||||
M44 *m = NULL;
|
||||
switch (mid) {
|
||||
case 4:
|
||||
m = (M44*)rdp.model;
|
||||
break;
|
||||
case 6:
|
||||
m = (M44*)rdp.proj;
|
||||
break;
|
||||
case 8:
|
||||
m = (M44*)rdp.combined;
|
||||
break;
|
||||
}
|
||||
|
||||
rdp.light[rdp.num_lights].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f;
|
||||
rdp.light[rdp.num_lights].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f;
|
||||
rdp.light[rdp.num_lights].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f;
|
||||
rdp.light[rdp.num_lights].a = 1.0f;
|
||||
FRDP ("ambient light: r: %.3f, g: %.3f, b: %.3f\n", rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b);
|
||||
a += 8;
|
||||
wxUint32 i;
|
||||
for (i = 0; i < rdp.num_lights; i++)
|
||||
{
|
||||
rdp.light[i].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f;
|
||||
rdp.light[i].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f;
|
||||
rdp.light[i].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f;
|
||||
rdp.light[i].a = 1.0f;
|
||||
rdp.light[i].dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f;
|
||||
rdp.light[i].dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f;
|
||||
rdp.light[i].dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f;
|
||||
FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n",
|
||||
i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b,
|
||||
rdp.light[i].dir_x, rdp.light[i].dir_y, rdp.light[i].dir_z);
|
||||
// TransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m);
|
||||
InverseTransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m);
|
||||
NormalizeVector (rdp.light_vector[i]);
|
||||
FRDP ("light vector: n: %d, x: %.3f, y: %.3f, z: %.3f\n",
|
||||
i, rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]);
|
||||
a += 24;
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
float dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f;
|
||||
float dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f;
|
||||
float dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f;
|
||||
if (sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) < 0.98)
|
||||
{
|
||||
rdp.use_lookat = FALSE;
|
||||
return;
|
||||
}
|
||||
rdp.lookat[i][0] = dir_x;
|
||||
rdp.lookat[i][1] = dir_y;
|
||||
rdp.lookat[i][2] = dir_z;
|
||||
a += 24;
|
||||
}
|
||||
rdp.use_lookat = TRUE;
|
||||
}
|
||||
|
||||
static void uc9_light ()
|
||||
{
|
||||
wxUint32 csrs = -1024 + ((rdp.cmd0>>12)&0xFFF);
|
||||
wxUint32 nsrs = -1024 + (rdp.cmd0&0xFFF);
|
||||
wxUint32 num = 1 + ((rdp.cmd1>>24)&0xFF);
|
||||
wxUint32 cdest = -1024 + ((rdp.cmd1>>12)&0xFFF);
|
||||
wxUint32 tdest = -1024 + (rdp.cmd1&0xFFF);
|
||||
int use_material = (csrs != 0x0ff0);
|
||||
tdest >>= 1;
|
||||
FRDP ("uc9:light n: %d, colsrs: %04lx, normales: %04lx, coldst: %04lx, texdst: %04lx\n", num, csrs, nsrs, cdest, tdest);
|
||||
VERTEX v;
|
||||
for (wxUint32 i = 0; i < num; i++)
|
||||
{
|
||||
v.vec[0] = ((char*)gfx.DMEM)[(nsrs++)^3];
|
||||
v.vec[1] = ((char*)gfx.DMEM)[(nsrs++)^3];
|
||||
v.vec[2] = ((char*)gfx.DMEM)[(nsrs++)^3];
|
||||
calc_sphere (&v);
|
||||
// calc_linear (&v);
|
||||
NormalizeVector (v.vec);
|
||||
calc_light (&v);
|
||||
v.a = 0xFF;
|
||||
if (use_material)
|
||||
{
|
||||
v.r = (wxUint8)(((wxUint32)v.r * gfx.DMEM[(csrs++)^3])>>8);
|
||||
v.g = (wxUint8)(((wxUint32)v.g * gfx.DMEM[(csrs++)^3])>>8);
|
||||
v.b = (wxUint8)(((wxUint32)v.b * gfx.DMEM[(csrs++)^3])>>8);
|
||||
v.a = gfx.DMEM[(csrs++)^3];
|
||||
}
|
||||
gfx.DMEM[(cdest++)^3] = v.r;
|
||||
gfx.DMEM[(cdest++)^3] = v.g;
|
||||
gfx.DMEM[(cdest++)^3] = v.b;
|
||||
gfx.DMEM[(cdest++)^3] = v.a;
|
||||
((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ou;
|
||||
((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ov;
|
||||
}
|
||||
}
|
||||
|
||||
static void uc9_mtxtrnsp ()
|
||||
{
|
||||
LRDP("uc9:mtxtrnsp - ignored\n");
|
||||
/*
|
||||
LRDP("uc9:mtxtrnsp ");
|
||||
M44 *s;
|
||||
switch (rdp.cmd1&0xF) {
|
||||
case 4:
|
||||
s = (M44*)rdp.model;
|
||||
LRDP("Model\n");
|
||||
break;
|
||||
case 6:
|
||||
s = (M44*)rdp.proj;
|
||||
LRDP("Proj\n");
|
||||
break;
|
||||
case 8:
|
||||
s = (M44*)rdp.combined;
|
||||
LRDP("Comb\n");
|
||||
break;
|
||||
}
|
||||
float m = *s[1][0];
|
||||
*s[1][0] = *s[0][1];
|
||||
*s[0][1] = m;
|
||||
m = *s[2][0];
|
||||
*s[2][0] = *s[0][2];
|
||||
*s[0][2] = m;
|
||||
m = *s[2][1];
|
||||
*s[2][1] = *s[1][2];
|
||||
*s[1][2] = m;
|
||||
*/
|
||||
}
|
||||
|
||||
static void uc9_mtxcat ()
|
||||
{
|
||||
LRDP("uc9:mtxcat ");
|
||||
M44 *s = NULL;
|
||||
M44 *t = NULL;
|
||||
wxUint32 S = rdp.cmd0&0xF;
|
||||
wxUint32 T = (rdp.cmd1>>16)&0xF;
|
||||
wxUint32 D = rdp.cmd1&0xF;
|
||||
switch (S) {
|
||||
case 4:
|
||||
s = (M44*)rdp.model;
|
||||
LRDP("Model * ");
|
||||
break;
|
||||
case 6:
|
||||
s = (M44*)rdp.proj;
|
||||
LRDP("Proj * ");
|
||||
break;
|
||||
case 8:
|
||||
s = (M44*)rdp.combined;
|
||||
LRDP("Comb * ");
|
||||
break;
|
||||
}
|
||||
switch (T) {
|
||||
case 4:
|
||||
t = (M44*)rdp.model;
|
||||
LRDP("Model -> ");
|
||||
break;
|
||||
case 6:
|
||||
t = (M44*)rdp.proj;
|
||||
LRDP("Proj -> ");
|
||||
break;
|
||||
case 8:
|
||||
LRDP("Comb -> ");
|
||||
t = (M44*)rdp.combined;
|
||||
break;
|
||||
}
|
||||
DECLAREALIGN16VAR(m[4][4]);
|
||||
MulMatrices(*s, *t, m);
|
||||
|
||||
switch (D) {
|
||||
case 4:
|
||||
memcpy (rdp.model, m, 64);;
|
||||
LRDP("Model\n");
|
||||
break;
|
||||
case 6:
|
||||
memcpy (rdp.proj, m, 64);;
|
||||
LRDP("Proj\n");
|
||||
break;
|
||||
case 8:
|
||||
memcpy (rdp.combined, m, 64);;
|
||||
LRDP("Comb\n");
|
||||
break;
|
||||
}
|
||||
#ifdef EXTREME_LOGGING
|
||||
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]);
|
||||
FRDP ("\ncombined\n{%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
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
short sy;
|
||||
short sx;
|
||||
int invw;
|
||||
short yi;
|
||||
short xi;
|
||||
short wi;
|
||||
wxUint8 fog;
|
||||
wxUint8 cc;
|
||||
} zSortVDest;
|
||||
|
||||
static void uc9_mult_mpmtx ()
|
||||
{
|
||||
//int id = rdp.cmd0&0xFF;
|
||||
int num = 1+ ((rdp.cmd1>>24)&0xFF);
|
||||
int src = -1024 + ((rdp.cmd1>>12)&0xFFF);
|
||||
int dst = -1024 + (rdp.cmd1&0xFFF);
|
||||
FRDP ("uc9:mult_mpmtx from: %04lx to: %04lx n: %d\n", src, dst, num);
|
||||
short * saddr = (short*)(gfx.DMEM+src);
|
||||
zSortVDest * daddr = (zSortVDest*)(gfx.DMEM+dst);
|
||||
int idx = 0;
|
||||
zSortVDest v;
|
||||
memset(&v, 0, sizeof(zSortVDest));
|
||||
//float scale_x = 4.0f/rdp.scale_x;
|
||||
//float scale_y = 4.0f/rdp.scale_y;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
short sx = saddr[(idx++)^1];
|
||||
short sy = saddr[(idx++)^1];
|
||||
short sz = saddr[(idx++)^1];
|
||||
float x = sx*rdp.combined[0][0] + sy*rdp.combined[1][0] + sz*rdp.combined[2][0] + rdp.combined[3][0];
|
||||
float y = sx*rdp.combined[0][1] + sy*rdp.combined[1][1] + sz*rdp.combined[2][1] + rdp.combined[3][1];
|
||||
float z = sx*rdp.combined[0][2] + sy*rdp.combined[1][2] + sz*rdp.combined[2][2] + rdp.combined[3][2];
|
||||
float w = sx*rdp.combined[0][3] + sy*rdp.combined[1][3] + sz*rdp.combined[2][3] + rdp.combined[3][3];
|
||||
v.sx = (short)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]);
|
||||
v.sy = (short)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]);
|
||||
|
||||
v.xi = (short)x;
|
||||
v.yi = (short)y;
|
||||
v.wi = (short)w;
|
||||
v.invw = Calc_invw((int)(w * 31.0));
|
||||
|
||||
if (w < 0.0f)
|
||||
v.fog = 0;
|
||||
else
|
||||
{
|
||||
int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset);
|
||||
if (fog > 255)
|
||||
fog = 255;
|
||||
v.fog = (fog >= 0) ? (wxUint8)fog : 0;
|
||||
}
|
||||
|
||||
v.cc = 0;
|
||||
if (x < -w) v.cc |= 0x10;
|
||||
if (x > w) v.cc |= 0x01;
|
||||
if (y < -w) v.cc |= 0x20;
|
||||
if (y > w) v.cc |= 0x02;
|
||||
if (w < 0.1f) v.cc |= 0x04;
|
||||
|
||||
daddr[i] = v;
|
||||
//memcpy(gfx.DMEM+dst+sizeof(zSortVDest)*i, &v, sizeof(zSortVDest));
|
||||
// FRDP("v%d x: %d, y: %d, z: %d -> sx: %d, sy: %d, w: %d, xi: %d, yi: %d, wi: %d, fog: %d\n", i, sx, sy, sz, v.sx, v.sy, v.invw, v.xi, v.yi, v.wi, v.fog);
|
||||
FRDP("v%d x: %d, y: %d, z: %d -> sx: %04lx, sy: %04lx, invw: %08lx - %f, xi: %04lx, yi: %04lx, wi: %04lx, fog: %04lx\n", i, sx, sy, sz, v.sx, v.sy, v.invw, w, v.xi, v.yi, v.wi, v.fog);
|
||||
}
|
||||
}
|
||||
|
||||
static void uc9_link_subdl ()
|
||||
{
|
||||
LRDP("uc9:link_subdl IGNORED\n");
|
||||
}
|
||||
|
||||
static void uc9_set_subdl ()
|
||||
{
|
||||
LRDP("uc9:set_subdl IGNORED\n");
|
||||
}
|
||||
|
||||
static void uc9_wait_signal ()
|
||||
{
|
||||
LRDP("uc9:wait_signal IGNORED\n");
|
||||
}
|
||||
|
||||
static void uc9_send_signal ()
|
||||
{
|
||||
LRDP("uc9:send_signal IGNORED\n");
|
||||
}
|
||||
|
||||
void uc9_movemem ()
|
||||
{
|
||||
LRDP("uc9:movemem\n");
|
||||
int idx = rdp.cmd0 & 0x0E;
|
||||
int ofs = ((rdp.cmd0>>6)&0x1ff)<<3;
|
||||
int len = (1 + ((rdp.cmd0>>15)&0x1ff))<<3;
|
||||
FRDP ("uc9:movemem ofs: %d, len: %d. ", ofs, len);
|
||||
int flag = rdp.cmd0 & 0x01;
|
||||
wxUint32 addr = segoffset(rdp.cmd1);
|
||||
switch (idx)
|
||||
{
|
||||
|
||||
case 0: //save/load
|
||||
if (flag == 0)
|
||||
{
|
||||
int dmem_addr = (idx<<3) + ofs;
|
||||
FRDP ("Load to DMEM. %08lx -> %08lx\n", addr, dmem_addr);
|
||||
memcpy(gfx.DMEM + dmem_addr, gfx.RDRAM + addr, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
int dmem_addr = (idx<<3) + ofs;
|
||||
FRDP ("Load from DMEM. %08lx -> %08lx\n", dmem_addr, addr);
|
||||
memcpy(gfx.RDRAM + addr, gfx.DMEM + dmem_addr, len);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // model matrix
|
||||
case 6: // projection matrix
|
||||
case 8: // combined matrix
|
||||
{
|
||||
DECLAREALIGN16VAR(m[4][4]);
|
||||
load_matrix(m, addr);
|
||||
switch (idx)
|
||||
{
|
||||
case 4: // model matrix
|
||||
LRDP("Modelview load\n");
|
||||
modelview_load (m);
|
||||
break;
|
||||
case 6: // projection matrix
|
||||
LRDP("Projection load\n");
|
||||
projection_load (m);
|
||||
break;
|
||||
case 8: // projection matrix
|
||||
LRDP("Combined load\n");
|
||||
rdp.update &= ~UPDATE_MULT_MAT;
|
||||
memcpy (rdp.combined, m, 64);;
|
||||
break;
|
||||
}
|
||||
#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
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
LRDP("Othermode - IGNORED\n");
|
||||
break;
|
||||
|
||||
case 12: // VIEWPORT
|
||||
{
|
||||
wxUint32 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];
|
||||
rdp.fog_multiplier = ((short*)gfx.RDRAM)[(a+3)^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.fog_offset = ((short*)gfx.RDRAM)[(a+7)^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;
|
||||
zSortRdp.view_scale[0] = (float)(scale_x*4);
|
||||
zSortRdp.view_scale[1] = (float)(scale_y*4);
|
||||
zSortRdp.view_trans[0] = (float)(trans_x*4);
|
||||
zSortRdp.view_trans[1] = (float)(trans_y*4);
|
||||
zSortRdp.scale_x = rdp.scale_x / 4.0f;
|
||||
zSortRdp.scale_y = rdp.scale_y / 4.0f;
|
||||
|
||||
rdp.update |= UPDATE_VIEWPORT;
|
||||
|
||||
rdp.mipmap_level = 0;
|
||||
rdp.cur_tile = 0;
|
||||
TILE *tmp_tile = &rdp.tiles[0];
|
||||
tmp_tile->on = 1;
|
||||
tmp_tile->org_s_scale = 0xFFFF;
|
||||
tmp_tile->org_t_scale = 0xFFFF;
|
||||
tmp_tile->s_scale = 0.031250f;
|
||||
tmp_tile->t_scale = 0.031250f;
|
||||
|
||||
rdp.geom_mode |= 0x0200;
|
||||
|
||||
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);
|
||||
FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FRDP ("** UNKNOWN %d\n", idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void uc9_setscissor()
|
||||
{
|
||||
rdp_setscissor();
|
||||
|
||||
if ((rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0]))
|
||||
{
|
||||
float w = (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) / 2.0f;
|
||||
float h = (rdp.scissor_o.lr_y - rdp.scissor_o.ul_y) / 2.0f;
|
||||
rdp.view_scale[0] = w * rdp.scale_x;
|
||||
rdp.view_scale[1] = h * rdp.scale_y;
|
||||
rdp.view_trans[0] = w * rdp.scale_x;
|
||||
rdp.view_trans[1] = h * rdp.scale_y;
|
||||
zSortRdp.view_scale[0] = w * 4.0f;
|
||||
zSortRdp.view_scale[1] = h * 4.0f;
|
||||
zSortRdp.view_trans[0] = w * 4.0f;
|
||||
zSortRdp.view_trans[1] = h * 4.0f;
|
||||
zSortRdp.scale_x = rdp.scale_x / 4.0f;
|
||||
zSortRdp.scale_y = rdp.scale_y / 4.0f;
|
||||
rdp.update |= UPDATE_VIEWPORT;
|
||||
|
||||
rdp.mipmap_level = 0;
|
||||
rdp.cur_tile = 0;
|
||||
TILE *tmp_tile = &rdp.tiles[0];
|
||||
tmp_tile->on = 1;
|
||||
tmp_tile->org_s_scale = 0xFFFF;
|
||||
tmp_tile->org_t_scale = 0xFFFF;
|
||||
tmp_tile->s_scale = 0.031250f;
|
||||
tmp_tile->t_scale = 0.031250f;
|
||||
|
||||
rdp.geom_mode |= 0x0200;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
//****************************************************************
|
||||
//
|
||||
// Glide64 - Glide Plugin for Nintendo 64 emulators
|
||||
// Project started on December 29th, 2001
|
||||
//
|
||||
// Authors:
|
||||
// Dave2001, original author, founded the project in 2001, left it in 2002
|
||||
// Gugaman, joined the project in 2002, left it in 2002
|
||||
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
|
||||
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//****************************************************************
|
||||
//
|
||||
// December 2008 Created by Gonetz (Gonetz@ngs.ru)
|
||||
//
|
||||
//****************************************************************
|
||||
|
||||
void uc9_rpdcmd ()
|
||||
{
|
||||
wxUint32 a = segoffset(rdp.cmd1) >> 2;
|
||||
FRDP ("uc9:rdpcmd addr: %08lx\n", a);
|
||||
if (a)
|
||||
{
|
||||
rdp.LLE = 1;
|
||||
wxUint32 cmd = 0;
|
||||
while(1)
|
||||
{
|
||||
rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
cmd = rdp.cmd0>>24;
|
||||
if (cmd == 0xDF)
|
||||
break;
|
||||
rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
if (cmd == 0xE4 || cmd == 0xE5)
|
||||
{
|
||||
a++;
|
||||
rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
a++;
|
||||
rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a++];
|
||||
}
|
||||
gfx_instruction[ucode_zSort][cmd] ();
|
||||
};
|
||||
rdp.LLE = 0;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Glide64 - Glide video plugin for Nintendo 64 emulators.
|
||||
* Copyright (c) 2002 Dave2001
|
||||
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
|
||||
* Copyright (c) 2012-2013 balrog, wahrhaft
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WINLNXDEFS_H
|
||||
#define WINLNXDEFS_H
|
||||
|
||||
#define wxPtrToUInt (uintptr_t)
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define _T(x) x
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int BOOL;
|
||||
typedef uint32_t wxUint32;
|
||||
typedef uint16_t wxUint16;
|
||||
typedef uint8_t wxUint8;
|
||||
typedef uint8_t BYTE;
|
||||
typedef long long LONGLONG;
|
||||
|
||||
|
||||
typedef int32_t wxInt32;
|
||||
typedef int16_t wxInt16;
|
||||
typedef int8_t wxInt8;
|
||||
|
||||
typedef uint64_t wxUint64;
|
||||
typedef int64_t wxInt64;
|
||||
|
||||
typedef unsigned char wxChar;
|
||||
typedef uintptr_t wxUIntPtr;
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
typedef union _LARGE_INTEGER
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t LowPart;
|
||||
uint32_t HighPart;
|
||||
} s;
|
||||
struct
|
||||
{
|
||||
uint32_t LowPart;
|
||||
uint32_t HighPart;
|
||||
} u;
|
||||
long long QuadPart;
|
||||
} LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
|
||||
#define WINAPI
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include "Ext_TxFilter.h"
|
||||
|
||||
extern "C"{
|
||||
|
||||
boolean txfilter_init(int maxwidth, int maxheight, int maxbpp,
|
||||
int options, int cachesize,
|
||||
wchar_t *datapath, wchar_t *cachepath, wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
|
||||
void txfilter_shutdown(void);
|
||||
|
||||
boolean txfilter(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat,
|
||||
uint64 g64crc, GHQTexInfo *info);
|
||||
|
||||
boolean txfilter_hirestex(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info);
|
||||
|
||||
uint64 txfilter_checksum(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette);
|
||||
|
||||
boolean txfilter_dmptx(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64);
|
||||
|
||||
boolean txfilter_reloadhirestex();
|
||||
|
||||
}
|
||||
|
||||
void ext_ghq_shutdown(void)
|
||||
{
|
||||
txfilter_shutdown();
|
||||
}
|
||||
|
||||
boolean ext_ghq_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize,
|
||||
wchar_t *datapath, wchar_t *cachepath, wchar_t *ident,
|
||||
dispInfoFuncExt callback)
|
||||
{
|
||||
boolean bRet = 0;
|
||||
|
||||
bRet = txfilter_init(maxwidth, maxheight, maxbpp, options, cachesize, datapath, cachepath, ident, callback);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
boolean ext_ghq_txfilter(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat,
|
||||
uint64 g64crc, GHQTexInfo *info)
|
||||
{
|
||||
boolean ret = 0;
|
||||
|
||||
ret = txfilter(src, srcwidth, srcheight, srcformat,
|
||||
g64crc, info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean ext_ghq_hirestex(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info)
|
||||
{
|
||||
boolean ret = 0;
|
||||
|
||||
ret = txfilter_hirestex(g64crc, r_crc64, palette, info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64 ext_ghq_checksum(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette)
|
||||
{
|
||||
uint64 ret = 0;
|
||||
|
||||
ret = txfilter_checksum(src, width, height, size, rowStride, palette);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean ext_ghq_dmptx(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64)
|
||||
{
|
||||
boolean ret = 0;
|
||||
|
||||
ret = txfilter_dmptx(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean ext_ghq_reloadhirestex()
|
||||
{
|
||||
boolean ret = 0;
|
||||
|
||||
ret = txfilter_reloadhirestex();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EXT_TXFILTER_H__
|
||||
#define __EXT_TXFILTER_H__
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#define TXHMODULE HMODULE
|
||||
#define DLOPEN(a) LoadLibraryW(a)
|
||||
#define DLCLOSE(a) FreeLibrary(a)
|
||||
#define DLSYM(a, b) GetProcAddress(a, b)
|
||||
#define GETCWD(a, b) GetCurrentDirectoryW(a, b)
|
||||
#define CHDIR(a) SetCurrentDirectoryW(a)
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <dlfcn.h>
|
||||
#define MAX_PATH 4095
|
||||
#define TXHMODULE void*
|
||||
#define DLOPEN(a) dlopen(a, RTLD_LAZY|RTLD_GLOBAL)
|
||||
#define DLCLOSE(a) dlclose(a)
|
||||
#define DLSYM(a, b) dlsym(a, b)
|
||||
#define GETCWD(a, b) getcwd(b, a)
|
||||
#define CHDIR(a) chdir(a)
|
||||
#endif
|
||||
|
||||
#ifdef __MSC__
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
|
||||
#define NO_OPTIONS 0x00000000
|
||||
|
||||
#define FILTER_MASK 0x000000ff
|
||||
#define NO_FILTER 0x00000000
|
||||
#define SMOOTH_FILTER_MASK 0x0000000f
|
||||
#define NO_SMOOTH_FILTER 0x00000000
|
||||
#define SMOOTH_FILTER_1 0x00000001
|
||||
#define SMOOTH_FILTER_2 0x00000002
|
||||
#define SMOOTH_FILTER_3 0x00000003
|
||||
#define SMOOTH_FILTER_4 0x00000004
|
||||
#define SHARP_FILTER_MASK 0x000000f0
|
||||
#define NO_SHARP_FILTER 0x00000000
|
||||
#define SHARP_FILTER_1 0x00000010
|
||||
#define SHARP_FILTER_2 0x00000020
|
||||
|
||||
#define ENHANCEMENT_MASK 0x00000f00
|
||||
#define NO_ENHANCEMENT 0x00000000
|
||||
#define X2_ENHANCEMENT 0x00000100
|
||||
#define X2SAI_ENHANCEMENT 0x00000200
|
||||
#define HQ2X_ENHANCEMENT 0x00000300
|
||||
#define LQ2X_ENHANCEMENT 0x00000400
|
||||
#define HQ4X_ENHANCEMENT 0x00000500
|
||||
#define HQ2XS_ENHANCEMENT 0x00000600
|
||||
#define LQ2XS_ENHANCEMENT 0x00000700
|
||||
|
||||
#define COMPRESSION_MASK 0x0000f000
|
||||
#define NO_COMPRESSION 0x00000000
|
||||
#define FXT1_COMPRESSION 0x00001000
|
||||
#define NCC_COMPRESSION 0x00002000
|
||||
#define S3TC_COMPRESSION 0x00003000
|
||||
|
||||
#define HIRESTEXTURES_MASK 0x000f0000
|
||||
#define NO_HIRESTEXTURES 0x00000000
|
||||
#define GHQ_HIRESTEXTURES 0x00010000
|
||||
#define RICE_HIRESTEXTURES 0x00020000
|
||||
#define JABO_HIRESTEXTURES 0x00030000
|
||||
|
||||
#define COMPRESS_TEX 0x00100000
|
||||
#define COMPRESS_HIRESTEX 0x00200000
|
||||
#define GZ_TEXCACHE 0x00400000
|
||||
#define GZ_HIRESTEXCACHE 0x00800000
|
||||
#define DUMP_TEXCACHE 0x01000000
|
||||
#define DUMP_HIRESTEXCACHE 0x02000000
|
||||
#define TILE_HIRESTEX 0x04000000
|
||||
#define UNDEFINED_0 0x08000000
|
||||
#define FORCE16BPP_HIRESTEX 0x10000000
|
||||
#define FORCE16BPP_TEX 0x20000000
|
||||
#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */
|
||||
#define DUMP_TEX 0x80000000
|
||||
|
||||
#ifndef __GLIDE_H__ /* GLIDE3 */
|
||||
/* from 3Dfx Interactive Inc. glide.h */
|
||||
#define GR_TEXFMT_ALPHA_8 0x2
|
||||
#define GR_TEXFMT_INTENSITY_8 0x3
|
||||
|
||||
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
|
||||
#define GR_TEXFMT_P_8 0x5
|
||||
|
||||
#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
|
||||
|
||||
/* from 3Dfx Interactive Inc. g3ext.h */
|
||||
#define GR_TEXFMT_ARGB_CMP_FXT1 0x11
|
||||
|
||||
#define GR_TEXFMT_ARGB_8888 0x12
|
||||
|
||||
#define GR_TEXFMT_ARGB_CMP_DXT1 0x16
|
||||
#define GR_TEXFMT_ARGB_CMP_DXT3 0x18
|
||||
#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A
|
||||
#endif /* GLIDE3 */
|
||||
|
||||
struct GHQTexInfo {
|
||||
|
||||
unsigned char *data;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int smallLodLog2;
|
||||
int largeLodLog2;
|
||||
int aspectRatioLog2;
|
||||
|
||||
int tiles;
|
||||
int untiled_width;
|
||||
int untiled_height;
|
||||
|
||||
unsigned short format;
|
||||
|
||||
unsigned char is_hires_tex;
|
||||
};
|
||||
|
||||
/* Callback to display hires texture info.
|
||||
* Gonetz <gonetz(at)ngs.ru>
|
||||
*
|
||||
* void DispInfo(const char *format, ...)
|
||||
* {
|
||||
* va_list args;
|
||||
* char buf[INFO_BUF];
|
||||
*
|
||||
* va_start(args, format);
|
||||
* vsprintf(buf, format, args);
|
||||
* va_end(args);
|
||||
*
|
||||
* printf(buf);
|
||||
* }
|
||||
*/
|
||||
#define INFO_BUF 4095
|
||||
typedef void (*dispInfoFuncExt)(const wchar_t *format, ...);
|
||||
|
||||
#ifndef TXFILTER_DLL
|
||||
boolean ext_ghq_init(int maxwidth, /* maximum texture width supported by hardware */
|
||||
int maxheight,/* maximum texture height supported by hardware */
|
||||
int maxbpp, /* maximum texture bpp supported by hardware */
|
||||
int options, /* options */
|
||||
int cachesize,/* cache textures to system memory */
|
||||
wchar_t *datapath, /* user data directory. must be smaller than MAX_PATH */
|
||||
wchar_t *cachepath, /* user cache directory. must be smaller than MAX_PATH */
|
||||
wchar_t *ident, /* name of ROM. must be no longer than 64 in character. */
|
||||
dispInfoFuncExt callback /* callback function to display info */
|
||||
);
|
||||
|
||||
void ext_ghq_shutdown(void);
|
||||
|
||||
boolean ext_ghq_txfilter(unsigned char *src, /* input texture */
|
||||
int srcwidth, /* width of input texture */
|
||||
int srcheight, /* height of input texture */
|
||||
unsigned short srcformat, /* format of input texture */
|
||||
uint64 g64crc, /* glide64 crc */
|
||||
GHQTexInfo *info /* output */
|
||||
);
|
||||
|
||||
boolean ext_ghq_hirestex(uint64 g64crc, /* glide64 crc */
|
||||
uint64 r_crc64, /* checksum hi:palette low:texture */
|
||||
unsigned short *palette, /* palette for CI textures */
|
||||
GHQTexInfo *info /* output */
|
||||
);
|
||||
|
||||
uint64 ext_ghq_checksum(unsigned char *src, /* input texture */
|
||||
int width, /* width of texture */
|
||||
int height, /* height of texture */
|
||||
int size, /* type of texture pixel */
|
||||
int rowStride, /* row stride in bytes */
|
||||
unsigned char *palette /* palette */
|
||||
);
|
||||
|
||||
boolean ext_ghq_dmptx(unsigned char *src, /* input texture (must be in 3Dfx Glide format) */
|
||||
int width, /* width of texture */
|
||||
int height, /* height of texture */
|
||||
int rowStridePixel, /* row stride of input texture in pixels */
|
||||
unsigned short gfmt, /* glide format of input texture */
|
||||
unsigned short n64fmt,/* N64 format hi:format low:size */
|
||||
uint64 r_crc64 /* checksum hi:palette low:texture */
|
||||
);
|
||||
|
||||
boolean ext_ghq_reloadhirestex();
|
||||
#endif /* TXFILTER_DLL */
|
||||
|
||||
#endif /* __EXT_TXFILTER_H__ */
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* GlideHQ (Texture enhancer library for Glide64)
|
||||
* Version: 1.5
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii aka KoolSmoky All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
About:
|
||||
This is a realtime texture enhancer library with hi-resolution texture
|
||||
pack support for Glide64 (http://glide64.emuxhaven.net). Traditional and
|
||||
non-traditional techniques have been used to achieve speed and high image
|
||||
quality even on a 9 year old 3Dfx Voodoo2.
|
||||
|
||||
Although the 3Dfx Glide3x texture format naming conventions are used, the
|
||||
library can be expanded for generic use.
|
||||
|
||||
Supported:
|
||||
OS: 32bit Linux and MS Windows
|
||||
Enhancers: Hq4x, Hq2x, Hq2xS, Lq2x, Lq2xS, Super2xSai, x2
|
||||
Filters: Smooth (1,2,3,4), Sharp (1,2)
|
||||
Compressors: FXT1, S3TC
|
||||
Input formats: GR_TEXFMT_ALPHA_8,
|
||||
GR_TEXFMT_RGB_565,
|
||||
GR_TEXFMT_ARGB_1555,
|
||||
GR_TEXFMT_ARGB_4444,
|
||||
GR_TEXFMT_ARGB_8888,
|
||||
GR_TEXFMT_ALPHA_INTENSITY_44,
|
||||
GR_TEXFMT_ALPHA_INTENSITY_88
|
||||
Output formats: Same as input unless compression or hires packs are used.
|
||||
Hires texture packs: Rice format (Jabo and GlideHQ format coming later)
|
||||
|
||||
Acknowledgments:
|
||||
I hope you enjoy GlideHQ (texture enhancer library for Glide64). Greatest
|
||||
thanks to Gonetz for making this happen in his busy time. We've rushed
|
||||
everything to share the eye-candy with all of you N64 emulation fans. I
|
||||
would also like to thank a great friend of mine, Daniel Borca for providing
|
||||
the texture compression code, Maxim Stepin (hq2x 4x), and Derek Liauw Kie Fa
|
||||
(2xSaI) for the filtering engines, Rice for his N64 graphics plugin source
|
||||
code, and Mudlord for the hq2xS lq2xS code. GlideHQ also uses the boost C++
|
||||
libraries, zlib general purpose compression library, and the Portable Network
|
||||
Graphics library. Thanks to all the developers for making them available. And
|
||||
special thanks to the Glide64 beta testing crew. Without their feedbacks
|
||||
this library would not have seen daylight. Thank you all.
|
||||
|
||||
The source code for GlideHQ is released in hopes that it will be improved.
|
||||
I know the coding is not on par after so much late night caffeine boosts.
|
||||
If you have suggestions or modifications, please feel free to post them on
|
||||
the Glide64 forum at emuxhaven.
|
||||
|
||||
Porting the library to other platforms should not be so hard. The coding is
|
||||
done with cross platform compatibility in mind and will build with GCC and
|
||||
GNU make. Currently supported are 32bit Linux and MS Windows.
|
||||
|
||||
If you are looking for driver updates for your 3Dfx Interactive Inc. gfx
|
||||
card, grab them from the forums at http://www.3dfxzone.it/enboard/
|
||||
Unbelievable as it seems, drivers are still being updated after 6 years
|
||||
from 3Dfx's demise.
|
||||
|
||||
I know N64 rules, anyone up for PSX? :))
|
||||
|
||||
-KoolSmoky
|
||||
|
||||
References:
|
||||
[1] R.W. Floyd & L. Steinberg, An adaptive algorithm for spatial grey scale,
|
||||
Proceedings of the Society of Information Display 17, pp75-77, 1976
|
||||
[2] Ken Turkowski, Filters for Common Resampling Tasks, Apple Computer 1990
|
||||
http://www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf
|
||||
[3] Don P. Mitchell and Arun N. Netravali, Reconstruction Filters in Computer
|
||||
Graphics, SIGGRAPH '88, Proceedings of the 15th annual conference on
|
||||
Computer graphics and interactive techniques, pp221-228, 1988
|
||||
[4] J. F. Kaiser and W. A. Reed, Data smoothing using low-pass digital
|
||||
filters, Rev. Sci. instrum. 48 (11), pp1447-1457, 1977
|
||||
[5] Maxim Stepin, hq4x Magnification Filter, http://www.hiend3d.com/hq4x.html
|
||||
[6] Derek Liauw Kie Fa, 2xSaI, http://elektron.its.tudelft.nl/~dalikifa
|
||||
[7] Dirk Stevens, Eagle engine http://www.retrofx.com/rfxtech.html
|
||||
[8] 3DFX_texture_compression_FXT1 and EXT_texture_compression_s3tc extension
|
||||
specs from the OpenGL Extension Registry. http://oss.sgi.com/projects/
|
||||
ogl-sample/registry/
|
|
@ -0,0 +1,702 @@
|
|||
/*
|
||||
Copyright (C) 2003 Rice1964
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You 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.
|
||||
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
|
||||
* Modified for the Texture Filtering library
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "TextureFilters.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* 2X filters */
|
||||
/************************************************************************/
|
||||
|
||||
#define DWORD_MAKE(r, g, b, a) ((uint32) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)))
|
||||
#define WORD_MAKE(r, g, b, a) ((uint16) (((a) << 12) | ((r) << 8) | ((g) << 4) | (b)))
|
||||
|
||||
// Basic 2x R8G8B8A8 filter with interpolation
|
||||
|
||||
void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
|
||||
{
|
||||
uint32 *pDst1, *pDst2;
|
||||
uint32 *pSrc, *pSrc2;
|
||||
uint32 nWidth = width;
|
||||
uint32 nHeight = height;
|
||||
|
||||
uint32 b1;
|
||||
uint32 g1;
|
||||
uint32 r1;
|
||||
uint32 a1;
|
||||
uint32 b2;
|
||||
uint32 g2;
|
||||
uint32 r2;
|
||||
uint32 a2;
|
||||
uint32 b3;
|
||||
uint32 g3;
|
||||
uint32 r3;
|
||||
uint32 a3;
|
||||
uint32 b4;
|
||||
uint32 g4;
|
||||
uint32 r4;
|
||||
uint32 a4;
|
||||
|
||||
uint32 xSrc;
|
||||
uint32 ySrc;
|
||||
|
||||
for (ySrc = 0; ySrc < nHeight; ySrc++)
|
||||
{
|
||||
pSrc = (uint32*)(((uint8*)srcPtr)+ySrc*srcPitch);
|
||||
pSrc2 = (uint32*)(((uint8*)srcPtr)+(ySrc+1)*srcPitch);
|
||||
pDst1 = (uint32*)(((uint8*)dstPtr)+(ySrc*2)*dstPitch);
|
||||
pDst2 = (uint32*)(((uint8*)dstPtr)+(ySrc*2+1)*dstPitch);
|
||||
|
||||
for (xSrc = 0; xSrc < nWidth; xSrc++)
|
||||
{
|
||||
b1 = (pSrc[xSrc]>>0)&0xFF;
|
||||
g1 = (pSrc[xSrc]>>8)&0xFF;
|
||||
r1 = (pSrc[xSrc]>>16)&0xFF;
|
||||
a1 = (pSrc[xSrc]>>24)&0xFF;
|
||||
|
||||
// Pixel 1
|
||||
pDst1[xSrc*2] = pSrc[xSrc];
|
||||
|
||||
// Pixel 2
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
b2 = (pSrc[xSrc+1]>>0)&0xFF;
|
||||
g2 = (pSrc[xSrc+1]>>8)&0xFF;
|
||||
r2 = (pSrc[xSrc+1]>>16)&0xFF;
|
||||
a2 = (pSrc[xSrc+1]>>24)&0xFF;
|
||||
pDst1[xSrc*2+1] = DWORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||
}
|
||||
else
|
||||
pDst1[xSrc*2+1] = pSrc[xSrc];
|
||||
|
||||
// Pixel 3
|
||||
if( ySrc<nHeight-1 )
|
||||
{
|
||||
b3 = (pSrc2[xSrc]>>0)&0xFF;
|
||||
g3 = (pSrc2[xSrc]>>8)&0xFF;
|
||||
r3 = (pSrc2[xSrc]>>16)&0xFF;
|
||||
a3 = (pSrc2[xSrc]>>24)&0xFF;
|
||||
pDst2[xSrc*2] = DWORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
b4 = (pSrc2[xSrc+1]>>0)&0xFF;
|
||||
g4 = (pSrc2[xSrc+1]>>8)&0xFF;
|
||||
r4 = (pSrc2[xSrc+1]>>16)&0xFF;
|
||||
a4 = (pSrc2[xSrc+1]>>24)&0xFF;
|
||||
// Pixel 4
|
||||
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r2+r3+r4)/4, (g1+g2+g3+g4)/4, (b1+b2+b3+b4)/4, (a1+a2+a3+a4)/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pixel 4
|
||||
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pixel 3
|
||||
pDst2[xSrc*2] = pSrc[xSrc];
|
||||
// Pixel 4
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
pDst2[xSrc*2+1] = DWORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
pDst2[xSrc*2+1] = pSrc[xSrc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
// Basic 2x R4G4B4A4 filter with interpolation
|
||||
void Texture2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
|
||||
{
|
||||
uint16 *pDst1, *pDst2;
|
||||
uint16 *pSrc, *pSrc2;
|
||||
uint32 nWidth = width;
|
||||
uint32 nHeight = height;
|
||||
|
||||
uint16 b1;
|
||||
uint16 g1;
|
||||
uint16 r1;
|
||||
uint16 a1;
|
||||
uint16 b2;
|
||||
uint16 g2;
|
||||
uint16 r2;
|
||||
uint16 a2;
|
||||
uint16 b3;
|
||||
uint16 g3;
|
||||
uint16 r3;
|
||||
uint16 a3;
|
||||
uint16 b4;
|
||||
uint16 g4;
|
||||
uint16 r4;
|
||||
uint16 a4;
|
||||
|
||||
uint16 xSrc;
|
||||
uint16 ySrc;
|
||||
|
||||
for (ySrc = 0; ySrc < nHeight; ySrc++)
|
||||
{
|
||||
pSrc = (uint16*)(((uint8*)srcPtr)+ySrc*srcPitch);
|
||||
pSrc2 = (uint16*)(((uint8*)srcPtr)+(ySrc+1)*srcPitch);
|
||||
pDst1 = (uint16*)(((uint8*)dstPtr)+(ySrc*2)*dstPitch);
|
||||
pDst2 = (uint16*)(((uint8*)dstPtr)+(ySrc*2+1)*dstPitch);
|
||||
|
||||
for (xSrc = 0; xSrc < nWidth; xSrc++)
|
||||
{
|
||||
b1 = (pSrc[xSrc]>> 0)&0xF;
|
||||
g1 = (pSrc[xSrc]>> 4)&0xF;
|
||||
r1 = (pSrc[xSrc]>> 8)&0xF;
|
||||
a1 = (pSrc[xSrc]>>12)&0xF;
|
||||
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
b2 = (pSrc[xSrc+1]>> 0)&0xF;
|
||||
g2 = (pSrc[xSrc+1]>> 4)&0xF;
|
||||
r2 = (pSrc[xSrc+1]>> 8)&0xF;
|
||||
a2 = (pSrc[xSrc+1]>>12)&0xF;
|
||||
}
|
||||
|
||||
if( ySrc<nHeight-1 )
|
||||
{
|
||||
b3 = (pSrc2[xSrc]>> 0)&0xF;
|
||||
g3 = (pSrc2[xSrc]>> 4)&0xF;
|
||||
r3 = (pSrc2[xSrc]>> 8)&0xF;
|
||||
a3 = (pSrc2[xSrc]>>12)&0xF;
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
b4 = (pSrc2[xSrc+1]>> 0)&0xF;
|
||||
g4 = (pSrc2[xSrc+1]>> 4)&0xF;
|
||||
r4 = (pSrc2[xSrc+1]>> 8)&0xF;
|
||||
a4 = (pSrc2[xSrc+1]>>12)&0xF;
|
||||
}
|
||||
}
|
||||
|
||||
// Pixel 1
|
||||
pDst1[xSrc*2] = pSrc[xSrc];
|
||||
|
||||
// Pixel 2
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
pDst1[xSrc*2+1] = WORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||
}
|
||||
else
|
||||
pDst1[xSrc*2+1] = pSrc[xSrc];
|
||||
|
||||
|
||||
// Pixel 3
|
||||
if( ySrc<nHeight-1 )
|
||||
{
|
||||
pDst2[xSrc*2] = WORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||
}
|
||||
else
|
||||
pDst2[xSrc*2] = pSrc[xSrc];
|
||||
|
||||
// Pixel 4
|
||||
if( xSrc<nWidth-1 )
|
||||
{
|
||||
if( ySrc<nHeight-1 )
|
||||
{
|
||||
pDst2[xSrc*2+1] = WORD_MAKE((r1+r2+r3+r4)/4, (g1+g2+g3+g4)/4, (b1+b2+b3+b4)/4, (a1+a2+a3+a4)/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pDst2[xSrc*2+1] = WORD_MAKE((r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ySrc<nHeight-1 )
|
||||
{
|
||||
pDst2[xSrc*2+1] = WORD_MAKE((r1+r3)/2, (g1+g3)/2, (b1+b3)/2, (a1+a3)/2);
|
||||
}
|
||||
else
|
||||
pDst2[xSrc*2+1] = pSrc[xSrc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
/*
|
||||
* Sharp filters
|
||||
* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
*/
|
||||
void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter)
|
||||
{
|
||||
// NOTE: for now we get away with copying the boundaries
|
||||
// filter the boundaries if we face problems
|
||||
|
||||
uint32 mul1, mul2, mul3, shift4;
|
||||
|
||||
uint32 x,y,z;
|
||||
uint32 *_src1, *_src2, *_src3, *_dest;
|
||||
uint32 val[4];
|
||||
uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
|
||||
switch( filter )
|
||||
{
|
||||
case SHARP_FILTER_2:
|
||||
mul1=1;
|
||||
mul2=8;
|
||||
mul3=12;
|
||||
shift4=2;
|
||||
break;
|
||||
case SHARP_FILTER_1:
|
||||
default:
|
||||
mul1=1;
|
||||
mul2=8;
|
||||
mul3=16;
|
||||
shift4=3;
|
||||
break;
|
||||
}
|
||||
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 2));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for (y = 1; y < srcheight-1; y++) {
|
||||
// copy the first pixel
|
||||
_dest[0] = *_src2;
|
||||
// filter 2nd pixel to 1 pixel before last
|
||||
for (x = 1; x < srcwidth-1; x++) {
|
||||
for (z=0; z<4; z++) {
|
||||
t1 = *((uint8*)(_src1+x-1)+z);
|
||||
t2 = *((uint8*)(_src1+x )+z);
|
||||
t3 = *((uint8*)(_src1+x+1)+z);
|
||||
t4 = *((uint8*)(_src2+x-1)+z);
|
||||
t5 = *((uint8*)(_src2+x )+z);
|
||||
t6 = *((uint8*)(_src2+x+1)+z);
|
||||
t7 = *((uint8*)(_src3+x-1)+z);
|
||||
t8 = *((uint8*)(_src3+x )+z);
|
||||
t9 = *((uint8*)(_src3+x+1)+z);
|
||||
|
||||
if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) {
|
||||
val[z]= ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4;
|
||||
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||
} else {
|
||||
val[z] = t5;
|
||||
}
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||
}
|
||||
// copy the ending pixel
|
||||
_dest[srcwidth-1] = *(_src3 - 1);
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 2));
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter)
|
||||
{
|
||||
// NOTE: for now we get away with copying the boundaries
|
||||
// filter the boundaries if we face problems
|
||||
|
||||
uint16 mul1, mul2, mul3, shift4;
|
||||
|
||||
uint32 x,y,z;
|
||||
uint16 *_src1, *_src2, *_src3, *_dest;
|
||||
uint16 val[4];
|
||||
uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
|
||||
switch( filter ) {
|
||||
case SHARP_FILTER_2:
|
||||
mul1=1;
|
||||
mul2=8;
|
||||
mul3=12;
|
||||
shift4=2;
|
||||
break;
|
||||
case SHARP_FILTER_1:
|
||||
default:
|
||||
mul1=1;
|
||||
mul2=8;
|
||||
mul3=16;
|
||||
shift4=3;
|
||||
break;
|
||||
}
|
||||
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 1));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for( y = 1; y < srcheight - 1; y++) {
|
||||
// copy the first pixel
|
||||
_dest[0] = *_src2;
|
||||
// filter 2nd pixel to 1 pixel before last
|
||||
for( x = 1; x < srcwidth - 1; x++) {
|
||||
for( z = 0; z < 4; z++ ) {
|
||||
/* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
* Read the entire 16bit pixel and then extract the A,R,G,B components.
|
||||
*/
|
||||
uint32 shift = z << 2;
|
||||
t1 = ((*((uint16*)(_src1+x-1))) >> shift) & 0xF;
|
||||
t2 = ((*((uint16*)(_src1+x ))) >> shift) & 0xF;
|
||||
t3 = ((*((uint16*)(_src1+x+1))) >> shift) & 0xF;
|
||||
t4 = ((*((uint16*)(_src2+x-1))) >> shift) & 0xF;
|
||||
t5 = ((*((uint16*)(_src2+x ))) >> shift) & 0xF;
|
||||
t6 = ((*((uint16*)(_src2+x+1))) >> shift) & 0xF;
|
||||
t7 = ((*((uint16*)(_src3+x-1))) >> shift) & 0xF;
|
||||
t8 = ((*((uint16*)(_src3+x ))) >> shift) & 0xF;
|
||||
t9 = ((*((uint16*)(_src3+x+1))) >> shift) & 0xF;
|
||||
|
||||
if( (t5*mul2) > (t1+t3+t7+t9+t2+t4+t6+t8)*mul1 ) {
|
||||
val[z] = ((t5*mul3) - (t1+t3+t7+t9+t2+t4+t6+t8)*mul1)>>shift4;
|
||||
if (val[z] > 0xF) val[z] = 0xF;
|
||||
} else {
|
||||
val[z] = t5;
|
||||
}
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||
}
|
||||
// copy the ending pixel
|
||||
_dest[srcwidth-1] = *(_src3 - 1);
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 1));
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
/*
|
||||
* Smooth filters
|
||||
* Hiroshi Morii <koolsmoky@users.sourceforge.net>
|
||||
*/
|
||||
void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter)
|
||||
{
|
||||
// NOTE: for now we get away with copying the boundaries
|
||||
// filter the boundaries if we face problems
|
||||
|
||||
uint32 mul1, mul2, mul3, shift4;
|
||||
|
||||
uint32 x,y,z;
|
||||
uint32 *_src1, *_src2, *_src3, *_dest;
|
||||
uint32 val[4];
|
||||
uint32 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
|
||||
switch( filter ) {
|
||||
case SMOOTH_FILTER_4:
|
||||
mul1=1;
|
||||
mul2=2;
|
||||
mul3=4;
|
||||
shift4=4;
|
||||
break;
|
||||
case SMOOTH_FILTER_3:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=8;
|
||||
shift4=4;
|
||||
break;
|
||||
case SMOOTH_FILTER_2:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=2;
|
||||
shift4=2;
|
||||
break;
|
||||
case SMOOTH_FILTER_1:
|
||||
default:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=6;
|
||||
shift4=3;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (filter) {
|
||||
case SMOOTH_FILTER_3:
|
||||
case SMOOTH_FILTER_4:
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 2));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for (y = 1; y < srcheight - 1; y++){
|
||||
// copy the first pixel
|
||||
_dest[0] = _src2[0];
|
||||
// filter 2nd pixel to 1 pixel before last
|
||||
for (x = 1; x < srcwidth - 1; x++) {
|
||||
for (z = 0; z < 4; z++ ) {
|
||||
t1 = *((uint8*)(_src1+x-1)+z);
|
||||
t2 = *((uint8*)(_src1+x )+z);
|
||||
t3 = *((uint8*)(_src1+x+1)+z);
|
||||
t4 = *((uint8*)(_src2+x-1)+z);
|
||||
t5 = *((uint8*)(_src2+x )+z);
|
||||
t6 = *((uint8*)(_src2+x+1)+z);
|
||||
t7 = *((uint8*)(_src3+x-1)+z);
|
||||
t8 = *((uint8*)(_src3+x )+z);
|
||||
t9 = *((uint8*)(_src3+x+1)+z);
|
||||
/* the component value must not overflow 0xFF */
|
||||
val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4;
|
||||
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||
}
|
||||
// copy the ending pixel
|
||||
_dest[srcwidth-1] = *(_src3 - 1);
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 2));
|
||||
break;
|
||||
case SMOOTH_FILTER_1:
|
||||
case SMOOTH_FILTER_2:
|
||||
default:
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 2));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for (y = 1; y < srcheight - 1; y++) {
|
||||
// filter 1st pixel to the last
|
||||
if (y & 1) {
|
||||
for( x = 0; x < srcwidth; x++) {
|
||||
for( z = 0; z < 4; z++ ) {
|
||||
t2 = *((uint8*)(_src1+x )+z);
|
||||
t5 = *((uint8*)(_src2+x )+z);
|
||||
t8 = *((uint8*)(_src3+x )+z);
|
||||
/* the component value must not overflow 0xFF */
|
||||
val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4;
|
||||
if (val[z] > 0xFF) val[z] = 0xFF;
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<8)|(val[2]<<16)|(val[3]<<24);
|
||||
}
|
||||
} else {
|
||||
memcpy(_dest, _src2, (srcwidth << 2));
|
||||
}
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter)
|
||||
{
|
||||
// NOTE: for now we get away with copying the boundaries
|
||||
// filter the boundaries if we face problems
|
||||
|
||||
uint16 mul1, mul2, mul3, shift4;
|
||||
|
||||
uint32 x,y,z;
|
||||
uint16 *_src1, *_src2, *_src3, *_dest;
|
||||
uint16 val[4];
|
||||
uint16 t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
|
||||
switch( filter ) {
|
||||
case SMOOTH_FILTER_4:
|
||||
mul1=1;
|
||||
mul2=2;
|
||||
mul3=4;
|
||||
shift4=4;
|
||||
break;
|
||||
case SMOOTH_FILTER_3:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=8;
|
||||
shift4=4;
|
||||
break;
|
||||
case SMOOTH_FILTER_2:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=2;
|
||||
shift4=2;
|
||||
break;
|
||||
case SMOOTH_FILTER_1:
|
||||
default:
|
||||
mul1=1;
|
||||
mul2=1;
|
||||
mul3=6;
|
||||
shift4=3;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (filter) {
|
||||
case SMOOTH_FILTER_3:
|
||||
case SMOOTH_FILTER_4:
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 1));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for (y = 1; y < srcheight - 1; y++) {
|
||||
// copy the first pixel
|
||||
_dest[0] = *_src2;
|
||||
// filter 2nd pixel to 1 pixel before last
|
||||
for (x = 1; x < srcwidth - 1; x++) {
|
||||
for (z = 0; z < 4; z++ ) {
|
||||
/* Read the entire 16bit pixel and then extract the A,R,G,B components. */
|
||||
uint32 shift = z << 2;
|
||||
t1 = ((*(uint16*)(_src1+x-1)) >> shift) & 0xF;
|
||||
t2 = ((*(uint16*)(_src1+x )) >> shift) & 0xF;
|
||||
t3 = ((*(uint16*)(_src1+x+1)) >> shift) & 0xF;
|
||||
t4 = ((*(uint16*)(_src2+x-1)) >> shift) & 0xF;
|
||||
t5 = ((*(uint16*)(_src2+x )) >> shift) & 0xF;
|
||||
t6 = ((*(uint16*)(_src2+x+1)) >> shift) & 0xF;
|
||||
t7 = ((*(uint16*)(_src3+x-1)) >> shift) & 0xF;
|
||||
t8 = ((*(uint16*)(_src3+x )) >> shift) & 0xF;
|
||||
t9 = ((*(uint16*)(_src3+x+1)) >> shift) & 0xF;
|
||||
/* the component value must not overflow 0xF */
|
||||
val[z] = ((t1+t3+t7+t9)*mul1+((t2+t4+t6+t8)*mul2)+(t5*mul3))>>shift4;
|
||||
if (val[z] > 0xF) val[z] = 0xF;
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||
}
|
||||
// copy the ending pixel
|
||||
_dest[srcwidth-1] = *(_src3 - 1);
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 1));
|
||||
break;
|
||||
case SMOOTH_FILTER_1:
|
||||
case SMOOTH_FILTER_2:
|
||||
default:
|
||||
// setup rows
|
||||
_src1 = src;
|
||||
_src2 = _src1 + srcwidth;
|
||||
_src3 = _src2 + srcwidth;
|
||||
_dest = dest;
|
||||
// copy the first row
|
||||
memcpy(_dest, _src1, (srcwidth << 1));
|
||||
_dest += srcwidth;
|
||||
// filter 2nd row to 1 row before the last
|
||||
for( y = 1; y < srcheight - 1; y++) {
|
||||
if (y & 1) {
|
||||
for( x = 0; x < srcwidth; x++) {
|
||||
for( z = 0; z < 4; z++ ) {
|
||||
/* Read the entire 16bit pixel and then extract the A,R,G,B components. */
|
||||
uint32 shift = z << 2;
|
||||
t2 = ((*(uint16*)(_src1+x)) >> shift) & 0xF;
|
||||
t5 = ((*(uint16*)(_src2+x)) >> shift) & 0xF;
|
||||
t8 = ((*(uint16*)(_src3+x)) >> shift) & 0xF;
|
||||
/* the component value must not overflow 0xF */
|
||||
val[z] = ((t2+t8)*mul2+(t5*mul3))>>shift4;
|
||||
if (val[z] > 0xF) val[z] = 0xF;
|
||||
}
|
||||
_dest[x] = val[0]|(val[1]<<4)|(val[2]<<8)|(val[3]<<12);
|
||||
}
|
||||
} else {
|
||||
memcpy(_dest, _src2, (srcwidth << 1));
|
||||
}
|
||||
// next row
|
||||
_src1 += srcwidth;
|
||||
_src2 += srcwidth;
|
||||
_src3 += srcwidth;
|
||||
_dest += srcwidth;
|
||||
}
|
||||
// copy the last row
|
||||
memcpy(_dest, _src2, (srcwidth << 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter) {
|
||||
switch (filter & ENHANCEMENT_MASK) {
|
||||
case HQ4X_ENHANCEMENT:
|
||||
hq4x_8888((uint8*)src, (uint8*)dest, srcwidth, srcheight, srcwidth, (srcwidth << 4));
|
||||
return;
|
||||
case HQ2X_ENHANCEMENT:
|
||||
hq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||
return;
|
||||
case HQ2XS_ENHANCEMENT:
|
||||
hq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||
return;
|
||||
case LQ2X_ENHANCEMENT:
|
||||
lq2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||
return;
|
||||
case LQ2XS_ENHANCEMENT:
|
||||
lq2xS_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||
return;
|
||||
case X2SAI_ENHANCEMENT:
|
||||
Super2xSaI_8888((uint32*)src, (uint32*)dest, srcwidth, srcheight, srcwidth);
|
||||
return;
|
||||
case X2_ENHANCEMENT:
|
||||
Texture2x_32((uint8*)src, (srcwidth << 2), (uint8*)dest, (srcwidth << 3), srcwidth, srcheight);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (filter & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) {
|
||||
case SMOOTH_FILTER_1:
|
||||
case SMOOTH_FILTER_2:
|
||||
case SMOOTH_FILTER_3:
|
||||
case SMOOTH_FILTER_4:
|
||||
SmoothFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SMOOTH_FILTER_MASK));
|
||||
return;
|
||||
case SHARP_FILTER_1:
|
||||
case SHARP_FILTER_2:
|
||||
SharpFilter_8888((uint32*)src, srcwidth, srcheight, (uint32*)dest, (filter & SHARP_FILTER_MASK));
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __TEXTUREFILTERS_H__
|
||||
#define __TEXTUREFILTERS_H__
|
||||
|
||||
/* 16bpp filters are somewhat buggy and output image is not clean.
|
||||
* Since there's not much time, we'll just convert them to ARGB8888
|
||||
* and use 32bpp filters until fixed.
|
||||
* (1:enable hack, 0:disable hack) */
|
||||
#define _16BPP_HACK 1
|
||||
|
||||
#include "TxInternal.h"
|
||||
|
||||
/* enhancers */
|
||||
void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||
|
||||
void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||
|
||||
void Texture2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
/* filters */
|
||||
void SharpFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||
|
||||
void SmoothFilter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||
|
||||
/* helper */
|
||||
void filter_8888(uint32 *src, uint32 srcwidth, uint32 srcheight, uint32 *dest, uint32 filter);
|
||||
|
||||
#if !_16BPP_HACK
|
||||
void hq4x_init(void);
|
||||
void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||
void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||
void hq4x_565 (unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL);
|
||||
|
||||
void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
void hq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||
void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||
void Super2xSaI_565 (uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||
void Super2xSaI_8 (uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch);
|
||||
|
||||
void Texture2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height);
|
||||
|
||||
void SharpFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter);
|
||||
|
||||
void SmoothFilter_4444(uint16 *src, uint32 srcwidth, uint32 srcheight, uint16 *dest, uint32 filter);
|
||||
#endif
|
||||
|
||||
#endif /* __TEXTUREFILTERS_H__ */
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */
|
||||
|
||||
#include "TextureFilters.h"
|
||||
|
||||
#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
|
||||
|
||||
void Super2xSaI_8888(uint32 *srcPtr, uint32 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
#define SAI_INTERPOLATE_8888(A, B) ((A & 0xFEFEFEFE) >> 1) + ((B & 0xFEFEFEFE) >> 1) + (A & B & 0x01010101)
|
||||
#define SAI_Q_INTERPOLATE_8888(A, B, C, D) ((A & 0xFCFCFCFC) >> 2) + ((B & 0xFCFCFCFC) >> 2) + ((C & 0xFCFCFCFC) >> 2) + ((D & 0xFCFCFCFC) >> 2) \
|
||||
+ ((((A & 0x03030303) + (B & 0x03030303) + (C & 0x03030303) + (D & 0x03030303)) >> 2) & 0x03030303)
|
||||
|
||||
#define SAI_INTERPOLATE SAI_INTERPOLATE_8888
|
||||
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8888
|
||||
|
||||
uint32 destWidth = width << 1;
|
||||
|
||||
uint32 color4, color5, color6;
|
||||
uint32 color1, color2, color3;
|
||||
uint32 colorA0, colorA1, colorA2, colorA3;
|
||||
uint32 colorB0, colorB1, colorB2, colorB3;
|
||||
uint32 colorS1, colorS2;
|
||||
uint32 product1a, product1b, product2a, product2b;
|
||||
|
||||
#include "TextureFilters_2xsai.h"
|
||||
|
||||
#undef SAI_INTERPOLATE
|
||||
#undef SAI_Q_INTERPOLATE
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
void Super2xSaI_4444(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
#define SAI_INTERPOLATE_4444(A, B) ((A & 0xEEEE) >> 1) + ((B & 0xEEEE) >> 1) + (A & B & 0x1111)
|
||||
#define SAI_Q_INTERPOLATE_4444(A, B, C, D) ((A & 0xCCCC) >> 2) + ((B & 0xCCCC) >> 2) + ((C & 0xCCCC) >> 2) + ((D & 0xCCCC) >> 2) \
|
||||
+ ((((A & 0x3333) + (B & 0x3333) + (C & 0x3333) + (D & 0x3333)) >> 2) & 0x3333)
|
||||
|
||||
#define SAI_INTERPOLATE SAI_INTERPOLATE_4444
|
||||
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_4444
|
||||
|
||||
uint32 destWidth = width << 1;
|
||||
uint32 destHeight = height << 1;
|
||||
|
||||
uint16 color4, color5, color6;
|
||||
uint16 color1, color2, color3;
|
||||
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||
uint16 colorS1, colorS2;
|
||||
uint16 product1a, product1b, product2a, product2b;
|
||||
|
||||
#include "TextureFilters_2xsai.h"
|
||||
|
||||
#undef SAI_INTERPOLATE
|
||||
#undef SAI_Q_INTERPOLATE
|
||||
}
|
||||
|
||||
void Super2xSaI_1555(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
#define SAI_INTERPOLATE_1555(A, B) ((A & 0x7BDE) >> 1) + ((B & 0x7BDE) >> 1) + (A & B & 0x8421)
|
||||
#define SAI_Q_INTERPOLATE_1555(A, B, C, D) ((A & 0x739C) >> 2) + ((B & 0x739C) >> 2) + ((C & 0x739C) >> 2) + ((D & 0x739C) >> 2) \
|
||||
+ ((((A & 0x8C63) + (B & 0x8C63) + (C & 0x8C63) + (D & 0x8C63)) >> 2) & 0x8C63)
|
||||
|
||||
#define SAI_INTERPOLATE SAI_INTERPOLATE_1555
|
||||
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_1555
|
||||
|
||||
uint32 destWidth = width << 1;
|
||||
uint32 destHeight = height << 1;
|
||||
|
||||
uint16 color4, color5, color6;
|
||||
uint16 color1, color2, color3;
|
||||
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||
uint16 colorS1, colorS2;
|
||||
uint16 product1a, product1b, product2a, product2b;
|
||||
|
||||
#include "TextureFilters_2xsai.h"
|
||||
|
||||
#undef SAI_INTERPOLATE
|
||||
#undef SAI_Q_INTERPOLATE
|
||||
}
|
||||
|
||||
void Super2xSaI_565(uint16 *srcPtr, uint16 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
#define SAI_INTERPOLATE_565(A, B) ((A & 0xF7DE) >> 1) + ((B & 0xF7DE) >> 1) + (A & B & 0x0821)
|
||||
#define SAI_Q_INTERPOLATE_565(A, B, C, D) ((A & 0xE79C) >> 2) + ((B & 0xE79C) >> 2) + ((C & 0xE79C) >> 2) + ((D & 0xE79C) >> 2) \
|
||||
+ ((((A & 0x1863) + (B & 0x1863) + (C & 0x1863) + (D & 0x1863)) >> 2) & 0x1863)
|
||||
|
||||
#define SAI_INTERPOLATE SAI_INTERPOLATE_565
|
||||
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_565
|
||||
|
||||
uint32 destWidth = width << 1;
|
||||
uint32 destHeight = height << 1;
|
||||
|
||||
uint16 color4, color5, color6;
|
||||
uint16 color1, color2, color3;
|
||||
uint16 colorA0, colorA1, colorA2, colorA3;
|
||||
uint16 colorB0, colorB1, colorB2, colorB3;
|
||||
uint16 colorS1, colorS2;
|
||||
uint16 product1a, product1b, product2a, product2b;
|
||||
|
||||
#include "TextureFilters_2xsai.h"
|
||||
|
||||
#undef SAI_INTERPOLATE
|
||||
#undef SAI_Q_INTERPOLATE
|
||||
}
|
||||
|
||||
void Super2xSaI_8(uint8 *srcPtr, uint8 *destPtr, uint32 width, uint32 height, uint32 pitch)
|
||||
{
|
||||
#define SAI_INTERPOLATE_8(A, B) ((A & 0xFE) >> 1) + ((B & 0xFE) >> 1) + (A & B & 0x01)
|
||||
#define SAI_Q_INTERPOLATE_8(A, B, C, D) ((A & 0xFC) >> 2) + ((B & 0xFC) >> 2) + ((C & 0xFC) >> 2) + ((D & 0xFC) >> 2) \
|
||||
+ ((((A & 0x03) + (B & 0x03) + (C & 0x03) + (D & 0x03)) >> 2) & 0x03)
|
||||
|
||||
#define SAI_INTERPOLATE SAI_INTERPOLATE_8
|
||||
#define SAI_Q_INTERPOLATE SAI_Q_INTERPOLATE_8
|
||||
|
||||
uint32 destWidth = width << 1;
|
||||
uint32 destHeight = height << 1;
|
||||
|
||||
uint8 color4, color5, color6;
|
||||
uint8 color1, color2, color3;
|
||||
uint8 colorA0, colorA1, colorA2, colorA3;
|
||||
uint8 colorB0, colorB1, colorB2, colorB3;
|
||||
uint8 colorS1, colorS2;
|
||||
uint8 product1a, product1b, product2a, product2b;
|
||||
|
||||
#include "TextureFilters_2xsai.h"
|
||||
|
||||
#undef SAI_INTERPOLATE
|
||||
#undef SAI_Q_INTERPOLATE
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Based on Derek Liauw Kie Fa and Rice1964 Super2xSaI code */
|
||||
|
||||
int row0, row1, row2, row3;
|
||||
int col0, col1, col2, col3;
|
||||
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
if ((y > 0) && (y < height - 1)) {
|
||||
row0 = width;
|
||||
row0 = -row0;
|
||||
row1 = 0;
|
||||
row2 = width;
|
||||
row3 = (y == height - 2 ? width : width << 1);
|
||||
} else {
|
||||
row0 = 0;
|
||||
row1 = 0;
|
||||
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) && (x < width - 1)) {
|
||||
col0 = -1;
|
||||
col1 = 0;
|
||||
col2 = 1;
|
||||
col3 = (x == width - 2 ? 1 : 2);
|
||||
} else {
|
||||
col0 = 0;
|
||||
col1 = 0;
|
||||
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 += GET_RESULT(color6, color5, color1, colorA1);
|
||||
r += GET_RESULT(color6, color5, color4, colorB1);
|
||||
r += GET_RESULT(color6, color5, colorA2, colorS1);
|
||||
r += GET_RESULT(color6, color5, colorB2, colorS2);
|
||||
|
||||
if (r > 0)
|
||||
product2b = product1b = color6;
|
||||
else if (r < 0)
|
||||
product2b = product1b = color5;
|
||||
else
|
||||
product2b = product1b = SAI_INTERPOLATE(color5, color6);
|
||||
|
||||
} else {
|
||||
|
||||
if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
|
||||
product2b = SAI_Q_INTERPOLATE(color3, color3, color3, color2);
|
||||
else if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
|
||||
product2b = SAI_Q_INTERPOLATE(color2, color2, color2, color3);
|
||||
else
|
||||
product2b = SAI_INTERPOLATE(color2, color3);
|
||||
|
||||
if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
|
||||
product1b = SAI_Q_INTERPOLATE(color6, color6, color6, color5);
|
||||
else if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
|
||||
product1b = SAI_Q_INTERPOLATE(color6, color5, color5, color5);
|
||||
else
|
||||
product1b = SAI_INTERPOLATE(color5, color6);
|
||||
}
|
||||
|
||||
if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
|
||||
product2a = SAI_INTERPOLATE(color2, color5);
|
||||
else if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
|
||||
product2a = SAI_INTERPOLATE(color2, color5);
|
||||
else
|
||||
product2a = color2;
|
||||
|
||||
if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
|
||||
product1a = SAI_INTERPOLATE(color2, color5);
|
||||
else if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
|
||||
product1a = SAI_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));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,892 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Based on Maxim Stepin and Rice1964 hq4x code */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "TextureFilters.h"
|
||||
|
||||
#if !_16BPP_HACK
|
||||
static uint32 RGB444toYUV[4096];
|
||||
#define RGB444toYUV(val) RGB444toYUV[val & 0x0FFF] /* val = ARGB4444 */
|
||||
|
||||
/*inline static uint32 RGB444toYUV(uint32 val)
|
||||
{
|
||||
uint32 r, g, b, Y, u, v;
|
||||
|
||||
r = (val & 0x0F00) >> 4;
|
||||
g = (val & 0x00F0);
|
||||
b = val & 0x000F;
|
||||
r |= r >> 4;
|
||||
g |= g >> 4;
|
||||
b |= b << 4;
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = 128 + ((r - b) >> 2);
|
||||
v = 128 + ((2*g - r - b)>>3);
|
||||
|
||||
return ((Y << 16) | (u << 8) | v);
|
||||
}*/
|
||||
|
||||
static uint32 RGB555toYUV(uint32 val)
|
||||
{
|
||||
uint32 r, g, b, Y, u, v;
|
||||
|
||||
r = (val & 0x7C00) >> 7;
|
||||
g = (val & 0x03E0) >> 2;
|
||||
b = (val & 0x001F) << 3;
|
||||
r |= r >> 5;
|
||||
g |= g >> 5;
|
||||
b |= b >> 5;
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = 128 + ((r - b) >> 2);
|
||||
v = 128 + ((2*g - r - b)>>3);
|
||||
|
||||
return ((Y << 16) | (u << 8) | v);
|
||||
}
|
||||
|
||||
static uint32 RGB565toYUV(uint32 val)
|
||||
{
|
||||
uint32 r, g, b, Y, u, v;
|
||||
|
||||
r = (val & 0xF800) >> 8;
|
||||
g = (val & 0x07E0) >> 3;
|
||||
b = (val & 0x001F) << 3;
|
||||
r |= r >> 5;
|
||||
g |= g >> 6;
|
||||
b |= b >> 5;
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = 128 + ((r - b) >> 2);
|
||||
v = 128 + ((2*g - r - b)>>3);
|
||||
|
||||
return ((Y << 16) | (u << 8) | v);
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
static uint32 RGB888toYUV(uint32 val)
|
||||
{
|
||||
#if 0
|
||||
uint32 Yuv;
|
||||
|
||||
__asm {
|
||||
mov eax, dword ptr [val];
|
||||
mov ebx, eax;
|
||||
mov ecx, eax;
|
||||
and ebx, 0x000000ff; // b
|
||||
and eax, 0x00ff0000; // r
|
||||
and ecx, 0x0000ff00; // g
|
||||
shl ebx, 14;
|
||||
shr eax, 2;
|
||||
shl ecx, 6;
|
||||
mov edx, ebx;
|
||||
add edx, eax;
|
||||
add edx, ecx;
|
||||
and edx, 0xffff0000;
|
||||
|
||||
sub eax, ebx;
|
||||
add eax, 0x00800000;
|
||||
shr eax, 8;
|
||||
or edx, eax;
|
||||
sub eax, 0x00800000;
|
||||
and edx, 0xffffff00;
|
||||
|
||||
add ecx, 0x00800000;
|
||||
shr ecx, 5;
|
||||
shr ebx, 7;
|
||||
add eax, ebx;
|
||||
sub ecx, eax;
|
||||
shr ecx, 11;
|
||||
or edx, ecx;
|
||||
|
||||
mov dword ptr [Yuv], edx;
|
||||
}
|
||||
|
||||
return Yuv;
|
||||
#else
|
||||
uint32 r, g, b, Y, u, v;
|
||||
|
||||
r = (val & 0x00ff0000) >> 16;
|
||||
g = (val & 0x0000ff00) >> 8;
|
||||
b = val & 0x000000ff;
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = (0x00000200 + r - b) >> 2;
|
||||
v = (0x00000400 + (g << 1) - r - b) >> 3;
|
||||
|
||||
return ((Y << 16) | (u << 8) | v);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define Ymask 0x00FF0000
|
||||
#define Umask 0x0000FF00
|
||||
#define Vmask 0x000000FF
|
||||
#define trY 0x00300000 // ?
|
||||
#define trU 0x00000700 // ??
|
||||
#define trV 0x00000006 // ???
|
||||
|
||||
#define HQ4X_INTERP1(n, b) \
|
||||
static void hq4x_Interp1_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||
{ \
|
||||
/* *((uint##b*)pc) = (p1*3+p2) >> 2; */ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*3 + INTERP_##n##_MASK_1_3(p2)) / 4) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*3 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 4 ); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP2(n, b) \
|
||||
static void hq4x_Interp2_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1*2+p2+p3) >> 2;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*2 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 4) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*2 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 4); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP3(n, b) \
|
||||
static void hq4x_Interp3_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1*7+p2)/8;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*7 + INTERP_##n##_MASK_1_3(p2)) / 8) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*7 + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 8); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP5(n, b) \
|
||||
static void hq4x_Interp5_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1+p2) >> 1;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1) + INTERP_##n##_MASK_1_3(p2)) / 2) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1) + INTERP_##n##_MASK_SHIFT_2_4(p2)) / 2); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP6(n, b) \
|
||||
static void hq4x_Interp6_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1*5+p2*2+p3)/8;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*2 + INTERP_##n##_MASK_1_3(p3)) / 8) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*2 + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP7(n, b) \
|
||||
static void hq4x_Interp7_##n (uint8 * pc, uint##b p1, uint##b p2, uint##b p3) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1*6+p2+p3)/8;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*6 + INTERP_##n##_MASK_1_3(p2) + INTERP_##n##_MASK_1_3(p3)) / 8) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*6 + INTERP_##n##_MASK_SHIFT_2_4(p2) + INTERP_##n##_MASK_SHIFT_2_4(p3)) / 8); \
|
||||
}
|
||||
|
||||
#define HQ4X_INTERP8(n, b) \
|
||||
static void hq4x_Interp8_##n (uint8 * pc, uint##b p1, uint##b p2) \
|
||||
{ \
|
||||
/**((uint##b*)pc) = (p1*5+p2*3)/8;*/ \
|
||||
*((uint##b*)pc) = INTERP_##n##_MASK_1_3((INTERP_##n##_MASK_1_3(p1)*5 + INTERP_##n##_MASK_1_3(p2)*3) / 8) \
|
||||
| INTERP_##n##_MASK_SHIFTBACK_2_4((INTERP_##n##_MASK_SHIFT_2_4(p1)*5 + INTERP_##n##_MASK_SHIFT_2_4(p2)*3) / 8); \
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
#define INTERP_4444_MASK_1_3(v) (v & 0x0F0F)
|
||||
#define INTERP_4444_MASK_SHIFT_2_4(v) ((v & 0xF0F0) >> 4)
|
||||
#define INTERP_4444_MASK_SHIFTBACK_2_4(v) (INTERP_4444_MASK_1_3(v) << 4)
|
||||
HQ4X_INTERP1(4444, 16)
|
||||
HQ4X_INTERP2(4444, 16)
|
||||
HQ4X_INTERP3(4444, 16)
|
||||
HQ4X_INTERP5(4444, 16)
|
||||
HQ4X_INTERP6(4444, 16)
|
||||
HQ4X_INTERP7(4444, 16)
|
||||
HQ4X_INTERP8(4444, 16)
|
||||
|
||||
#define INTERP_1555_MASK_1_3(v) (v & 0x7C1F)
|
||||
#define INTERP_1555_MASK_SHIFT_2_4(v) ((v & 0x83E0) >> 5)
|
||||
#define INTERP_1555_MASK_SHIFTBACK_2_4(v) (INTERP_1555_MASK_1_3(v) << 5)
|
||||
HQ4X_INTERP1(1555, 16)
|
||||
HQ4X_INTERP2(1555, 16)
|
||||
HQ4X_INTERP3(1555, 16)
|
||||
HQ4X_INTERP5(1555, 16)
|
||||
HQ4X_INTERP6(1555, 16)
|
||||
HQ4X_INTERP7(1555, 16)
|
||||
HQ4X_INTERP8(1555, 16)
|
||||
|
||||
#define INTERP_565_MASK_1_3(v) (v & 0xF81F)
|
||||
#define INTERP_565_MASK_SHIFT_2_4(v) ((v & 0x7E0) >> 5)
|
||||
#define INTERP_565_MASK_SHIFTBACK_2_4(v) (INTERP_565_MASK_1_3(v) << 5)
|
||||
HQ4X_INTERP1(565, 16)
|
||||
HQ4X_INTERP2(565, 16)
|
||||
HQ4X_INTERP3(565, 16)
|
||||
HQ4X_INTERP5(565, 16)
|
||||
HQ4X_INTERP6(565, 16)
|
||||
HQ4X_INTERP7(565, 16)
|
||||
HQ4X_INTERP8(565, 16)
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
#define INTERP_8888_MASK_1_3(v) (v & 0x00FF00FF)
|
||||
#define INTERP_8888_MASK_SHIFT_2_4(v) ((v & 0xFF00FF00) >> 8)
|
||||
#define INTERP_8888_MASK_SHIFTBACK_2_4(v) (INTERP_8888_MASK_1_3(v) << 8)
|
||||
HQ4X_INTERP1(8888, 32)
|
||||
HQ4X_INTERP2(8888, 32)
|
||||
HQ4X_INTERP3(8888, 32)
|
||||
HQ4X_INTERP5(8888, 32)
|
||||
HQ4X_INTERP6(8888, 32)
|
||||
HQ4X_INTERP7(8888, 32)
|
||||
HQ4X_INTERP8(8888, 32)
|
||||
|
||||
#define PIXEL00_0 *((int*)(pOut)) = c[5];
|
||||
#define PIXEL00_11 hq4x_Interp1(pOut, c[5], c[4]);
|
||||
#define PIXEL00_12 hq4x_Interp1(pOut, c[5], c[2]);
|
||||
#define PIXEL00_20 hq4x_Interp2(pOut, c[5], c[2], c[4]);
|
||||
#define PIXEL00_50 hq4x_Interp5(pOut, c[2], c[4]);
|
||||
#define PIXEL00_80 hq4x_Interp8(pOut, c[5], c[1]);
|
||||
#define PIXEL00_81 hq4x_Interp8(pOut, c[5], c[4]);
|
||||
#define PIXEL00_82 hq4x_Interp8(pOut, c[5], c[2]);
|
||||
#define PIXEL01_0 *((int*)(pOut+BPP)) = c[5];
|
||||
#define PIXEL01_10 hq4x_Interp1(pOut+BPP, c[5], c[1]);
|
||||
#define PIXEL01_12 hq4x_Interp1(pOut+BPP, c[5], c[2]);
|
||||
#define PIXEL01_14 hq4x_Interp1(pOut+BPP, c[2], c[5]);
|
||||
#define PIXEL01_21 hq4x_Interp2(pOut+BPP, c[2], c[5], c[4]);
|
||||
#define PIXEL01_31 hq4x_Interp3(pOut+BPP, c[5], c[4]);
|
||||
#define PIXEL01_50 hq4x_Interp5(pOut+BPP, c[2], c[5]);
|
||||
#define PIXEL01_60 hq4x_Interp6(pOut+BPP, c[5], c[2], c[4]);
|
||||
#define PIXEL01_61 hq4x_Interp6(pOut+BPP, c[5], c[2], c[1]);
|
||||
#define PIXEL01_82 hq4x_Interp8(pOut+BPP, c[5], c[2]);
|
||||
#define PIXEL01_83 hq4x_Interp8(pOut+BPP, c[2], c[4]);
|
||||
#define PIXEL02_0 *((int*)(pOut+BPP2)) = c[5];
|
||||
#define PIXEL02_10 hq4x_Interp1(pOut+BPP2, c[5], c[3]);
|
||||
#define PIXEL02_11 hq4x_Interp1(pOut+BPP2, c[5], c[2]);
|
||||
#define PIXEL02_13 hq4x_Interp1(pOut+BPP2, c[2], c[5]);
|
||||
#define PIXEL02_21 hq4x_Interp2(pOut+BPP2, c[2], c[5], c[6]);
|
||||
#define PIXEL02_32 hq4x_Interp3(pOut+BPP2, c[5], c[6]);
|
||||
#define PIXEL02_50 hq4x_Interp5(pOut+BPP2, c[2], c[5]);
|
||||
#define PIXEL02_60 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[6]);
|
||||
#define PIXEL02_61 hq4x_Interp6(pOut+BPP2, c[5], c[2], c[3]);
|
||||
#define PIXEL02_81 hq4x_Interp8(pOut+BPP2, c[5], c[2]);
|
||||
#define PIXEL02_83 hq4x_Interp8(pOut+BPP2, c[2], c[6]);
|
||||
#define PIXEL03_0 *((int*)(pOut+BPP3)) = c[5];
|
||||
#define PIXEL03_11 hq4x_Interp1(pOut+BPP3, c[5], c[2]);
|
||||
#define PIXEL03_12 hq4x_Interp1(pOut+BPP3, c[5], c[6]);
|
||||
#define PIXEL03_20 hq4x_Interp2(pOut+BPP3, c[5], c[2], c[6]);
|
||||
#define PIXEL03_50 hq4x_Interp5(pOut+BPP3, c[2], c[6]);
|
||||
#define PIXEL03_80 hq4x_Interp8(pOut+BPP3, c[5], c[3]);
|
||||
#define PIXEL03_81 hq4x_Interp8(pOut+BPP3, c[5], c[2]);
|
||||
#define PIXEL03_82 hq4x_Interp8(pOut+BPP3, c[5], c[6]);
|
||||
#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5];
|
||||
#define PIXEL10_10 hq4x_Interp1(pOut+BpL, c[5], c[1]);
|
||||
#define PIXEL10_11 hq4x_Interp1(pOut+BpL, c[5], c[4]);
|
||||
#define PIXEL10_13 hq4x_Interp1(pOut+BpL, c[4], c[5]);
|
||||
#define PIXEL10_21 hq4x_Interp2(pOut+BpL, c[4], c[5], c[2]);
|
||||
#define PIXEL10_32 hq4x_Interp3(pOut+BpL, c[5], c[2]);
|
||||
#define PIXEL10_50 hq4x_Interp5(pOut+BpL, c[4], c[5]);
|
||||
#define PIXEL10_60 hq4x_Interp6(pOut+BpL, c[5], c[4], c[2]);
|
||||
#define PIXEL10_61 hq4x_Interp6(pOut+BpL, c[5], c[4], c[1]);
|
||||
#define PIXEL10_81 hq4x_Interp8(pOut+BpL, c[5], c[4]);
|
||||
#define PIXEL10_83 hq4x_Interp8(pOut+BpL, c[4], c[2]);
|
||||
#define PIXEL11_0 *((int*)(pOut+BpL+BPP)) = c[5];
|
||||
#define PIXEL11_30 hq4x_Interp3(pOut+BpL+BPP, c[5], c[1]);
|
||||
#define PIXEL11_31 hq4x_Interp3(pOut+BpL+BPP, c[5], c[4]);
|
||||
#define PIXEL11_32 hq4x_Interp3(pOut+BpL+BPP, c[5], c[2]);
|
||||
#define PIXEL11_70 hq4x_Interp7(pOut+BpL+BPP, c[5], c[4], c[2]);
|
||||
#define PIXEL12_0 *((int*)(pOut+BpL+BPP2)) = c[5];
|
||||
#define PIXEL12_30 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[3]);
|
||||
#define PIXEL12_31 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[2]);
|
||||
#define PIXEL12_32 hq4x_Interp3(pOut+BpL+BPP2, c[5], c[6]);
|
||||
#define PIXEL12_70 hq4x_Interp7(pOut+BpL+BPP2, c[5], c[6], c[2]);
|
||||
#define PIXEL13_0 *((int*)(pOut+BpL+BPP3)) = c[5];
|
||||
#define PIXEL13_10 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[3]);
|
||||
#define PIXEL13_12 hq4x_Interp1(pOut+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL13_14 hq4x_Interp1(pOut+BpL+BPP3, c[6], c[5]);
|
||||
#define PIXEL13_21 hq4x_Interp2(pOut+BpL+BPP3, c[6], c[5], c[2]);
|
||||
#define PIXEL13_31 hq4x_Interp3(pOut+BpL+BPP3, c[5], c[2]);
|
||||
#define PIXEL13_50 hq4x_Interp5(pOut+BpL+BPP3, c[6], c[5]);
|
||||
#define PIXEL13_60 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[2]);
|
||||
#define PIXEL13_61 hq4x_Interp6(pOut+BpL+BPP3, c[5], c[6], c[3]);
|
||||
#define PIXEL13_82 hq4x_Interp8(pOut+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL13_83 hq4x_Interp8(pOut+BpL+BPP3, c[6], c[2]);
|
||||
#define PIXEL20_0 *((int*)(pOut+BpL+BpL)) = c[5];
|
||||
#define PIXEL20_10 hq4x_Interp1(pOut+BpL+BpL, c[5], c[7]);
|
||||
#define PIXEL20_12 hq4x_Interp1(pOut+BpL+BpL, c[5], c[4]);
|
||||
#define PIXEL20_14 hq4x_Interp1(pOut+BpL+BpL, c[4], c[5]);
|
||||
#define PIXEL20_21 hq4x_Interp2(pOut+BpL+BpL, c[4], c[5], c[8]);
|
||||
#define PIXEL20_31 hq4x_Interp3(pOut+BpL+BpL, c[5], c[8]);
|
||||
#define PIXEL20_50 hq4x_Interp5(pOut+BpL+BpL, c[4], c[5]);
|
||||
#define PIXEL20_60 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[8]);
|
||||
#define PIXEL20_61 hq4x_Interp6(pOut+BpL+BpL, c[5], c[4], c[7]);
|
||||
#define PIXEL20_82 hq4x_Interp8(pOut+BpL+BpL, c[5], c[4]);
|
||||
#define PIXEL20_83 hq4x_Interp8(pOut+BpL+BpL, c[4], c[8]);
|
||||
#define PIXEL21_0 *((int*)(pOut+BpL+BpL+BPP)) = c[5];
|
||||
#define PIXEL21_30 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[7]);
|
||||
#define PIXEL21_31 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[8]);
|
||||
#define PIXEL21_32 hq4x_Interp3(pOut+BpL+BpL+BPP, c[5], c[4]);
|
||||
#define PIXEL21_70 hq4x_Interp7(pOut+BpL+BpL+BPP, c[5], c[4], c[8]);
|
||||
#define PIXEL22_0 *((int*)(pOut+BpL+BpL+BPP2)) = c[5];
|
||||
#define PIXEL22_30 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[9]);
|
||||
#define PIXEL22_31 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[6]);
|
||||
#define PIXEL22_32 hq4x_Interp3(pOut+BpL+BpL+BPP2, c[5], c[8]);
|
||||
#define PIXEL22_70 hq4x_Interp7(pOut+BpL+BpL+BPP2, c[5], c[6], c[8]);
|
||||
#define PIXEL23_0 *((int*)(pOut+BpL+BpL+BPP3)) = c[5];
|
||||
#define PIXEL23_10 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[9]);
|
||||
#define PIXEL23_11 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL23_13 hq4x_Interp1(pOut+BpL+BpL+BPP3, c[6], c[5]);
|
||||
#define PIXEL23_21 hq4x_Interp2(pOut+BpL+BpL+BPP3, c[6], c[5], c[8]);
|
||||
#define PIXEL23_32 hq4x_Interp3(pOut+BpL+BpL+BPP3, c[5], c[8]);
|
||||
#define PIXEL23_50 hq4x_Interp5(pOut+BpL+BpL+BPP3, c[6], c[5]);
|
||||
#define PIXEL23_60 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[8]);
|
||||
#define PIXEL23_61 hq4x_Interp6(pOut+BpL+BpL+BPP3, c[5], c[6], c[9]);
|
||||
#define PIXEL23_81 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL23_83 hq4x_Interp8(pOut+BpL+BpL+BPP3, c[6], c[8]);
|
||||
#define PIXEL30_0 *((int*)(pOut+BpL+BpL+BpL)) = c[5];
|
||||
#define PIXEL30_11 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[8]);
|
||||
#define PIXEL30_12 hq4x_Interp1(pOut+BpL+BpL+BpL, c[5], c[4]);
|
||||
#define PIXEL30_20 hq4x_Interp2(pOut+BpL+BpL+BpL, c[5], c[8], c[4]);
|
||||
#define PIXEL30_50 hq4x_Interp5(pOut+BpL+BpL+BpL, c[8], c[4]);
|
||||
#define PIXEL30_80 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[7]);
|
||||
#define PIXEL30_81 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[8]);
|
||||
#define PIXEL30_82 hq4x_Interp8(pOut+BpL+BpL+BpL, c[5], c[4]);
|
||||
#define PIXEL31_0 *((int*)(pOut+BpL+BpL+BpL+BPP)) = c[5];
|
||||
#define PIXEL31_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[7]);
|
||||
#define PIXEL31_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[5], c[8]);
|
||||
#define PIXEL31_13 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP, c[8], c[5]);
|
||||
#define PIXEL31_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP, c[8], c[5], c[4]);
|
||||
#define PIXEL31_32 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP, c[5], c[4]);
|
||||
#define PIXEL31_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP, c[8], c[5]);
|
||||
#define PIXEL31_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[4]);
|
||||
#define PIXEL31_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP, c[5], c[8], c[7]);
|
||||
#define PIXEL31_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[5], c[8]);
|
||||
#define PIXEL31_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP, c[8], c[4]);
|
||||
#define PIXEL32_0 *((int*)(pOut+BpL+BpL+BpL+BPP2)) = c[5];
|
||||
#define PIXEL32_10 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[9]);
|
||||
#define PIXEL32_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]);
|
||||
#define PIXEL32_14 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]);
|
||||
#define PIXEL32_21 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP2, c[8], c[5], c[6]);
|
||||
#define PIXEL32_31 hq4x_Interp3(pOut+BpL+BpL+BpL+BPP2, c[5], c[6]);
|
||||
#define PIXEL32_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP2, c[8], c[5]);
|
||||
#define PIXEL32_60 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[6]);
|
||||
#define PIXEL32_61 hq4x_Interp6(pOut+BpL+BpL+BpL+BPP2, c[5], c[8], c[9]);
|
||||
#define PIXEL32_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[5], c[8]);
|
||||
#define PIXEL32_83 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP2, c[8], c[6]);
|
||||
#define PIXEL33_0 *((int*)(pOut+BpL+BpL+BpL+BPP3)) = c[5];
|
||||
#define PIXEL33_11 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL33_12 hq4x_Interp1(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]);
|
||||
#define PIXEL33_20 hq4x_Interp2(pOut+BpL+BpL+BpL+BPP3, c[5], c[8], c[6]);
|
||||
#define PIXEL33_50 hq4x_Interp5(pOut+BpL+BpL+BpL+BPP3, c[8], c[6]);
|
||||
#define PIXEL33_80 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[9]);
|
||||
#define PIXEL33_81 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[6]);
|
||||
#define PIXEL33_82 hq4x_Interp8(pOut+BpL+BpL+BpL+BPP3, c[5], c[8]);
|
||||
|
||||
#define HQ4X_DIFF(n, b) \
|
||||
static int Diff_##n (uint##b w1, uint##b w2) \
|
||||
{ \
|
||||
int YUV1, YUV2; \
|
||||
YUV1 = RGB##n##toYUV(w1); \
|
||||
YUV2 = RGB##n##toYUV(w2); \
|
||||
return ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || \
|
||||
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || \
|
||||
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ); \
|
||||
}
|
||||
|
||||
HQ4X_DIFF(888, 32)
|
||||
|
||||
#if !_16BPP_HACK
|
||||
HQ4X_DIFF(444, 16)
|
||||
HQ4X_DIFF(555, 16)
|
||||
HQ4X_DIFF(565, 16)
|
||||
|
||||
void hq4x_4444(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||
{
|
||||
#define hq4x_Interp1 hq4x_Interp1_4444
|
||||
#define hq4x_Interp2 hq4x_Interp2_4444
|
||||
#define hq4x_Interp3 hq4x_Interp3_4444
|
||||
#define hq4x_Interp4 hq4x_Interp4_4444
|
||||
#define hq4x_Interp5 hq4x_Interp5_4444
|
||||
#define hq4x_Interp6 hq4x_Interp6_4444
|
||||
#define hq4x_Interp7 hq4x_Interp7_4444
|
||||
#define hq4x_Interp8 hq4x_Interp8_4444
|
||||
#define Diff Diff_444
|
||||
#define BPP 2
|
||||
#define BPP2 4
|
||||
#define BPP3 6
|
||||
|
||||
int i, j, k;
|
||||
int prevline, nextline;
|
||||
uint16 w[10];
|
||||
uint16 c[10];
|
||||
|
||||
int pattern;
|
||||
int flag;
|
||||
|
||||
int YUV1, YUV2;
|
||||
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w1 | w2 | w3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w4 | w5 | w6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w7 | w8 | w9 |
|
||||
// +----+----+----+
|
||||
|
||||
for (j = 0; j < Yres; j++) {
|
||||
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||
|
||||
for (i=0; i<Xres; i++) {
|
||||
w[2] = *((uint16*)(pIn + prevline));
|
||||
w[5] = *((uint16*)pIn);
|
||||
w[8] = *((uint16*)(pIn + nextline));
|
||||
|
||||
if (i>0) {
|
||||
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||
w[4] = *((uint16*)(pIn - 2));
|
||||
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||
} else {
|
||||
w[1] = w[2];
|
||||
w[4] = w[5];
|
||||
w[7] = w[8];
|
||||
}
|
||||
|
||||
if (i<Xres-1) {
|
||||
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||
w[6] = *((uint16*)(pIn + 2));
|
||||
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||
} else {
|
||||
w[3] = w[2];
|
||||
w[6] = w[5];
|
||||
w[9] = w[8];
|
||||
}
|
||||
|
||||
pattern = 0;
|
||||
flag = 1;
|
||||
|
||||
YUV1 = RGB444toYUV(w[5]);
|
||||
|
||||
for (k=1; k<=9; k++) {
|
||||
if (k==5) continue;
|
||||
|
||||
if ( w[k] != w[5] ) {
|
||||
YUV2 = RGB444toYUV(w[k]);
|
||||
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||
pattern |= flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
for (k=1; k<=9; k++)
|
||||
c[k] = w[k];
|
||||
|
||||
#include "TextureFilters_hq4x.h"
|
||||
|
||||
pIn+=2;
|
||||
pOut+=8;
|
||||
}
|
||||
pIn += 2*(SrcPPL-Xres);
|
||||
pOut+= 8*(SrcPPL-Xres);
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
}
|
||||
|
||||
#undef BPP
|
||||
#undef BPP2
|
||||
#undef BPP3
|
||||
#undef Diff
|
||||
#undef hq4x_Interp1
|
||||
#undef hq4x_Interp2
|
||||
#undef hq4x_Interp3
|
||||
#undef hq4x_Interp4
|
||||
#undef hq4x_Interp5
|
||||
#undef hq4x_Interp6
|
||||
#undef hq4x_Interp7
|
||||
#undef hq4x_Interp8
|
||||
}
|
||||
|
||||
void hq4x_1555(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||
{
|
||||
#define hq4x_Interp1 hq4x_Interp1_1555
|
||||
#define hq4x_Interp2 hq4x_Interp2_1555
|
||||
#define hq4x_Interp3 hq4x_Interp3_1555
|
||||
#define hq4x_Interp4 hq4x_Interp4_1555
|
||||
#define hq4x_Interp5 hq4x_Interp5_1555
|
||||
#define hq4x_Interp6 hq4x_Interp6_1555
|
||||
#define hq4x_Interp7 hq4x_Interp7_1555
|
||||
#define hq4x_Interp8 hq4x_Interp8_1555
|
||||
#define Diff Diff_555
|
||||
#define BPP 2
|
||||
#define BPP2 4
|
||||
#define BPP3 6
|
||||
|
||||
int i, j, k;
|
||||
int prevline, nextline;
|
||||
uint16 w[10];
|
||||
uint16 c[10];
|
||||
|
||||
int pattern;
|
||||
int flag;
|
||||
|
||||
int YUV1, YUV2;
|
||||
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w1 | w2 | w3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w4 | w5 | w6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w7 | w8 | w9 |
|
||||
// +----+----+----+
|
||||
|
||||
for (j = 0; j < Yres; j++) {
|
||||
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||
|
||||
for (i=0; i<Xres; i++) {
|
||||
w[2] = *((uint16*)(pIn + prevline));
|
||||
w[5] = *((uint16*)pIn);
|
||||
w[8] = *((uint16*)(pIn + nextline));
|
||||
|
||||
if (i>0) {
|
||||
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||
w[4] = *((uint16*)(pIn - 2));
|
||||
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||
} else {
|
||||
w[1] = w[2];
|
||||
w[4] = w[5];
|
||||
w[7] = w[8];
|
||||
}
|
||||
|
||||
if (i<Xres-1) {
|
||||
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||
w[6] = *((uint16*)(pIn + 2));
|
||||
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||
} else {
|
||||
w[3] = w[2];
|
||||
w[6] = w[5];
|
||||
w[9] = w[8];
|
||||
}
|
||||
|
||||
pattern = 0;
|
||||
flag = 1;
|
||||
|
||||
YUV1 = RGB555toYUV(w[5]);
|
||||
|
||||
for (k=1; k<=9; k++) {
|
||||
if (k==5) continue;
|
||||
|
||||
if ( w[k] != w[5] ) {
|
||||
YUV2 = RGB555toYUV(w[k]);
|
||||
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||
pattern |= flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
for (k=1; k<=9; k++)
|
||||
c[k] = w[k];
|
||||
|
||||
#include "TextureFilters_hq4x.h"
|
||||
|
||||
pIn+=2;
|
||||
pOut+=8;
|
||||
}
|
||||
pIn += 2*(SrcPPL-Xres);
|
||||
pOut+= 8*(SrcPPL-Xres);
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
}
|
||||
|
||||
#undef BPP
|
||||
#undef BPP2
|
||||
#undef BPP3
|
||||
#undef Diff
|
||||
#undef hq4x_Interp1
|
||||
#undef hq4x_Interp2
|
||||
#undef hq4x_Interp3
|
||||
#undef hq4x_Interp4
|
||||
#undef hq4x_Interp5
|
||||
#undef hq4x_Interp6
|
||||
#undef hq4x_Interp7
|
||||
#undef hq4x_Interp8
|
||||
}
|
||||
|
||||
void hq4x_565(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||
{
|
||||
#define hq4x_Interp1 hq4x_Interp1_565
|
||||
#define hq4x_Interp2 hq4x_Interp2_565
|
||||
#define hq4x_Interp3 hq4x_Interp3_565
|
||||
#define hq4x_Interp4 hq4x_Interp4_565
|
||||
#define hq4x_Interp5 hq4x_Interp5_565
|
||||
#define hq4x_Interp6 hq4x_Interp6_565
|
||||
#define hq4x_Interp7 hq4x_Interp7_565
|
||||
#define hq4x_Interp8 hq4x_Interp8_565
|
||||
#define Diff Diff_565
|
||||
#define BPP 2
|
||||
#define BPP2 4
|
||||
#define BPP3 6
|
||||
|
||||
int i, j, k;
|
||||
int prevline, nextline;
|
||||
uint16 w[10];
|
||||
uint16 c[10];
|
||||
|
||||
int pattern;
|
||||
int flag;
|
||||
|
||||
int YUV1, YUV2;
|
||||
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w1 | w2 | w3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w4 | w5 | w6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w7 | w8 | w9 |
|
||||
// +----+----+----+
|
||||
|
||||
for (j = 0; j < Yres; j++) {
|
||||
if (j>0) prevline = -SrcPPL*2; else prevline = 0;
|
||||
if (j<Yres-1) nextline = SrcPPL*2; else nextline = 0;
|
||||
|
||||
for (i=0; i<Xres; i++) {
|
||||
w[2] = *((uint16*)(pIn + prevline));
|
||||
w[5] = *((uint16*)pIn);
|
||||
w[8] = *((uint16*)(pIn + nextline));
|
||||
|
||||
if (i>0) {
|
||||
w[1] = *((uint16*)(pIn + prevline - 2));
|
||||
w[4] = *((uint16*)(pIn - 2));
|
||||
w[7] = *((uint16*)(pIn + nextline - 2));
|
||||
} else {
|
||||
w[1] = w[2];
|
||||
w[4] = w[5];
|
||||
w[7] = w[8];
|
||||
}
|
||||
|
||||
if (i<Xres-1) {
|
||||
w[3] = *((uint16*)(pIn + prevline + 2));
|
||||
w[6] = *((uint16*)(pIn + 2));
|
||||
w[9] = *((uint16*)(pIn + nextline + 2));
|
||||
} else {
|
||||
w[3] = w[2];
|
||||
w[6] = w[5];
|
||||
w[9] = w[8];
|
||||
}
|
||||
|
||||
pattern = 0;
|
||||
flag = 1;
|
||||
|
||||
YUV1 = RGB565toYUV(w[5]);
|
||||
|
||||
for (k=1; k<=9; k++) {
|
||||
if (k==5) continue;
|
||||
|
||||
if ( w[k] != w[5] ) {
|
||||
YUV2 = RGB565toYUV(w[k]);
|
||||
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||
pattern |= flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
for (k=1; k<=9; k++)
|
||||
c[k] = w[k];
|
||||
|
||||
#include "TextureFilters_hq4x.h"
|
||||
|
||||
pIn+=2;
|
||||
pOut+=8;
|
||||
}
|
||||
pIn += 2*(SrcPPL-Xres);
|
||||
pOut+= 8*(SrcPPL-Xres);
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
}
|
||||
|
||||
#undef BPP
|
||||
#undef BPP2
|
||||
#undef BPP3
|
||||
#undef Diff
|
||||
#undef hq4x_Interp1
|
||||
#undef hq4x_Interp2
|
||||
#undef hq4x_Interp3
|
||||
#undef hq4x_Interp4
|
||||
#undef hq4x_Interp5
|
||||
#undef hq4x_Interp6
|
||||
#undef hq4x_Interp7
|
||||
#undef hq4x_Interp8
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
||||
|
||||
void hq4x_8888(unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int SrcPPL, int BpL)
|
||||
{
|
||||
#define hq4x_Interp1 hq4x_Interp1_8888
|
||||
#define hq4x_Interp2 hq4x_Interp2_8888
|
||||
#define hq4x_Interp3 hq4x_Interp3_8888
|
||||
#define hq4x_Interp4 hq4x_Interp4_8888
|
||||
#define hq4x_Interp5 hq4x_Interp5_8888
|
||||
#define hq4x_Interp6 hq4x_Interp6_8888
|
||||
#define hq4x_Interp7 hq4x_Interp7_8888
|
||||
#define hq4x_Interp8 hq4x_Interp8_8888
|
||||
#define Diff Diff_888
|
||||
#define BPP 4
|
||||
#define BPP2 8
|
||||
#define BPP3 12
|
||||
|
||||
int i, j, k;
|
||||
int prevline, nextline;
|
||||
uint32 w[10];
|
||||
uint32 c[10];
|
||||
|
||||
int pattern;
|
||||
int flag;
|
||||
|
||||
int YUV1, YUV2;
|
||||
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w1 | w2 | w3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w4 | w5 | w6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | w7 | w8 | w9 |
|
||||
// +----+----+----+
|
||||
|
||||
for (j = 0; j < Yres; j++) {
|
||||
if (j>0) prevline = -SrcPPL*4; else prevline = 0;
|
||||
if (j<Yres-1) nextline = SrcPPL*4; else nextline = 0;
|
||||
|
||||
for (i=0; i<Xres; i++) {
|
||||
w[2] = *((uint32*)(pIn + prevline));
|
||||
w[5] = *((uint32*)pIn);
|
||||
w[8] = *((uint32*)(pIn + nextline));
|
||||
|
||||
if (i>0) {
|
||||
w[1] = *((uint32*)(pIn + prevline - 4));
|
||||
w[4] = *((uint32*)(pIn - 4));
|
||||
w[7] = *((uint32*)(pIn + nextline - 4));
|
||||
} else {
|
||||
w[1] = w[2];
|
||||
w[4] = w[5];
|
||||
w[7] = w[8];
|
||||
}
|
||||
|
||||
if (i<Xres-1) {
|
||||
w[3] = *((uint32*)(pIn + prevline + 4));
|
||||
w[6] = *((uint32*)(pIn + 4));
|
||||
w[9] = *((uint32*)(pIn + nextline + 4));
|
||||
} else {
|
||||
w[3] = w[2];
|
||||
w[6] = w[5];
|
||||
w[9] = w[8];
|
||||
}
|
||||
|
||||
pattern = 0;
|
||||
flag = 1;
|
||||
|
||||
YUV1 = RGB888toYUV(w[5]);
|
||||
|
||||
for (k=1; k<=9; k++) {
|
||||
if (k==5) continue;
|
||||
|
||||
if ( w[k] != w[5] ) {
|
||||
YUV2 = RGB888toYUV(w[k]);
|
||||
if ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) ||
|
||||
( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) ||
|
||||
( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) )
|
||||
pattern |= flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
for (k=1; k<=9; k++)
|
||||
c[k] = w[k];
|
||||
|
||||
#include "TextureFilters_hq4x.h"
|
||||
|
||||
pIn+=4;
|
||||
pOut+=16;
|
||||
}
|
||||
|
||||
pIn += 4*(SrcPPL-Xres);
|
||||
pOut+= 16*(SrcPPL-Xres);
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
pOut+=BpL;
|
||||
}
|
||||
|
||||
#undef BPP
|
||||
#undef BPP2
|
||||
#undef BPP3
|
||||
#undef Diff
|
||||
#undef hq4x_Interp1
|
||||
#undef hq4x_Interp2
|
||||
#undef hq4x_Interp3
|
||||
#undef hq4x_Interp4
|
||||
#undef hq4x_Interp5
|
||||
#undef hq4x_Interp6
|
||||
#undef hq4x_Interp7
|
||||
#undef hq4x_Interp8
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
void hq4x_init(void)
|
||||
{
|
||||
static int done = 0;
|
||||
int r, g, b, Y, u, v, i, j, k;
|
||||
|
||||
if (done ) return;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
for (k = 0; k < 16; k++) {
|
||||
r = (i << 4) | i;
|
||||
g = (j << 4) | j;
|
||||
b = (k << 4) | k;
|
||||
|
||||
/* Microsoft's RGB888->YUV conversion */
|
||||
/*Y = ((( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16) & 0xFF;
|
||||
u = ((( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128) & 0xFF;
|
||||
v = ((( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128) & 0xFF;*/
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = 128 + ((r - b) >> 2);
|
||||
v = 128 + ((-r + 2*g -b)>>3);
|
||||
|
||||
RGB444toYUV[(i << 8) | (j << 4) | k] = (Y << 16) | (u << 8) | v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done = 1;
|
||||
}
|
||||
#endif /* !_16BPP_HACK */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef __MSC__
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <zlib.h>
|
||||
#include "TxCache.h"
|
||||
#include "TxDbg.h"
|
||||
#include "../Glide64/m64p.h"
|
||||
#include "../Glide64/Gfx_1.3.h"
|
||||
|
||||
TxCache::~TxCache()
|
||||
{
|
||||
/* free memory, clean up, etc */
|
||||
clear();
|
||||
|
||||
delete _txUtil;
|
||||
}
|
||||
|
||||
TxCache::TxCache(int options, int cachesize, const wchar_t *datapath,
|
||||
const wchar_t *cachepath, const wchar_t *ident,
|
||||
dispInfoFuncExt callback)
|
||||
{
|
||||
_txUtil = new TxUtil();
|
||||
|
||||
_options = options;
|
||||
_cacheSize = cachesize;
|
||||
_callback = callback;
|
||||
_totalSize = 0;
|
||||
|
||||
/* save path name */
|
||||
if (datapath)
|
||||
_datapath.assign(datapath);
|
||||
if (cachepath)
|
||||
_cachepath.assign(cachepath);
|
||||
|
||||
/* save ROM name */
|
||||
if (ident)
|
||||
_ident.assign(ident);
|
||||
|
||||
/* zlib memory buffers to (de)compress hires textures */
|
||||
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
||||
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
||||
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
||||
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
||||
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
||||
|
||||
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
||||
_options &= ~(GZ_TEXCACHE|GZ_HIRESTEXCACHE);
|
||||
_gzdest0 = NULL;
|
||||
_gzdest1 = NULL;
|
||||
_gzdestLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize)
|
||||
{
|
||||
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||
|
||||
if (!checksum || !info->data) return 0;
|
||||
|
||||
uint8 *dest = info->data;
|
||||
uint16 format = info->format;
|
||||
|
||||
if (!dataSize) {
|
||||
dataSize = _txUtil->sizeofTx(info->width, info->height, info->format);
|
||||
|
||||
if (!dataSize) return 0;
|
||||
|
||||
if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) {
|
||||
/* zlib compress it. compression level:1 (best speed) */
|
||||
uLongf destLen = _gzdestLen;
|
||||
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
||||
if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) {
|
||||
dest = info->data;
|
||||
DBG_INFO(80, L"Error: zlib compression failed!\n");
|
||||
} else {
|
||||
DBG_INFO(80, L"zlib compressed: %.02fkb->%.02fkb\n", (float)dataSize/1000, (float)destLen/1000);
|
||||
dataSize = destLen;
|
||||
format |= GR_TEXFMT_GZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if cache size exceeds limit, remove old cache */
|
||||
if (_cacheSize > 0) {
|
||||
_totalSize += dataSize;
|
||||
if ((_totalSize > _cacheSize) && !_cachelist.empty()) {
|
||||
/* _cachelist is arranged so that frequently used textures are in the back */
|
||||
std::list<uint64>::iterator itList = _cachelist.begin();
|
||||
while (itList != _cachelist.end()) {
|
||||
/* find it in _cache */
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList);
|
||||
if (itMap != _cache.end()) {
|
||||
/* yep we have it. remove it. */
|
||||
_totalSize -= (*itMap).second->size;
|
||||
free((*itMap).second->info.data);
|
||||
delete (*itMap).second;
|
||||
_cache.erase(itMap);
|
||||
}
|
||||
itList++;
|
||||
|
||||
/* check if memory cache has enough space */
|
||||
if (_totalSize <= _cacheSize)
|
||||
break;
|
||||
}
|
||||
/* remove from _cachelist */
|
||||
_cachelist.erase(_cachelist.begin(), itList);
|
||||
|
||||
DBG_INFO(80, L"+++++++++\n");
|
||||
}
|
||||
_totalSize -= dataSize;
|
||||
}
|
||||
|
||||
/* cache it */
|
||||
uint8 *tmpdata = (uint8*)malloc(dataSize);
|
||||
if (tmpdata) {
|
||||
TXCACHE *txCache = new TXCACHE;
|
||||
if (txCache) {
|
||||
/* we can directly write as we filter, but for now we get away
|
||||
* with doing memcpy after all the filtering is done.
|
||||
*/
|
||||
memcpy(tmpdata, dest, dataSize);
|
||||
|
||||
/* copy it */
|
||||
memcpy(&txCache->info, info, sizeof(GHQTexInfo));
|
||||
txCache->info.data = tmpdata;
|
||||
txCache->info.format = format;
|
||||
txCache->size = dataSize;
|
||||
|
||||
/* add to cache */
|
||||
if (_cacheSize > 0) {
|
||||
_cachelist.push_back(checksum);
|
||||
txCache->it = --(_cachelist.end());
|
||||
}
|
||||
/* _cache[checksum] = txCache; */
|
||||
_cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache));
|
||||
|
||||
#ifdef DEBUG
|
||||
DBG_INFO(80, L"[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n",
|
||||
_cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff),
|
||||
info->width, info->height, info->format, (float)_totalSize/1000000);
|
||||
|
||||
DBG_INFO(80, L"smalllodlog2:%d largelodlog2:%d aspectratiolog2:%d\n",
|
||||
txCache->info.smallLodLog2, txCache->info.largeLodLog2, txCache->info.aspectRatioLog2);
|
||||
|
||||
if (info->tiles) {
|
||||
DBG_INFO(80, L"tiles:%d un-tiled size:%d x %d\n", info->tiles, info->untiled_width, info->untiled_height);
|
||||
}
|
||||
|
||||
if (_cacheSize > 0) {
|
||||
DBG_INFO(80, L"cache max config:%.02fmb\n", (float)_cacheSize/1000000);
|
||||
|
||||
if (_cache.size() != _cachelist.size()) {
|
||||
DBG_INFO(80, L"Error: cache/cachelist mismatch! (%d/%d)\n", _cache.size(), _cachelist.size());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* total cache size */
|
||||
_totalSize += dataSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
free(tmpdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::get(uint64 checksum, GHQTexInfo *info)
|
||||
{
|
||||
if (!checksum || _cache.empty()) return 0;
|
||||
|
||||
/* find a match in cache */
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||
if (itMap != _cache.end()) {
|
||||
/* yep, we've got it. */
|
||||
memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo));
|
||||
|
||||
/* push it to the back of the list */
|
||||
if (_cacheSize > 0) {
|
||||
_cachelist.erase(((*itMap).second)->it);
|
||||
_cachelist.push_back(checksum);
|
||||
((*itMap).second)->it = --(_cachelist.end());
|
||||
}
|
||||
|
||||
/* zlib decompress it */
|
||||
if (info->format & GR_TEXFMT_GZ) {
|
||||
uLongf destLen = _gzdestLen;
|
||||
uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0;
|
||||
if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) {
|
||||
DBG_INFO(80, L"Error: zlib decompression failed!\n");
|
||||
return 0;
|
||||
}
|
||||
info->data = dest;
|
||||
info->format &= ~GR_TEXFMT_GZ;
|
||||
DBG_INFO(80, L"zlib decompressed: %.02fkb->%.02fkb\n", (float)(((*itMap).second)->size)/1000, (float)destLen/1000);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||
{
|
||||
if (!_cache.empty()) {
|
||||
/* dump cache to disk */
|
||||
char cbuf[MAX_PATH];
|
||||
|
||||
boost::filesystem::wpath cachepath(path);
|
||||
boost::filesystem::create_directory(cachepath);
|
||||
|
||||
/* Ugly hack to enable fopen/gzopen in Win9x */
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
wchar_t curpath[MAX_PATH];
|
||||
GETCWD(MAX_PATH, curpath);
|
||||
CHDIR(cachepath.wstring().c_str());
|
||||
#else
|
||||
char curpath[MAX_PATH];
|
||||
wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH);
|
||||
if (GETCWD(MAX_PATH, curpath) == NULL)
|
||||
ERRLOG("Error while retrieving working directory!");
|
||||
if (CHDIR(cbuf) != 0)
|
||||
ERRLOG("Error while changing current directory to '%s'!", cbuf);
|
||||
#endif
|
||||
|
||||
wcstombs(cbuf, filename, MAX_PATH);
|
||||
|
||||
gzFile gzfp = gzopen(cbuf, "wb1");
|
||||
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||
if (gzfp) {
|
||||
/* write header to determine config match */
|
||||
gzwrite(gzfp, &config, 4);
|
||||
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||
while (itMap != _cache.end()) {
|
||||
uint8 *dest = (*itMap).second->info.data;
|
||||
uint32 destLen = (*itMap).second->size;
|
||||
uint16 format = (*itMap).second->info.format;
|
||||
|
||||
/* to keep things simple, we save the texture data in a zlib uncompressed state. */
|
||||
/* sigh... for those who cannot wait the extra few seconds. changed to keep
|
||||
* texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE
|
||||
* option is toggled, the cache will need to be rebuilt.
|
||||
*/
|
||||
/*if (format & GR_TEXFMT_GZ) {
|
||||
dest = _gzdest0;
|
||||
destLen = _gzdestLen;
|
||||
if (dest && destLen) {
|
||||
if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) {
|
||||
dest = NULL;
|
||||
destLen = 0;
|
||||
}
|
||||
format &= ~GR_TEXFMT_GZ;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (dest && destLen) {
|
||||
/* texture checksum */
|
||||
gzwrite(gzfp, &((*itMap).first), 8);
|
||||
|
||||
/* other texture info */
|
||||
gzwrite(gzfp, &((*itMap).second->info.width), 4);
|
||||
gzwrite(gzfp, &((*itMap).second->info.height), 4);
|
||||
gzwrite(gzfp, &format, 2);
|
||||
|
||||
gzwrite(gzfp, &((*itMap).second->info.smallLodLog2), 4);
|
||||
gzwrite(gzfp, &((*itMap).second->info.largeLodLog2), 4);
|
||||
gzwrite(gzfp, &((*itMap).second->info.aspectRatioLog2), 4);
|
||||
|
||||
gzwrite(gzfp, &((*itMap).second->info.tiles), 4);
|
||||
gzwrite(gzfp, &((*itMap).second->info.untiled_width), 4);
|
||||
gzwrite(gzfp, &((*itMap).second->info.untiled_height), 4);
|
||||
|
||||
gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1);
|
||||
|
||||
gzwrite(gzfp, &destLen, 4);
|
||||
gzwrite(gzfp, dest, destLen);
|
||||
}
|
||||
|
||||
itMap++;
|
||||
|
||||
/* not ready yet */
|
||||
/*if (_callback)
|
||||
(*_callback)(L"Total textures saved to HDD: %d\n", std::distance(itMap, _cache.begin()));*/
|
||||
}
|
||||
gzclose(gzfp);
|
||||
}
|
||||
|
||||
if (CHDIR(curpath) != 0)
|
||||
ERRLOG("Error while changing current directory back to original path of '%s'!", curpath);
|
||||
}
|
||||
|
||||
return _cache.empty();
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::load(const wchar_t *path, const wchar_t *filename, int config)
|
||||
{
|
||||
/* find it on disk */
|
||||
char cbuf[MAX_PATH];
|
||||
|
||||
boost::filesystem::wpath cachepath(path);
|
||||
|
||||
#ifdef BOOST_WINDOWS_API
|
||||
wchar_t curpath[MAX_PATH];
|
||||
GETCWD(MAX_PATH, curpath);
|
||||
CHDIR(cachepath.wstring().c_str());
|
||||
#else
|
||||
char curpath[MAX_PATH];
|
||||
wcstombs(cbuf, cachepath.wstring().c_str(), MAX_PATH);
|
||||
if (GETCWD(MAX_PATH, curpath) == NULL)
|
||||
ERRLOG("Error while retrieving working directory!");
|
||||
if (CHDIR(cbuf) != 0)
|
||||
ERRLOG("Error while changing current directory to '%s'!", cbuf);
|
||||
#endif
|
||||
|
||||
wcstombs(cbuf, filename, MAX_PATH);
|
||||
|
||||
gzFile gzfp = gzopen(cbuf, "rb");
|
||||
DBG_INFO(80, L"gzfp:%x file:%ls\n", gzfp, filename);
|
||||
if (gzfp) {
|
||||
/* yep, we have it. load it into memory cache. */
|
||||
int dataSize;
|
||||
uint64 checksum;
|
||||
GHQTexInfo tmpInfo;
|
||||
int tmpconfig;
|
||||
/* read header to determine config match */
|
||||
gzread(gzfp, &tmpconfig, 4);
|
||||
|
||||
if (tmpconfig == config) {
|
||||
do {
|
||||
memset(&tmpInfo, 0, sizeof(GHQTexInfo));
|
||||
|
||||
gzread(gzfp, &checksum, 8);
|
||||
|
||||
gzread(gzfp, &tmpInfo.width, 4);
|
||||
gzread(gzfp, &tmpInfo.height, 4);
|
||||
gzread(gzfp, &tmpInfo.format, 2);
|
||||
|
||||
gzread(gzfp, &tmpInfo.smallLodLog2, 4);
|
||||
gzread(gzfp, &tmpInfo.largeLodLog2, 4);
|
||||
gzread(gzfp, &tmpInfo.aspectRatioLog2, 4);
|
||||
|
||||
gzread(gzfp, &tmpInfo.tiles, 4);
|
||||
gzread(gzfp, &tmpInfo.untiled_width, 4);
|
||||
gzread(gzfp, &tmpInfo.untiled_height, 4);
|
||||
|
||||
gzread(gzfp, &tmpInfo.is_hires_tex, 1);
|
||||
|
||||
gzread(gzfp, &dataSize, 4);
|
||||
|
||||
tmpInfo.data = (uint8*)malloc(dataSize);
|
||||
if (tmpInfo.data) {
|
||||
gzread(gzfp, tmpInfo.data, dataSize);
|
||||
|
||||
/* add to memory cache */
|
||||
add(checksum, &tmpInfo, (tmpInfo.format & GR_TEXFMT_GZ) ? dataSize : 0);
|
||||
|
||||
free(tmpInfo.data);
|
||||
} else {
|
||||
gzseek(gzfp, dataSize, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* skip in between to prevent the loop from being tied down to vsync */
|
||||
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
||||
(*_callback)(L"[%d] total mem:%.02fmb - %ls\n", _cache.size(), (float)_totalSize/1000000, filename);
|
||||
|
||||
} while (!gzeof(gzfp));
|
||||
gzclose(gzfp);
|
||||
} else {
|
||||
if ((tmpconfig & HIRESTEXTURES_MASK) != (config & HIRESTEXTURES_MASK)) {
|
||||
const char *conf_str;
|
||||
if ((tmpconfig & HIRESTEXTURES_MASK) == NO_HIRESTEXTURES)
|
||||
conf_str = "0";
|
||||
else if ((tmpconfig & HIRESTEXTURES_MASK) == RICE_HIRESTEXTURES)
|
||||
conf_str = "1";
|
||||
else
|
||||
conf_str = "set to an unsupported format";
|
||||
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_hirs must be %s", conf_str);
|
||||
}
|
||||
if ((tmpconfig & COMPRESS_HIRESTEX) != (config & COMPRESS_HIRESTEX))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_hirs_cmpr must be %s", (tmpconfig & COMPRESS_HIRESTEX) ? "True" : "False");
|
||||
if ((tmpconfig & COMPRESSION_MASK) != (config & COMPRESSION_MASK) && (tmpconfig & COMPRESS_HIRESTEX)) {
|
||||
const char *conf_str;
|
||||
if ((tmpconfig & COMPRESSION_MASK) == FXT1_COMPRESSION)
|
||||
conf_str = "1";
|
||||
else if ((tmpconfig & COMPRESSION_MASK) == S3TC_COMPRESSION)
|
||||
conf_str = "0";
|
||||
else
|
||||
conf_str = "set to an unsupported format";
|
||||
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_cmpr must be %s", conf_str);
|
||||
}
|
||||
if ((tmpconfig & TILE_HIRESTEX) != (config & TILE_HIRESTEX))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_hirs_tile must be %s", (tmpconfig & TILE_HIRESTEX) ? "True" : "False");
|
||||
if ((tmpconfig & FORCE16BPP_HIRESTEX) != (config & FORCE16BPP_HIRESTEX))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_hirs_f16bpp must be %s", (tmpconfig & FORCE16BPP_HIRESTEX) ? "True" : "False");
|
||||
if ((tmpconfig & GZ_HIRESTEXCACHE) != (config & GZ_HIRESTEXCACHE))
|
||||
WriteLog(M64MSG_WARNING, "ghq_hirs_gz must be %s", (tmpconfig & GZ_HIRESTEXCACHE) ? "True" : "False");
|
||||
if ((tmpconfig & LET_TEXARTISTS_FLY) != (config & LET_TEXARTISTS_FLY))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_hirs_let_texartists_fly must be %s", (tmpconfig & LET_TEXARTISTS_FLY) ? "True" : "False");
|
||||
|
||||
if ((tmpconfig & FILTER_MASK) != (config & FILTER_MASK)) {
|
||||
const char *conf_str;
|
||||
if ((tmpconfig & FILTER_MASK) == NO_FILTER)
|
||||
conf_str = "0";
|
||||
else if ((tmpconfig & FILTER_MASK) == SMOOTH_FILTER_1)
|
||||
conf_str = "1";
|
||||
else if ((tmpconfig & FILTER_MASK) == SMOOTH_FILTER_2)
|
||||
conf_str = "2";
|
||||
else if ((tmpconfig & FILTER_MASK) == SMOOTH_FILTER_3)
|
||||
conf_str = "3";
|
||||
else if ((tmpconfig & FILTER_MASK) == SMOOTH_FILTER_4)
|
||||
conf_str = "4";
|
||||
else if ((tmpconfig & FILTER_MASK) == SHARP_FILTER_1)
|
||||
conf_str = "5";
|
||||
else if ((tmpconfig & FILTER_MASK) == SHARP_FILTER_2)
|
||||
conf_str = "6";
|
||||
else
|
||||
conf_str = "set to an unsupported format";
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_fltr must be %s", conf_str);
|
||||
}
|
||||
|
||||
if ((tmpconfig & ENHANCEMENT_MASK) != (config & ENHANCEMENT_MASK)) {
|
||||
const char *conf_str;
|
||||
if ((tmpconfig & ENHANCEMENT_MASK) == NO_ENHANCEMENT)
|
||||
conf_str = "0";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == X2_ENHANCEMENT)
|
||||
conf_str = "2";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == X2SAI_ENHANCEMENT)
|
||||
conf_str = "3";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == HQ2X_ENHANCEMENT)
|
||||
conf_str = "4";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == HQ2XS_ENHANCEMENT)
|
||||
conf_str = "5";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == LQ2X_ENHANCEMENT)
|
||||
conf_str = "6";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == LQ2XS_ENHANCEMENT)
|
||||
conf_str = "7";
|
||||
else if ((tmpconfig & ENHANCEMENT_MASK) == HQ4X_ENHANCEMENT)
|
||||
conf_str = "8";
|
||||
else
|
||||
conf_str = "set to an unsupported format";
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_enht must be %s", conf_str);
|
||||
}
|
||||
|
||||
if ((tmpconfig & COMPRESS_TEX) != (config & COMPRESS_TEX))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_enht_cmpr must be %s", (tmpconfig & COMPRESS_TEX) ? "True" : "False");
|
||||
if ((tmpconfig & FORCE16BPP_TEX) != (config & FORCE16BPP_TEX))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_enht_f16bpp must be %s", (tmpconfig & FORCE16BPP_TEX) ? "True" : "False");
|
||||
if ((tmpconfig & GZ_TEXCACHE) != (config & GZ_TEXCACHE))
|
||||
WriteLog(M64MSG_WARNING, "Ignored texture cache due to incompatible setting: ghq_enht_gz must be %s", (tmpconfig & GZ_TEXCACHE) ? "True" : "False");
|
||||
}
|
||||
}
|
||||
|
||||
if (CHDIR(curpath) != 0)
|
||||
ERRLOG("Error while changing current directory back to original path of '%s'!", curpath);
|
||||
|
||||
return !_cache.empty();
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::del(uint64 checksum)
|
||||
{
|
||||
if (!checksum || _cache.empty()) return 0;
|
||||
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||
if (itMap != _cache.end()) {
|
||||
|
||||
/* for texture cache (not hi-res cache) */
|
||||
if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it);
|
||||
|
||||
/* remove from cache */
|
||||
free((*itMap).second->info.data);
|
||||
_totalSize -= (*itMap).second->size;
|
||||
delete (*itMap).second;
|
||||
_cache.erase(itMap);
|
||||
|
||||
DBG_INFO(80, L"removed from cache: checksum = %08X %08X\n", (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxCache::is_cached(uint64 checksum)
|
||||
{
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum);
|
||||
if (itMap != _cache.end()) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TxCache::clear()
|
||||
{
|
||||
if (!_cache.empty()) {
|
||||
std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin();
|
||||
while (itMap != _cache.end()) {
|
||||
free((*itMap).second->info.data);
|
||||
delete (*itMap).second;
|
||||
itMap++;
|
||||
}
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
if (!_cachelist.empty()) _cachelist.clear();
|
||||
|
||||
_totalSize = 0;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXCACHE_H__
|
||||
#define __TXCACHE_H__
|
||||
|
||||
#include "TxInternal.h"
|
||||
#include "TxUtil.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class TxCache
|
||||
{
|
||||
private:
|
||||
std::list<uint64> _cachelist;
|
||||
uint8 *_gzdest0;
|
||||
uint8 *_gzdest1;
|
||||
uint32 _gzdestLen;
|
||||
protected:
|
||||
int _options;
|
||||
std::wstring _ident;
|
||||
std::wstring _datapath;
|
||||
std::wstring _cachepath;
|
||||
dispInfoFuncExt _callback;
|
||||
TxUtil *_txUtil;
|
||||
struct TXCACHE {
|
||||
int size;
|
||||
GHQTexInfo info;
|
||||
std::list<uint64>::iterator it;
|
||||
};
|
||||
int _totalSize;
|
||||
int _cacheSize;
|
||||
std::map<uint64, TXCACHE*> _cache;
|
||||
boolean save(const wchar_t *path, const wchar_t *filename, const int config);
|
||||
boolean load(const wchar_t *path, const wchar_t *filename, const int config);
|
||||
boolean del(uint64 checksum); /* checksum hi:palette low:texture */
|
||||
boolean is_cached(uint64 checksum); /* checksum hi:palette low:texture */
|
||||
void clear();
|
||||
public:
|
||||
~TxCache();
|
||||
TxCache(int options, int cachesize, const wchar_t *datapath,
|
||||
const wchar_t *cachepath, const wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
boolean add(uint64 checksum, /* checksum hi:palette low:texture */
|
||||
GHQTexInfo *info, int dataSize = 0);
|
||||
boolean get(uint64 checksum, /* checksum hi:palette low:texture */
|
||||
GHQTexInfo *info);
|
||||
};
|
||||
|
||||
#endif /* __TXCACHE_H__ */
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define DBG_LEVEL 80
|
||||
|
||||
#include "TxDbg.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
TxDbg::TxDbg()
|
||||
{
|
||||
_level = DBG_LEVEL;
|
||||
|
||||
if (!_dbgfile)
|
||||
#ifdef GHQCHK
|
||||
_dbgfile = fopen("ghqchk.txt", "w");
|
||||
#else
|
||||
_dbgfile = fopen("glidehq.dbg", "w");
|
||||
#endif
|
||||
}
|
||||
|
||||
TxDbg::~TxDbg()
|
||||
{
|
||||
if (_dbgfile) {
|
||||
fclose(_dbgfile);
|
||||
_dbgfile = 0;
|
||||
}
|
||||
|
||||
_level = DBG_LEVEL;
|
||||
}
|
||||
|
||||
void
|
||||
TxDbg::output(const int level, const wchar_t *format, ...)
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
|
||||
wchar_t newformat[4095];
|
||||
#else
|
||||
std::wstring newformat;
|
||||
#endif
|
||||
|
||||
va_list args;
|
||||
|
||||
if (level > _level)
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
#ifdef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
|
||||
swprintf(newformat, L"%d:\t", level);
|
||||
wcscat(newformat, format);
|
||||
vfwprintf(_dbgfile, newformat, args);
|
||||
#else
|
||||
newformat = std::to_wstring(level) + L":\t" + format;
|
||||
vfwprintf(_dbgfile, newformat.c_str(), args);
|
||||
#endif
|
||||
fflush(_dbgfile);
|
||||
#ifdef GHQCHK
|
||||
//vwprintf(newformat, args);
|
||||
vwprintf(newformat.c_str(), args);
|
||||
#endif
|
||||
va_end(args);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXDBG_H__
|
||||
#define __TXDBG_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include "TxInternal.h"
|
||||
|
||||
class TxDbg
|
||||
{
|
||||
private:
|
||||
FILE* _dbgfile;
|
||||
int _level;
|
||||
TxDbg();
|
||||
public:
|
||||
static TxDbg* getInstance() {
|
||||
static TxDbg txDbg;
|
||||
return &txDbg;
|
||||
}
|
||||
~TxDbg();
|
||||
void output(const int level, const wchar_t *format, ...);
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG_INFO(...) TxDbg::getInstance()->output(__VA_ARGS__)
|
||||
#define INFO(...) DBG_INFO(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_INFO(...)
|
||||
#ifdef GHQCHK
|
||||
#define INFO(...) TxDbg::getInstance()->output(__VA_ARGS__)
|
||||
#else
|
||||
#if 0 /* XXX enable this to log basic hires texture checks */
|
||||
#define INFO(...) TxDbg::getInstance()->output(__VA_ARGS__)
|
||||
#else
|
||||
#define INFO(...) DBG_INFO(__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __TXDBG_H__ */
|
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef __MSC__
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
#include "TxFilter.h"
|
||||
#include "TextureFilters.h"
|
||||
#include "TxDbg.h"
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
void TxFilter::clear()
|
||||
{
|
||||
/* clear hires texture cache */
|
||||
delete _txHiResCache;
|
||||
_txHiResCache = NULL;
|
||||
|
||||
/* clear texture cache */
|
||||
delete _txTexCache;
|
||||
_txTexCache = NULL;
|
||||
|
||||
/* free memory */
|
||||
TxMemBuf::getInstance()->shutdown();
|
||||
|
||||
/* clear other stuff */
|
||||
delete _txImage;
|
||||
_txImage = NULL;
|
||||
delete _txQuantize;
|
||||
_txQuantize = NULL;
|
||||
delete _txUtil;
|
||||
_txUtil = NULL;
|
||||
}
|
||||
|
||||
TxFilter::~TxFilter()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
TxFilter::TxFilter(int maxwidth, int maxheight, int maxbpp, int options,
|
||||
int cachesize, wchar_t *datapath, wchar_t *cachepath,
|
||||
wchar_t *ident, dispInfoFuncExt callback) :
|
||||
_numcore(1), _tex1(NULL), _tex2(NULL), _maxwidth(0), _maxheight(0),
|
||||
_maxbpp(0), _options(0), _cacheSize(0), _ident(), _datapath(), _cachepath(),
|
||||
_txQuantize(NULL), _txTexCache(NULL), _txHiResCache(NULL), _txUtil(NULL),
|
||||
_txImage(NULL), _initialized(false)
|
||||
{
|
||||
clear(); /* gcc does not allow the destructor to be called */
|
||||
|
||||
/* shamelessness :P this first call to the debug output message creates
|
||||
* a file in the executable directory. */
|
||||
INFO(0, L"------------------------------------------------------------------\n");
|
||||
#ifdef GHQCHK
|
||||
INFO(0, L" GlideHQ Hires Texture Checker 1.02.00.%d\n", 0);
|
||||
#else
|
||||
INFO(0, L" GlideHQ version 1.02.00.%d\n", 0);
|
||||
#endif
|
||||
INFO(0, L" Copyright (C) 2010 Hiroshi Morii All Rights Reserved\n");
|
||||
INFO(0, L" email : koolsmoky(at)users.sourceforge.net\n");
|
||||
INFO(0, L" website : http://www.3dfxzone.it/koolsmoky\n");
|
||||
INFO(0, L"\n");
|
||||
INFO(0, L" Glide64 official website : http://glide64.emuxhaven.net\n");
|
||||
INFO(0, L"------------------------------------------------------------------\n");
|
||||
|
||||
_options = options;
|
||||
|
||||
_txImage = new TxImage();
|
||||
_txQuantize = new TxQuantize();
|
||||
_txUtil = new TxUtil();
|
||||
|
||||
/* get number of CPU cores. */
|
||||
_numcore = _txUtil->getNumberofProcessors();
|
||||
|
||||
_initialized = 0;
|
||||
|
||||
_tex1 = NULL;
|
||||
_tex2 = NULL;
|
||||
|
||||
/* XXX: anything larger than 1024 * 1024 is overkill */
|
||||
_maxwidth = maxwidth > 1024 ? 1024 : maxwidth;
|
||||
_maxheight = maxheight > 1024 ? 1024 : maxheight;
|
||||
_maxbpp = maxbpp;
|
||||
|
||||
_cacheSize = cachesize;
|
||||
|
||||
/* TODO: validate options and do overrides here*/
|
||||
|
||||
/* save path name */
|
||||
if (datapath)
|
||||
_datapath.assign(datapath);
|
||||
if (cachepath)
|
||||
_cachepath.assign(cachepath);
|
||||
|
||||
/* save ROM name */
|
||||
if (ident && wcscmp(ident, L"DEFAULT") != 0)
|
||||
_ident.assign(ident);
|
||||
|
||||
/* check for dxtn extensions */
|
||||
if (!TxLoadLib::getInstance()->getdxtCompressTexFuncExt())
|
||||
_options &= ~S3TC_COMPRESSION;
|
||||
|
||||
if (!TxLoadLib::getInstance()->getfxtCompressTexFuncExt())
|
||||
_options &= ~FXT1_COMPRESSION;
|
||||
|
||||
switch (options & COMPRESSION_MASK) {
|
||||
case FXT1_COMPRESSION:
|
||||
case S3TC_COMPRESSION:
|
||||
break;
|
||||
case NCC_COMPRESSION:
|
||||
default:
|
||||
_options &= ~COMPRESSION_MASK;
|
||||
}
|
||||
|
||||
if (TxMemBuf::getInstance()->init(_maxwidth, _maxheight)) {
|
||||
if (!_tex1)
|
||||
_tex1 = TxMemBuf::getInstance()->get(0);
|
||||
|
||||
if (!_tex2)
|
||||
_tex2 = TxMemBuf::getInstance()->get(1);
|
||||
}
|
||||
|
||||
#if !_16BPP_HACK
|
||||
/* initialize hq4x filter */
|
||||
hq4x_init();
|
||||
#endif
|
||||
|
||||
/* initialize texture cache in bytes. 128Mb will do nicely in most cases */
|
||||
_txTexCache = new TxTexCache(_options, _cacheSize, _datapath.c_str(), _cachepath.c_str(), _ident.c_str(), callback);
|
||||
|
||||
/* hires texture */
|
||||
#if HIRES_TEXTURE
|
||||
_txHiResCache = new TxHiResCache(_maxwidth, _maxheight, _maxbpp, _options, _datapath.c_str(), _cachepath.c_str(), _ident.c_str(), callback);
|
||||
|
||||
if (_txHiResCache->empty())
|
||||
_options &= ~HIRESTEXTURES_MASK;
|
||||
#endif
|
||||
|
||||
if (!(_options & COMPRESS_TEX))
|
||||
_options &= ~COMPRESSION_MASK;
|
||||
|
||||
if (_tex1 && _tex2)
|
||||
_initialized = 1;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxFilter::filter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat, uint64 g64crc, GHQTexInfo *info)
|
||||
{
|
||||
uint8 *texture = src;
|
||||
uint8 *tmptex = _tex1;
|
||||
uint16 destformat = srcformat;
|
||||
|
||||
/* We need to be initialized first! */
|
||||
if (!_initialized) return 0;
|
||||
|
||||
/* find cached textures */
|
||||
if (_cacheSize) {
|
||||
|
||||
/* calculate checksum of source texture */
|
||||
if (!g64crc)
|
||||
g64crc = (uint64)(_txUtil->checksumTx(texture, srcwidth, srcheight, srcformat));
|
||||
|
||||
DBG_INFO(80, L"filter: crc:%08X %08X %d x %d gfmt:%x\n",
|
||||
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff), srcwidth, srcheight, srcformat);
|
||||
|
||||
#if 0 /* use hirestex to retrieve cached textures. */
|
||||
/* check if we have it in cache */
|
||||
if (!(g64crc & 0xffffffff00000000) && /* we reach here only when there is no hires texture for this crc */
|
||||
_txTexCache->get(g64crc, info)) {
|
||||
DBG_INFO(80, L"cache hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||
return 1; /* yep, we've got it */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Leave small textures alone because filtering makes little difference.
|
||||
* Moreover, some filters require at least 4 * 4 to work.
|
||||
* Bypass _options to do ARGB8888->16bpp if _maxbpp=16 or forced color reduction.
|
||||
*/
|
||||
if ((srcwidth >= 4 && srcheight >= 4) &&
|
||||
((_options & (FILTER_MASK|ENHANCEMENT_MASK|COMPRESSION_MASK)) ||
|
||||
(srcformat == GR_TEXFMT_ARGB_8888 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)))) {
|
||||
|
||||
#if !_16BPP_HACK
|
||||
/* convert textures to a format that the compressor accepts (ARGB8888) */
|
||||
if (_options & COMPRESSION_MASK) {
|
||||
#endif
|
||||
if (srcformat != GR_TEXFMT_ARGB_8888) {
|
||||
if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, srcformat, GR_TEXFMT_ARGB_8888)) {
|
||||
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", srcformat);
|
||||
return 0;
|
||||
}
|
||||
texture = tmptex;
|
||||
destformat = GR_TEXFMT_ARGB_8888;
|
||||
}
|
||||
#if !_16BPP_HACK
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (destformat) {
|
||||
case GR_TEXFMT_ARGB_8888:
|
||||
|
||||
/*
|
||||
* prepare texture enhancements (x2, x4 scalers)
|
||||
*/
|
||||
int scale_shift = 0, num_filters = 0;
|
||||
uint32 filter = 0;
|
||||
|
||||
if ((_options & ENHANCEMENT_MASK) == HQ4X_ENHANCEMENT) {
|
||||
if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) {
|
||||
filter |= HQ4X_ENHANCEMENT;
|
||||
scale_shift = 2;
|
||||
num_filters++;
|
||||
} else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
filter |= HQ2X_ENHANCEMENT;
|
||||
scale_shift = 1;
|
||||
num_filters++;
|
||||
}
|
||||
} else if (_options & ENHANCEMENT_MASK) {
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
filter |= (_options & ENHANCEMENT_MASK);
|
||||
scale_shift = 1;
|
||||
num_filters++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare texture filters
|
||||
*/
|
||||
if (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK)) {
|
||||
filter |= (_options & (SMOOTH_FILTER_MASK|SHARP_FILTER_MASK));
|
||||
num_filters++;
|
||||
}
|
||||
|
||||
/*
|
||||
* execute texture enhancements and filters
|
||||
*/
|
||||
while (num_filters > 0) {
|
||||
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
|
||||
uint8 *_texture = texture;
|
||||
uint8 *_tmptex = tmptex;
|
||||
|
||||
#if !defined(NO_FILTER_THREAD)
|
||||
unsigned int numcore = _numcore;
|
||||
unsigned int blkrow = 0;
|
||||
while (numcore > 1 && blkrow == 0) {
|
||||
blkrow = (srcheight >> 2) / numcore;
|
||||
numcore--;
|
||||
}
|
||||
if (blkrow > 0 && numcore > 1) {
|
||||
std::thread *thrd[MAX_NUMCORE];
|
||||
unsigned int i;
|
||||
int blkheight = blkrow << 2;
|
||||
unsigned int srcStride = (srcwidth * blkheight) << 2;
|
||||
unsigned int destStride = srcStride << scale_shift << scale_shift;
|
||||
for (i = 0; i < numcore - 1; i++) {
|
||||
thrd[i] = new std::thread(std::bind(filter_8888,
|
||||
(uint32*)_texture,
|
||||
srcwidth,
|
||||
blkheight,
|
||||
(uint32*)_tmptex,
|
||||
filter));
|
||||
_texture += srcStride;
|
||||
_tmptex += destStride;
|
||||
}
|
||||
thrd[i] = new std::thread(std::bind(filter_8888,
|
||||
(uint32*)_texture,
|
||||
srcwidth,
|
||||
srcheight - blkheight * i,
|
||||
(uint32*)_tmptex,
|
||||
filter));
|
||||
for (i = 0; i < numcore; i++) {
|
||||
thrd[i]->join();
|
||||
delete thrd[i];
|
||||
}
|
||||
} else {
|
||||
filter_8888((uint32*)_texture, srcwidth, srcheight, (uint32*)_tmptex, filter);
|
||||
}
|
||||
#else
|
||||
filter_8888((uint32*)_texture, srcwidth, srcheight, (uint32*)_tmptex, filter);
|
||||
#endif
|
||||
|
||||
if (filter & ENHANCEMENT_MASK) {
|
||||
srcwidth <<= scale_shift;
|
||||
srcheight <<= scale_shift;
|
||||
filter &= ~ENHANCEMENT_MASK;
|
||||
scale_shift = 0;
|
||||
}
|
||||
|
||||
texture = tmptex;
|
||||
num_filters--;
|
||||
}
|
||||
|
||||
/*
|
||||
* texture compression
|
||||
*/
|
||||
/* ignored if we only have texture compression option on.
|
||||
* only done when texture enhancer is used. see constructor. */
|
||||
if ((_options & COMPRESSION_MASK) &&
|
||||
(srcwidth >= 64 && srcheight >= 64) /* Texture compression is not suitable for low pixel coarse detail
|
||||
* textures. The assumption here is that textures larger than 64x64
|
||||
* have enough detail to produce decent quality when compressed. The
|
||||
* down side is that narrow stripped textures that the N64 often use
|
||||
* for large background textures are also ignored. It would be more
|
||||
* reasonable if decisions are made based on fourier-transform
|
||||
* spectrum or RMS error.
|
||||
*/
|
||||
) {
|
||||
int compressionType = _options & COMPRESSION_MASK;
|
||||
int tmpwidth, tmpheight;
|
||||
uint16 tmpformat;
|
||||
/* XXX: textures that use 8bit alpha channel look bad with the current
|
||||
* fxt1 library, so we substitute it with dxtn for now. afaik all gfx
|
||||
* cards that support fxt1 also support dxtn. (3dfx and Intel) */
|
||||
if ((destformat == GR_TEXFMT_ALPHA_INTENSITY_88) ||
|
||||
(destformat == GR_TEXFMT_ARGB_8888) ||
|
||||
(destformat == GR_TEXFMT_ALPHA_8)) {
|
||||
compressionType = S3TC_COMPRESSION;
|
||||
}
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
if (_txQuantize->compress(texture, tmptex,
|
||||
srcwidth, srcheight, srcformat,
|
||||
&tmpwidth, &tmpheight, &tmpformat,
|
||||
compressionType)) {
|
||||
srcwidth = tmpwidth;
|
||||
srcheight = tmpheight;
|
||||
destformat = tmpformat;
|
||||
texture = tmptex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* texture (re)conversions
|
||||
*/
|
||||
if (destformat == GR_TEXFMT_ARGB_8888) {
|
||||
if (srcformat == GR_TEXFMT_ARGB_8888 && (_maxbpp < 32 || _options & FORCE16BPP_TEX)) srcformat = GR_TEXFMT_ARGB_4444;
|
||||
if (srcformat != GR_TEXFMT_ARGB_8888) {
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
if (!_txQuantize->quantize(texture, tmptex, srcwidth, srcheight, GR_TEXFMT_ARGB_8888, srcformat)) {
|
||||
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", srcformat);
|
||||
return 0;
|
||||
}
|
||||
texture = tmptex;
|
||||
destformat = srcformat;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
#if !_16BPP_HACK
|
||||
case GR_TEXFMT_ARGB_4444:
|
||||
|
||||
int scale_shift = 0;
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
|
||||
switch (_options & ENHANCEMENT_MASK) {
|
||||
case HQ4X_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 2) && srcheight <= (_maxheight >> 2)) {
|
||||
hq4x_4444((uint8*)texture, (uint8*)tmptex, srcwidth, srcheight, srcwidth, srcwidth * 4 * 2);
|
||||
scale_shift = 2;
|
||||
}/* else if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}*/
|
||||
break;
|
||||
case HQ2X_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
hq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}
|
||||
break;
|
||||
case HQ2XS_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
hq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}
|
||||
break;
|
||||
case LQ2X_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
lq2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}
|
||||
break;
|
||||
case LQ2XS_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
lq2xS_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}
|
||||
break;
|
||||
case X2SAI_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
Super2xSaI_4444((uint16*)texture, (uint16*)tmptex, srcwidth, srcheight, srcwidth);
|
||||
scale_shift = 1;
|
||||
}
|
||||
break;
|
||||
case X2_ENHANCEMENT:
|
||||
if (srcwidth <= (_maxwidth >> 1) && srcheight <= (_maxheight >> 1)) {
|
||||
Texture2x_16((uint8*)texture, srcwidth * 2, (uint8*)tmptex, srcwidth * 2 * 2, srcwidth, srcheight);
|
||||
scale_shift = 1;
|
||||
}
|
||||
}
|
||||
if (scale_shift) {
|
||||
srcwidth <<= scale_shift;
|
||||
srcheight <<= scale_shift;
|
||||
texture = tmptex;
|
||||
}
|
||||
|
||||
if (_options & SMOOTH_FILTER_MASK) {
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
SmoothFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SMOOTH_FILTER_MASK));
|
||||
texture = tmptex;
|
||||
} else if (_options & SHARP_FILTER_MASK) {
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
SharpFilter_4444((uint16*)texture, srcwidth, srcheight, (uint16*)tmptex, (_options & SHARP_FILTER_MASK));
|
||||
texture = tmptex;
|
||||
}
|
||||
|
||||
break;
|
||||
case GR_TEXFMT_ARGB_1555:
|
||||
break;
|
||||
case GR_TEXFMT_RGB_565:
|
||||
break;
|
||||
case GR_TEXFMT_ALPHA_8:
|
||||
break;
|
||||
#endif /* _16BPP_HACK */
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in the texture info. */
|
||||
info->data = texture;
|
||||
info->width = srcwidth;
|
||||
info->height = srcheight;
|
||||
info->format = destformat;
|
||||
info->smallLodLog2 = _txUtil->grLodLog2(srcwidth, srcheight);
|
||||
info->largeLodLog2 = info->smallLodLog2;
|
||||
info->aspectRatioLog2 = _txUtil->grAspectRatioLog2(srcwidth, srcheight);
|
||||
info->is_hires_tex = 0;
|
||||
|
||||
/* cache the texture. */
|
||||
if (_cacheSize) _txTexCache->add(g64crc, info);
|
||||
|
||||
DBG_INFO(80, L"filtered texture: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxFilter::hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
||||
{
|
||||
/* NOTE: Rice CRC32 sometimes return the same value for different textures.
|
||||
* As a workaround, Glide64 CRC32 is used for the key for NON-hires
|
||||
* texture cache.
|
||||
*
|
||||
* r_crc64 = hi:palette low:texture
|
||||
* (separate crc. doesn't necessary have to be rice crc)
|
||||
* g64crc = texture + palette glide64 crc32
|
||||
* (can be any other crc if robust)
|
||||
*/
|
||||
|
||||
DBG_INFO(80, L"hirestex: r_crc64:%08X %08X, g64crc:%08X %08X\n",
|
||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff),
|
||||
(uint32)(g64crc >> 32), (uint32)(g64crc & 0xffffffff));
|
||||
|
||||
#if HIRES_TEXTURE
|
||||
/* check if we have it in hires memory cache. */
|
||||
if ((_options & HIRESTEXTURES_MASK) && r_crc64) {
|
||||
if (_txHiResCache->get(r_crc64, info)) {
|
||||
DBG_INFO(80, L"hires hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||
|
||||
/* TODO: Enable emulation for special N64 combiner modes. There are few ways
|
||||
* to get this done. Also applies for CI textures below.
|
||||
*
|
||||
* Solution 1. Load the hiresolution textures in ARGB8888 (or A8, IA88) format
|
||||
* to cache. When a cache is hit, then we take the modes passed in from Glide64
|
||||
* (also TODO) and apply the modification. Then we do color reduction or format
|
||||
* conversion or compression if desired and stuff it into the non-hires texture
|
||||
* cache.
|
||||
*
|
||||
* Solution 2. When a cache is hit and if the combiner modes are present,
|
||||
* convert the texture to ARGB4444 and pass it back to Glide64 to process.
|
||||
* If a texture is compressed, it needs to be decompressed first. Then add
|
||||
* the processed texture to the non-hires texture cache.
|
||||
*
|
||||
* Solution 3. Hybrid of the above 2. Load the textures in ARGB8888 (A8, IA88)
|
||||
* format. Convert the texture to ARGB4444 and pass it back to Glide64 when
|
||||
* the combiner modes are present. Get the processed texture back from Glide64
|
||||
* and compress if desired and add it to the non-hires texture cache.
|
||||
*
|
||||
* Solution 4. Take the easy way out and forget about this whole thing.
|
||||
*/
|
||||
|
||||
return 1; /* yep, got it */
|
||||
}
|
||||
if (_txHiResCache->get((r_crc64 & 0xffffffff), info)) {
|
||||
DBG_INFO(80, L"hires hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||
|
||||
/* for true CI textures, we use the passed in palette to convert to
|
||||
* ARGB1555 and add it to memory cache.
|
||||
*
|
||||
* NOTE: we do this AFTER all other texture cache searches because
|
||||
* only a few texture packs actually use true CI textures.
|
||||
*
|
||||
* NOTE: the pre-converted palette from Glide64 is in RGBA5551 format.
|
||||
* A comp comes before RGB comp.
|
||||
*/
|
||||
if (palette && info->format == GR_TEXFMT_P_8) {
|
||||
DBG_INFO(80, L"found GR_TEXFMT_P_8 format. Need conversion!!\n");
|
||||
|
||||
int width = info->width;
|
||||
int height = info->height;
|
||||
uint16 format = info->format;
|
||||
/* XXX: avoid collision with zlib compression buffer in TxHiResTexture::get */
|
||||
uint8 *texture = info->data;
|
||||
uint8 *tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
|
||||
/* use palette and convert to 16bit format */
|
||||
_txQuantize->P8_16BPP((uint32*)texture, (uint32*)tmptex, info->width, info->height, (uint32*)palette);
|
||||
texture = tmptex;
|
||||
format = GR_TEXFMT_ARGB_1555;
|
||||
|
||||
#if 1
|
||||
/* XXX: compressed if memory cache compression is ON */
|
||||
if (_options & COMPRESSION_MASK) {
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
if (_txQuantize->quantize(texture, tmptex, info->width, info->height, format, GR_TEXFMT_ARGB_8888)) {
|
||||
texture = tmptex;
|
||||
format = GR_TEXFMT_ARGB_8888;
|
||||
}
|
||||
if (format == GR_TEXFMT_ARGB_8888) {
|
||||
tmptex = (texture == _tex1) ? _tex2 : _tex1;
|
||||
if (_txQuantize->compress(texture, tmptex,
|
||||
info->width, info->height, GR_TEXFMT_ARGB_1555,
|
||||
&width, &height, &format,
|
||||
_options & COMPRESSION_MASK)) {
|
||||
texture = tmptex;
|
||||
} else {
|
||||
/*if (!_txQuantize->quantize(texture, tmptex, info->width, info->height, GR_TEXFMT_ARGB_8888, GR_TEXFMT_ARGB_1555)) {
|
||||
DBG_INFO(80, L"Error: unsupported format! gfmt:%x\n", format);
|
||||
return 0;
|
||||
}*/
|
||||
texture = tmptex;
|
||||
format = GR_TEXFMT_ARGB_1555;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* fill in the required info to return */
|
||||
info->data = texture;
|
||||
info->width = width;
|
||||
info->height = height;
|
||||
info->format = format;
|
||||
info->smallLodLog2 = _txUtil->grLodLog2(width, height);
|
||||
info->largeLodLog2 = info->smallLodLog2;
|
||||
info->aspectRatioLog2 = _txUtil->grAspectRatioLog2(width, height);
|
||||
info->is_hires_tex = 1;
|
||||
|
||||
/* XXX: add to hires texture cache!!! */
|
||||
_txHiResCache->add(r_crc64, info);
|
||||
|
||||
DBG_INFO(80, L"GR_TEXFMT_P_8 loaded as gfmt:%x!\n", format);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check if we have it in memory cache */
|
||||
if (_cacheSize && g64crc) {
|
||||
if (_txTexCache->get(g64crc, info)) {
|
||||
DBG_INFO(80, L"cache hit: %d x %d gfmt:%x\n", info->width, info->height, info->format);
|
||||
return 1; /* yep, we've got it */
|
||||
}
|
||||
}
|
||||
|
||||
DBG_INFO(80, L"no cache hits.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
TxFilter::checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette)
|
||||
{
|
||||
if (_options & (HIRESTEXTURES_MASK|DUMP_TEX))
|
||||
return _txUtil->checksum64(src, width, height, size, rowStride, palette);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxFilter::dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64)
|
||||
{
|
||||
if (!_initialized)
|
||||
return 0;
|
||||
|
||||
if (!(_options & DUMP_TEX))
|
||||
return 0;
|
||||
|
||||
#ifdef DUMP_CACHE
|
||||
DBG_INFO(80, L"gfmt = %02x n64fmt = %02x\n", gfmt, n64fmt);
|
||||
DBG_INFO(80, L"hirestex: r_crc64:%08X %08X\n",
|
||||
(uint32)(r_crc64 >> 32), (uint32)(r_crc64 & 0xffffffff));
|
||||
|
||||
if (!_txQuantize->quantize(src, _tex1, rowStridePixel, height, (gfmt & 0x00ff), GR_TEXFMT_ARGB_8888))
|
||||
return 0;
|
||||
|
||||
src = _tex1;
|
||||
|
||||
if (!_datapath.empty() && !_ident.empty()) {
|
||||
/* dump it to disk */
|
||||
FILE *fp = NULL;
|
||||
std::wstring tmpbuf;
|
||||
wchar_t texid[36];
|
||||
|
||||
/* create directories */
|
||||
tmpbuf.assign(_datapath + L"/texture_dump");
|
||||
if (!boost::filesystem::exists(tmpbuf) &&
|
||||
!boost::filesystem::create_directory(tmpbuf))
|
||||
return 0;
|
||||
|
||||
tmpbuf.append(L"/" + _ident);
|
||||
if (!boost::filesystem::exists(tmpbuf) &&
|
||||
!boost::filesystem::create_directory(tmpbuf))
|
||||
return 0;
|
||||
|
||||
tmpbuf.append(L"/GlideHQ");
|
||||
if (!boost::filesystem::exists(tmpbuf) &&
|
||||
!boost::filesystem::create_directory(tmpbuf))
|
||||
return 0;
|
||||
|
||||
if ((n64fmt >> 8) == 0x2) {
|
||||
swprintf(texid, 36, L"%08X#%01X#%01X#%08X", (uint32)(r_crc64 & 0xffffffff), (uint32)(n64fmt >> 8), (uint32)(n64fmt & 0xf), (uint32)(r_crc64 >> 32));
|
||||
tmpbuf.append(L"/" + _ident + L"#" + texid + L"_ciByRGBA.png");
|
||||
} else {
|
||||
swprintf(texid, 36, L"%08X#%01X#%01X", (uint32)(r_crc64 & 0xffffffff), (uint32)(n64fmt >> 8), (uint32)(n64fmt & 0xf));
|
||||
tmpbuf.append(L"/" + _ident + L"#" + texid + L"_all.png");
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if ((fp = _wfopen(tmpbuf.c_str(), L"wb")) != NULL) {
|
||||
#else
|
||||
char cbuf[MAX_PATH];
|
||||
wcstombs(cbuf, tmpbuf.c_str(), MAX_PATH);
|
||||
if ((fp = fopen(cbuf, "wb")) != NULL) {
|
||||
#endif
|
||||
_txImage->writePNG(src, fp, width, height, (rowStridePixel << 2), 0x0003, 0);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxFilter::reloadhirestex()
|
||||
{
|
||||
DBG_INFO(80, L"Reload hires textures from texture pack.\n");
|
||||
|
||||
if (_txHiResCache->load(0)) {
|
||||
if (_txHiResCache->empty()) _options &= ~HIRESTEXTURES_MASK;
|
||||
else _options |= HIRESTEXTURES_MASK;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXFILTER_H__
|
||||
#define __TXFILTER_H__
|
||||
|
||||
#include "TxInternal.h"
|
||||
#include "TxQuantize.h"
|
||||
#include "TxHiResCache.h"
|
||||
#include "TxTexCache.h"
|
||||
#include "TxUtil.h"
|
||||
#include "TxImage.h"
|
||||
#include <string>
|
||||
|
||||
class TxFilter
|
||||
{
|
||||
private:
|
||||
int _numcore;
|
||||
|
||||
uint8 *_tex1;
|
||||
uint8 *_tex2;
|
||||
int _maxwidth;
|
||||
int _maxheight;
|
||||
int _maxbpp;
|
||||
int _options;
|
||||
int _cacheSize;
|
||||
std::wstring _ident;
|
||||
std::wstring _datapath;
|
||||
std::wstring _cachepath;
|
||||
TxQuantize *_txQuantize;
|
||||
TxTexCache *_txTexCache;
|
||||
TxHiResCache *_txHiResCache;
|
||||
TxUtil *_txUtil;
|
||||
TxImage *_txImage;
|
||||
boolean _initialized;
|
||||
void clear();
|
||||
public:
|
||||
~TxFilter();
|
||||
TxFilter(int maxwidth,
|
||||
int maxheight,
|
||||
int maxbpp,
|
||||
int options,
|
||||
int cachesize,
|
||||
wchar_t *datapath,
|
||||
wchar_t *cachepath,
|
||||
wchar_t *ident,
|
||||
dispInfoFuncExt callback);
|
||||
boolean filter(uint8 *src,
|
||||
int srcwidth,
|
||||
int srcheight,
|
||||
uint16 srcformat,
|
||||
uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||
GHQTexInfo *info);
|
||||
boolean hirestex(uint64 g64crc, /* glide64 crc, 64bit for future use */
|
||||
uint64 r_crc64, /* checksum hi:palette low:texture */
|
||||
uint16 *palette,
|
||||
GHQTexInfo *info);
|
||||
uint64 checksum64(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette);
|
||||
boolean dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64);
|
||||
boolean reloadhirestex();
|
||||
};
|
||||
|
||||
#endif /* __TXFILTER_H__ */
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef __MSC__
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
#include "TxFilter.h"
|
||||
|
||||
TxFilter *txFilter = NULL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize,
|
||||
wchar_t *datapath, wchar_t *cachepath, wchar_t*ident,
|
||||
dispInfoFuncExt callback)
|
||||
{
|
||||
if (txFilter) return 0;
|
||||
|
||||
txFilter = new TxFilter(maxwidth, maxheight, maxbpp, options, cachesize,
|
||||
datapath, cachepath, ident, callback);
|
||||
|
||||
return (txFilter ? 1 : 0);
|
||||
}
|
||||
|
||||
TAPI void TAPIENTRY
|
||||
txfilter_shutdown(void)
|
||||
{
|
||||
if (txFilter) delete txFilter;
|
||||
|
||||
txFilter = NULL;
|
||||
}
|
||||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter(uint8 *src, int srcwidth, int srcheight, uint16 srcformat,
|
||||
uint64 g64crc, GHQTexInfo *info)
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->filter(src, srcwidth, srcheight, srcformat,
|
||||
g64crc, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_hirestex(uint64 g64crc, uint64 r_crc64, uint16 *palette, GHQTexInfo *info)
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->hirestex(g64crc, r_crc64, palette, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAPI uint64 TAPIENTRY
|
||||
txfilter_checksum(uint8 *src, int width, int height, int size, int rowStride, uint8 *palette)
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->checksum64(src, width, height, size, rowStride, palette);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_dmptx(uint8 *src, int width, int height, int rowStridePixel, uint16 gfmt, uint16 n64fmt, uint64 r_crc64)
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->dmptx(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAPI boolean TAPIENTRY
|
||||
txfilter_reloadhirestex()
|
||||
{
|
||||
if (txFilter)
|
||||
return txFilter->reloadhirestex();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXHIRESCACHE_H__
|
||||
#define __TXHIRESCACHE_H__
|
||||
|
||||
/* support hires textures
|
||||
* 0: disable
|
||||
* 1: enable
|
||||
*/
|
||||
#define HIRES_TEXTURE 1
|
||||
|
||||
#include "TxCache.h"
|
||||
#include "TxQuantize.h"
|
||||
#include "TxImage.h"
|
||||
#include "TxReSample.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
class TxHiResCache : public TxCache
|
||||
{
|
||||
private:
|
||||
int _maxwidth;
|
||||
int _maxheight;
|
||||
int _maxbpp;
|
||||
boolean _haveCache;
|
||||
boolean _abortLoad;
|
||||
TxImage *_txImage;
|
||||
TxQuantize *_txQuantize;
|
||||
TxReSample *_txReSample;
|
||||
boolean loadHiResTextures(boost::filesystem::wpath dir_path, boolean replace);
|
||||
public:
|
||||
~TxHiResCache();
|
||||
TxHiResCache(int maxwidth, int maxheight, int maxbpp, int options,
|
||||
const wchar_t *datapath, const wchar_t *cachepath,
|
||||
const wchar_t *ident, dispInfoFuncExt callback);
|
||||
boolean empty();
|
||||
boolean load(boolean replace);
|
||||
};
|
||||
|
||||
#endif /* __TXHIRESCACHE_H__ */
|
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* use power of 2 texture size
|
||||
* (0:disable, 1:enable, 2:3dfx) */
|
||||
#define POW2_TEXTURES 0
|
||||
|
||||
/* check 8 bytes. use a larger value if needed. */
|
||||
#define PNG_CHK_BYTES 8
|
||||
|
||||
#include "TxImage.h"
|
||||
#include "TxReSample.h"
|
||||
#include "TxDbg.h"
|
||||
#include <stdlib.h>
|
||||
#include "../Glide64/Gfx_1.3.h"
|
||||
|
||||
boolean
|
||||
TxImage::getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr)
|
||||
{
|
||||
unsigned char sig[PNG_CHK_BYTES];
|
||||
|
||||
/* check for valid file pointer */
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
/* check if file is PNG */
|
||||
if (fread(sig, 1, PNG_CHK_BYTES, fp) != PNG_CHK_BYTES)
|
||||
return 0;
|
||||
|
||||
if (png_sig_cmp(sig, 0, PNG_CHK_BYTES) != 0)
|
||||
return 0;
|
||||
|
||||
/* get PNG file info */
|
||||
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!*png_ptr)
|
||||
return 0;
|
||||
|
||||
*info_ptr = png_create_info_struct(*png_ptr);
|
||||
if (!*info_ptr) {
|
||||
png_destroy_read_struct(png_ptr, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(*png_ptr))) {
|
||||
DBG_INFO(80, L"error reading png!\n");
|
||||
png_destroy_read_struct(png_ptr, info_ptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
png_init_io(*png_ptr, fp);
|
||||
png_set_sig_bytes(*png_ptr, PNG_CHK_BYTES);
|
||||
png_read_info(*png_ptr, *info_ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8*
|
||||
TxImage::readPNG(FILE* fp, int* width, int* height, uint16* format)
|
||||
{
|
||||
/* NOTE: returned image format is GR_TEXFMT_ARGB_8888 */
|
||||
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
uint8 *image = NULL;
|
||||
int bit_depth, color_type, interlace_type, compression_type, filter_type,
|
||||
row_bytes, o_width, o_height, num_pas;
|
||||
|
||||
/* initialize */
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*format = 0;
|
||||
|
||||
/* check if we have a valid png file */
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
if (!getPNGInfo(fp, &png_ptr, &info_ptr)) {
|
||||
INFO(80, L"error reading png file! png image is corrupt.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr,
|
||||
(png_uint_32*)&o_width, (png_uint_32*)&o_height, &bit_depth, &color_type,
|
||||
&interlace_type, &compression_type, &filter_type);
|
||||
|
||||
DBG_INFO(80, L"png format %d x %d bitdepth:%d color:%x interlace:%x compression:%x filter:%x\n",
|
||||
o_width, o_height, bit_depth, color_type,
|
||||
interlace_type, compression_type, filter_type);
|
||||
|
||||
/* transformations */
|
||||
|
||||
/* Rice hi-res textures
|
||||
* _all.png
|
||||
* _rgb.png, _a.png
|
||||
* _ciByRGBA.png
|
||||
* _allciByRGBA.png
|
||||
*/
|
||||
|
||||
/* strip if color channel is larger than 8 bits */
|
||||
if (bit_depth > 8) {
|
||||
png_set_strip_16(png_ptr);
|
||||
bit_depth = 8;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* These are not really required per Rice format spec,
|
||||
* but is done just in case someone uses them.
|
||||
*/
|
||||
/* convert palette color to rgb color */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
}
|
||||
|
||||
/* expand 1,2,4 bit gray scale to 8 bit gray scale */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
|
||||
/* convert gray scale or gray scale + alpha to rgb color */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* add alpha channel if any */
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
}
|
||||
|
||||
/* convert rgb to rgba */
|
||||
if (color_type == PNG_COLOR_TYPE_RGB) {
|
||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
}
|
||||
|
||||
/* punt invalid formats */
|
||||
if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
DBG_INFO(80, L"Error: not PNG_COLOR_TYPE_RGB_ALPHA format!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*png_color_8p sig_bit;
|
||||
if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
|
||||
png_set_shift(png_ptr, sig_bit);*/
|
||||
|
||||
/* convert rgba to bgra */
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
/* turn on interlace handling to cope with the weirdness
|
||||
* of texture authors using interlaced format */
|
||||
num_pas = png_set_interlace_handling(png_ptr);
|
||||
|
||||
/* update info structure */
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
/* we only get here if ARGB8888 */
|
||||
row_bytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
/* allocate memory to read in image */
|
||||
image = (uint8*)malloc(row_bytes * o_height);
|
||||
|
||||
/* read in image */
|
||||
if (image) {
|
||||
int pas, i;
|
||||
uint8* tmpimage;
|
||||
|
||||
for (pas = 0; pas < num_pas; pas++) { /* deal with interlacing */
|
||||
tmpimage = image;
|
||||
|
||||
for (i = 0; i < o_height; i++) {
|
||||
/* copy row */
|
||||
png_read_rows(png_ptr, &tmpimage, NULL, 1);
|
||||
tmpimage += row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/* read rest of the info structure */
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
*width = (row_bytes >> 2);
|
||||
*height = o_height;
|
||||
*format = GR_TEXFMT_ARGB_8888;
|
||||
|
||||
#if POW2_TEXTURES
|
||||
/* next power of 2 size conversions */
|
||||
/* NOTE: I can do this in the above loop for faster operations, but some
|
||||
* texture packs require a workaround. see HACKALERT in nextPow2().
|
||||
*/
|
||||
|
||||
TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place.
|
||||
|
||||
#if (POW2_TEXTURES == 2)
|
||||
if (!txReSample->nextPow2(&image, width, height, 32, 1)) {
|
||||
#else
|
||||
if (!txReSample->nextPow2(&image, width, height, 32, 0)) {
|
||||
#endif
|
||||
if (image) {
|
||||
free(image);
|
||||
image = NULL;
|
||||
}
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*format = 0;
|
||||
}
|
||||
|
||||
delete txReSample;
|
||||
|
||||
#endif /* POW2_TEXTURES */
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!image) {
|
||||
DBG_INFO(80, L"Error: failed to load png image!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxImage::writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_color_8 sig_bit;
|
||||
png_colorp palette_ptr = NULL;
|
||||
png_bytep trans_ptr = NULL;
|
||||
int bit_depth, color_type, row_bytes, num_palette;
|
||||
int i;
|
||||
//uint16 srcfmt, destfmt;
|
||||
|
||||
if (!src || !fp)
|
||||
return 0;
|
||||
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL)
|
||||
return 0;
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (png_jmpbuf(png_ptr)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
/* TODO: images must be converted to RGBA8888 or CI8,
|
||||
* palettes need to be separated to A and RGB. */
|
||||
|
||||
/* N64 formats
|
||||
* Format: 0 - RGBA, 1 - YUV, 2 - CI, 3 - IA, 4 - I
|
||||
* Size: 0 - 4bit, 1 - 8bit, 2 - 16bit, 3 - 32 bit
|
||||
* format = (Format << 8 | Size);
|
||||
*/
|
||||
|
||||
/* each channel is saved in 8bits for consistency */
|
||||
switch (format) {
|
||||
case 0x0002:/* RGBA5551 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 5;
|
||||
sig_bit.green = 5;
|
||||
sig_bit.blue = 5;
|
||||
sig_bit.alpha = 1;
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
case 0x0003:/* RGBA8888 */
|
||||
case 0x0302:/* IA88 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 8;
|
||||
sig_bit.green = 8;
|
||||
sig_bit.blue = 8;
|
||||
sig_bit.alpha = 8;
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
case 0x0300:/* IA31 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 3;
|
||||
sig_bit.green = 3;
|
||||
sig_bit.blue = 3;
|
||||
sig_bit.alpha = 1;
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
case 0x0301:/* IA44 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 4;
|
||||
sig_bit.green = 4;
|
||||
sig_bit.blue = 4;
|
||||
sig_bit.alpha = 4;
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
case 0x0400:/* I4 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 4;
|
||||
sig_bit.green = 4;
|
||||
sig_bit.blue = 4;
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
break;
|
||||
case 0x0401:/* I8 */
|
||||
case 0x0402:/* I16 */
|
||||
bit_depth = 8;
|
||||
sig_bit.red = 8;
|
||||
sig_bit.green = 8;
|
||||
sig_bit.blue = 8;
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
break;
|
||||
case 0x0200:/* CI4 */
|
||||
bit_depth = 8;
|
||||
num_palette = 16;
|
||||
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||
break;
|
||||
case 0x0201:/* CI8 */
|
||||
bit_depth = 8;
|
||||
num_palette = 256;
|
||||
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||
break;
|
||||
case 0x0102:/* YUV ? */
|
||||
case 0x0103:
|
||||
default:
|
||||
/* unsupported format */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (color_type) {
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
//row_bytes = (bit_depth * width) >> 1;
|
||||
row_bytes = rowStride;
|
||||
png_set_bgr(png_ptr);
|
||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||
break;
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
//row_bytes = (bit_depth * width) >> 3;
|
||||
row_bytes = rowStride;
|
||||
png_set_PLTE(png_ptr, info_ptr, palette_ptr, num_palette);
|
||||
png_set_tRNS(png_ptr, info_ptr, trans_ptr, num_palette, 0);
|
||||
}
|
||||
|
||||
//png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);
|
||||
|
||||
//if (bit_depth == 16)
|
||||
// png_set_swap(png_ptr);
|
||||
|
||||
//if (bit_depth < 8)
|
||||
// png_set_packswap(png_ptr);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height,
|
||||
bit_depth, color_type, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
//png_set_gAMA(png_ptr, info_ptr, 1.0);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
for (i = 0; i < height; i++) {
|
||||
png_write_row(png_ptr, (png_bytep)src);
|
||||
src += row_bytes;
|
||||
}
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
//if (tex_ptr) delete [] tex_ptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxImage::getBMPInfo(FILE* fp, BITMAPFILEHEADER* bmp_fhdr, BITMAPINFOHEADER* bmp_ihdr)
|
||||
{
|
||||
/*
|
||||
* read in BITMAPFILEHEADER
|
||||
*/
|
||||
|
||||
/* is this a BMP file? */
|
||||
if (fread(&bmp_fhdr->bfType, 2, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (memcmp(&bmp_fhdr->bfType, "BM", 2) != 0)
|
||||
return 0;
|
||||
|
||||
/* get file size */
|
||||
if (fread(&bmp_fhdr->bfSize, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* reserved 1 */
|
||||
if (fread(&bmp_fhdr->bfReserved1, 2, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* reserved 2 */
|
||||
if (fread(&bmp_fhdr->bfReserved2, 2, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* offset to the image data */
|
||||
if (fread(&bmp_fhdr->bfOffBits, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* read in BITMAPINFOHEADER
|
||||
*/
|
||||
|
||||
/* size of BITMAPINFOHEADER */
|
||||
if (fread(&bmp_ihdr->biSize, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* is this a Windows BMP? */
|
||||
if (bmp_ihdr->biSize != 40)
|
||||
return 0;
|
||||
|
||||
/* width of the bitmap in pixels */
|
||||
if (fread(&bmp_ihdr->biWidth, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* height of the bitmap in pixels */
|
||||
if (fread(&bmp_ihdr->biHeight, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* number of planes (always 1) */
|
||||
if (fread(&bmp_ihdr->biPlanes, 2, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* number of bits-per-pixel. (1, 4, 8, 16, 24, 32) */
|
||||
if (fread(&bmp_ihdr->biBitCount, 2, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* compression for a compressed bottom-up bitmap
|
||||
* 0 : uncompressed format
|
||||
* 1 : run-length encoded 4 bpp format
|
||||
* 2 : run-length encoded 8 bpp format
|
||||
* 3 : bitfield
|
||||
*/
|
||||
if (fread(&bmp_ihdr->biCompression, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* size of the image in bytes */
|
||||
if (fread(&bmp_ihdr->biSizeImage, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* horizontal resolution in pixels-per-meter */
|
||||
if (fread(&bmp_ihdr->biXPelsPerMeter, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* vertical resolution in pixels-per-meter */
|
||||
if (fread(&bmp_ihdr->biYPelsPerMeter, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* number of color indexes in the color table that are actually used */
|
||||
if (fread(&bmp_ihdr->biClrUsed, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* the number of color indexes that are required for displaying */
|
||||
if (fread(&bmp_ihdr->biClrImportant, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8*
|
||||
TxImage::readBMP(FILE* fp, int* width, int* height, uint16* format)
|
||||
{
|
||||
/* NOTE: returned image format;
|
||||
* 4, 8bit palette bmp -> GR_TEXFMT_P_8
|
||||
* 24, 32bit bmp -> GR_TEXFMT_ARGB_8888
|
||||
*/
|
||||
|
||||
uint8 *image = NULL;
|
||||
uint8 *image_row = NULL;
|
||||
uint8 *tmpimage = NULL;
|
||||
unsigned int row_bytes, pos;
|
||||
int i, j;
|
||||
/* Windows Bitmap */
|
||||
BITMAPFILEHEADER bmp_fhdr;
|
||||
BITMAPINFOHEADER bmp_ihdr;
|
||||
|
||||
/* initialize */
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*format = 0;
|
||||
|
||||
/* check if we have a valid bmp file */
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
if (!getBMPInfo(fp, &bmp_fhdr, &bmp_ihdr)) {
|
||||
INFO(80, L"error reading bitmap file! bitmap image is corrupt.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG_INFO(80, L"bmp format %d x %d bitdepth:%d compression:%x offset:%d\n",
|
||||
bmp_ihdr.biWidth, bmp_ihdr.biHeight, bmp_ihdr.biBitCount,
|
||||
bmp_ihdr.biCompression, bmp_fhdr.bfOffBits);
|
||||
|
||||
/* rowStride in bytes */
|
||||
row_bytes = (bmp_ihdr.biWidth * bmp_ihdr.biBitCount) >> 3;
|
||||
/* align to 4bytes boundary */
|
||||
row_bytes = (row_bytes + 3) & ~3;
|
||||
|
||||
/* Rice hi-res textures */
|
||||
if (!(bmp_ihdr.biBitCount == 8 || bmp_ihdr.biBitCount == 4 || bmp_ihdr.biBitCount == 32 || bmp_ihdr.biBitCount == 24) ||
|
||||
bmp_ihdr.biCompression != 0) {
|
||||
DBG_INFO(80, L"Error: incompatible bitmap format!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (bmp_ihdr.biBitCount) {
|
||||
case 8:
|
||||
case 32:
|
||||
/* 8 bit, 32 bit bitmap */
|
||||
image = (uint8*)malloc(row_bytes * bmp_ihdr.biHeight);
|
||||
if (image) {
|
||||
tmpimage = image;
|
||||
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||
/* read in image */
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
if (fread(tmpimage, 1, row_bytes, fp) != row_bytes)
|
||||
ERRLOG("fread() failed for row of '%i' bytes in 8/32-bit BMP image", row_bytes);
|
||||
tmpimage += row_bytes;
|
||||
pos -= row_bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* 4bit bitmap */
|
||||
image = (uint8*)malloc((row_bytes * bmp_ihdr.biHeight) << 1);
|
||||
image_row = (uint8*)malloc(row_bytes);
|
||||
if (image && image_row) {
|
||||
tmpimage = image;
|
||||
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||
/* read in image */
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
if (fread(image_row, 1, row_bytes, fp) != row_bytes)
|
||||
ERRLOG("fread failed for row of '%i' bytes in 4-bit BMP image", row_bytes);
|
||||
/* expand 4bpp to 8bpp. stuff 4bit values into 8bit comps. */
|
||||
for (j = 0; j < (int) row_bytes; j++) {
|
||||
tmpimage[j << 1] = image_row[j] & 0x0f;
|
||||
tmpimage[(j << 1) + 1] = (image_row[j] & 0xf0) >> 4;
|
||||
}
|
||||
tmpimage += (row_bytes << 1);
|
||||
pos -= row_bytes;
|
||||
}
|
||||
free(image_row);
|
||||
} else {
|
||||
if (image_row) free(image_row);
|
||||
if (image) free(image);
|
||||
image = NULL;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
/* 24 bit bitmap */
|
||||
image = (uint8*)malloc((bmp_ihdr.biWidth * bmp_ihdr.biHeight) << 2);
|
||||
image_row = (uint8*)malloc(row_bytes);
|
||||
if (image && image_row) {
|
||||
tmpimage = image;
|
||||
pos = bmp_fhdr.bfOffBits + row_bytes * (bmp_ihdr.biHeight - 1);
|
||||
for (i = 0; i < bmp_ihdr.biHeight; i++) {
|
||||
/* read in image */
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
if (fread(image_row, 1, row_bytes, fp) != row_bytes)
|
||||
ERRLOG("fread failed for row of '%i' bytes in 24-bit BMP image", row_bytes);
|
||||
/* convert 24bpp to 32bpp. */
|
||||
for (j = 0; j < bmp_ihdr.biWidth; j++) {
|
||||
tmpimage[(j << 2)] = image_row[j * 3];
|
||||
tmpimage[(j << 2) + 1] = image_row[j * 3 + 1];
|
||||
tmpimage[(j << 2) + 2] = image_row[j * 3 + 2];
|
||||
tmpimage[(j << 2) + 3] = 0xFF;
|
||||
}
|
||||
tmpimage += (bmp_ihdr.biWidth << 2);
|
||||
pos -= row_bytes;
|
||||
}
|
||||
free(image_row);
|
||||
} else {
|
||||
if (image_row) free(image_row);
|
||||
if (image) free(image);
|
||||
image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (image) {
|
||||
*width = (row_bytes << 3) / bmp_ihdr.biBitCount;
|
||||
*height = bmp_ihdr.biHeight;
|
||||
|
||||
switch (bmp_ihdr.biBitCount) {
|
||||
case 8:
|
||||
case 4:
|
||||
*format = GR_TEXFMT_P_8;
|
||||
break;
|
||||
case 32:
|
||||
case 24:
|
||||
*format = GR_TEXFMT_ARGB_8888;
|
||||
}
|
||||
|
||||
#if POW2_TEXTURES
|
||||
/* next power of 2 size conversions */
|
||||
/* NOTE: I can do this in the above loop for faster operations, but some
|
||||
* texture packs require a workaround. see HACKALERT in nextPow2().
|
||||
*/
|
||||
|
||||
TxReSample txReSample = new TxReSample; // XXX: temporary. move to a better place.
|
||||
|
||||
#if (POW2_TEXTURES == 2)
|
||||
if (!txReSample->nextPow2(&image, width, height, 8, 1)) {
|
||||
#else
|
||||
if (!txReSample->nextPow2(&image, width, height, 8, 0)) {
|
||||
#endif
|
||||
if (image) {
|
||||
free(image);
|
||||
image = NULL;
|
||||
}
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*format = 0;
|
||||
}
|
||||
|
||||
delete txReSample;
|
||||
|
||||
#endif /* POW2_TEXTURES */
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!image) {
|
||||
DBG_INFO(80, L"Error: failed to load bmp image!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxImage::getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr)
|
||||
{
|
||||
/*
|
||||
* read in DDSFILEHEADER
|
||||
*/
|
||||
|
||||
/* is this a DDS file? */
|
||||
if (fread(&dds_fhdr->dwMagic, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (memcmp(&dds_fhdr->dwMagic, "DDS ", 4) != 0)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwSize, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* get file flags */
|
||||
if (fread(&dds_fhdr->dwFlags, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* height of dds in pixels */
|
||||
if (fread(&dds_fhdr->dwHeight, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
/* width of dds in pixels */
|
||||
if (fread(&dds_fhdr->dwWidth, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwLinearSize, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwDepth, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwMipMapCount, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwReserved1, 4 * 11, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwSize, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwFlags, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwFourCC, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwRGBBitCount, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwRBitMask, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwGBitMask, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwBBitMask, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->ddpf.dwRGBAlphaBitMask, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwCaps1, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
if (fread(&dds_fhdr->dwCaps2, 4, 1, fp) != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8*
|
||||
TxImage::readDDS(FILE* fp, int* width, int* height, uint16* format)
|
||||
{
|
||||
uint8 *image = NULL;
|
||||
DDSFILEHEADER dds_fhdr;
|
||||
uint16 tmpformat = 0;
|
||||
|
||||
/* initialize */
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*format = 0;
|
||||
|
||||
/* check if we have a valid dds file */
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
if (!getDDSInfo(fp, &dds_fhdr)) {
|
||||
INFO(80, L"error reading dds file! dds image is corrupt.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG_INFO(80, L"dds format %d x %d HeaderSize %d LinearSize %d\n",
|
||||
dds_fhdr.dwWidth, dds_fhdr.dwHeight, dds_fhdr.dwSize, dds_fhdr.dwLinearSize);
|
||||
|
||||
if (!(dds_fhdr.dwFlags & (DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_LINEARSIZE))) {
|
||||
DBG_INFO(80, L"Error: incompatible dds format!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((dds_fhdr.dwFlags & DDSD_MIPMAPCOUNT) && dds_fhdr.dwMipMapCount != 1) {
|
||||
DBG_INFO(80, L"Error: mipmapped dds not supported!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!((dds_fhdr.ddpf.dwFlags & DDPF_FOURCC) && dds_fhdr.dwCaps2 == 0)) {
|
||||
DBG_INFO(80, L"Error: not fourcc standard texture!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT1", 4) == 0) {
|
||||
DBG_INFO(80, L"DXT1 format\n");
|
||||
/* compensate for missing LinearSize */
|
||||
dds_fhdr.dwLinearSize = (dds_fhdr.dwWidth * dds_fhdr.dwHeight) >> 1;
|
||||
tmpformat = GR_TEXFMT_ARGB_CMP_DXT1;
|
||||
} else if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT3", 4) == 0) {
|
||||
DBG_INFO(80, L"DXT3 format\n");
|
||||
dds_fhdr.dwLinearSize = dds_fhdr.dwWidth * dds_fhdr.dwHeight;
|
||||
tmpformat = GR_TEXFMT_ARGB_CMP_DXT3;
|
||||
} else if (memcmp(&dds_fhdr.ddpf.dwFourCC, "DXT5", 4) == 0) {
|
||||
DBG_INFO(80, L"DXT5 format\n");
|
||||
dds_fhdr.dwLinearSize = dds_fhdr.dwWidth * dds_fhdr.dwHeight;
|
||||
tmpformat = GR_TEXFMT_ARGB_CMP_DXT5;
|
||||
} else {
|
||||
DBG_INFO(80, L"Error: not DXT1 or DXT3 or DXT5 format!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read in image */
|
||||
image = (uint8*)malloc(dds_fhdr.dwLinearSize);
|
||||
if (image) {
|
||||
*width = dds_fhdr.dwWidth;
|
||||
*height = dds_fhdr.dwHeight;
|
||||
*format = tmpformat;
|
||||
|
||||
fseek(fp, 128, SEEK_SET); /* size of header is 128 bytes */
|
||||
if (fread(image, 1, dds_fhdr.dwLinearSize, fp) != dds_fhdr.dwLinearSize)
|
||||
ERRLOG("fread failed to read DDS image of '%i' bytes", dds_fhdr.dwLinearSize);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXIMAGE_H__
|
||||
#define __TXIMAGE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <png.h>
|
||||
#include "TxInternal.h"
|
||||
|
||||
#ifndef WIN32
|
||||
typedef struct tagBITMAPFILEHEADER {
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
} BITMAPFILEHEADER;
|
||||
|
||||
typedef struct tagBITMAPINFOHEADER {
|
||||
uint32_t biSize;
|
||||
int32_t biWidth;
|
||||
int32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
uint32_t biXPelsPerMeter;
|
||||
uint32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
} BITMAPINFOHEADER;
|
||||
#else
|
||||
typedef struct tagBITMAPFILEHEADER BITMAPFILEHEADER;
|
||||
typedef struct tagBITMAPINFOHEADER BITMAPINFOHEADER;
|
||||
#endif
|
||||
|
||||
#define DDSD_CAPS 0x00000001
|
||||
#define DDSD_HEIGHT 0x00000002
|
||||
#define DDSD_WIDTH 0x00000004
|
||||
#define DDSD_PITCH 0x00000008
|
||||
#define DDSD_PIXELFORMAT 0x00001000
|
||||
#define DDSD_MIPMAPCOUNT 0x00020000
|
||||
#define DDSD_LINEARSIZE 0x00080000
|
||||
#define DDSD_DEPTH 0x00800000
|
||||
|
||||
#define DDPF_ALPHAPIXELS 0x00000001
|
||||
#define DDPF_FOURCC 0x00000004
|
||||
#define DDPF_RGB 0x00000040
|
||||
|
||||
#define DDSCAPS_COMPLEX 0x00000008
|
||||
#define DDSCAPS_TEXTURE 0x00001000
|
||||
#define DDSCAPS_MIPMAP 0x00400000
|
||||
|
||||
typedef struct tagDDSPIXELFORMAT {
|
||||
uint32_t dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwFourCC;
|
||||
uint32_t dwRGBBitCount;
|
||||
uint32_t dwRBitMask;
|
||||
uint32_t dwGBitMask;
|
||||
uint32_t dwBBitMask;
|
||||
uint32_t dwRGBAlphaBitMask;
|
||||
} DDSPIXELFORMAT;
|
||||
|
||||
typedef struct tagDDSFILEHEADER {
|
||||
uint32_t dwMagic;
|
||||
uint32_t dwSize;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwHeight;
|
||||
uint32_t dwWidth;
|
||||
uint32_t dwLinearSize;
|
||||
uint32_t dwDepth;
|
||||
uint32_t dwMipMapCount;
|
||||
uint32_t dwReserved1[11];
|
||||
DDSPIXELFORMAT ddpf;
|
||||
uint32_t dwCaps1;
|
||||
uint32_t dwCaps2;
|
||||
} DDSFILEHEADER;
|
||||
|
||||
class TxImage
|
||||
{
|
||||
private:
|
||||
boolean getPNGInfo(FILE *fp, png_structp *png_ptr, png_infop *info_ptr);
|
||||
boolean getBMPInfo(FILE *fp, BITMAPFILEHEADER *bmp_fhdr, BITMAPINFOHEADER *bmp_ihdr);
|
||||
boolean getDDSInfo(FILE *fp, DDSFILEHEADER *dds_fhdr);
|
||||
public:
|
||||
TxImage() {}
|
||||
~TxImage() {}
|
||||
uint8* readPNG(FILE* fp, int* width, int* height, uint16* format);
|
||||
boolean writePNG(uint8* src, FILE* fp, int width, int height, int rowStride, uint16 format, uint8 *palette);
|
||||
uint8* readBMP(FILE* fp, int* width, int* height, uint16* format);
|
||||
uint8* readDDS(FILE* fp, int* width, int* height, uint16* format);
|
||||
};
|
||||
|
||||
#endif /* __TXIMAGE_H__ */
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_H__
|
||||
#define __INTERNAL_H__
|
||||
|
||||
#include "Ext_TxFilter.h"
|
||||
|
||||
/* dll exports */
|
||||
#ifdef TXFILTER_DLL
|
||||
#define TAPI __declspec(dllexport)
|
||||
#define TAPIENTRY
|
||||
#else
|
||||
#define TAPI
|
||||
#define TAPIENTRY
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
|
||||
#ifdef WIN32
|
||||
#define KBHIT(key) ((GetAsyncKeyState(key) & 0x8001) == 0x8001)
|
||||
#else
|
||||
#define KBHIT(key) (0)
|
||||
#endif
|
||||
|
||||
/* from OpenGL glext.h */
|
||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
|
||||
/* for explicit fxt1 compression */
|
||||
#define CC_CHROMA 0x0
|
||||
#define CC_HI 0x1
|
||||
#define CC_ALPHA 0x2
|
||||
|
||||
/* in-memory zlib texture compression */
|
||||
#define GR_TEXFMT_GZ 0x8000
|
||||
|
||||
#if 0 /* this is here to remind me of other formats */
|
||||
/* from 3Dfx Interactive Inc. glide.h */
|
||||
#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
|
||||
|
||||
/* from 3Dfx Interactive Inc. g3ext.h */
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif /* __INTERNAL_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXQUANTIZE_H__
|
||||
#define __TXQUANTIZE_H__
|
||||
|
||||
/* Glide64 DXTn workaround
|
||||
* (0:disable, 1:enable) */
|
||||
#define GLIDE64_DXTN 1
|
||||
|
||||
#include "TxInternal.h"
|
||||
#include "TxUtil.h"
|
||||
|
||||
class TxQuantize
|
||||
{
|
||||
private:
|
||||
TxUtil *_txUtil;
|
||||
int _numcore;
|
||||
|
||||
fxtCompressTexFuncExt _tx_compress_fxt1;
|
||||
dxtCompressTexFuncExt _tx_compress_dxtn;
|
||||
|
||||
/* fast optimized... well, sort of. */
|
||||
void ARGB1555_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB4444_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
void RGB565_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
void A8_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
void AI44_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
void AI88_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
|
||||
void ARGB8888_ARGB1555(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_ARGB4444(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_RGB565(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_A8(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_AI44(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_AI88(uint32* src, uint32* dst, int width, int height);
|
||||
|
||||
/* quality */
|
||||
void ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height);
|
||||
|
||||
/* compressors */
|
||||
boolean FXT1(uint8 *src, uint8 *dest,
|
||||
int srcwidth, int srcheight, uint16 srcformat,
|
||||
int *destwidth, int *destheight, uint16 *destformat);
|
||||
boolean DXTn(uint8 *src, uint8 *dest,
|
||||
int srcwidth, int srcheight, uint16 srcformat,
|
||||
int *destwidth, int *destheight, uint16 *destformat);
|
||||
|
||||
public:
|
||||
TxQuantize();
|
||||
~TxQuantize();
|
||||
|
||||
/* others */
|
||||
void P8_16BPP(uint32* src, uint32* dst, int width, int height, uint32* palette);
|
||||
|
||||
boolean quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer = 1);
|
||||
|
||||
boolean compress(uint8 *src, uint8 *dest,
|
||||
int srcwidth, int srcheight, uint16 srcformat,
|
||||
int *destwidth, int *destheight, uint16 *destformat,
|
||||
int compressionType);
|
||||
|
||||
|
||||
#if 0 /* unused */
|
||||
void ARGB8888_I8(uint32* src, uint32* dst, int width, int height);
|
||||
void I8_ARGB8888(uint32* src, uint32* dst, int width, int height);
|
||||
|
||||
void ARGB1555_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB4444_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||
void ARGB8888_ABGR8888(uint32* src, uint32* dst, int width, int height);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __TXQUANTIZE_H__ */
|
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "TxReSample.h"
|
||||
#include "TxDbg.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
int
|
||||
TxReSample::nextPow2(int num)
|
||||
{
|
||||
num = num - 1;
|
||||
num = num | (num >> 1);
|
||||
num = num | (num >> 2);
|
||||
num = num | (num >> 4);
|
||||
num = num | (num >> 8);
|
||||
num = num | (num >> 16);
|
||||
/*num = num | (num >> 32);*//* for 64bit architecture */
|
||||
num = num + 1;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
boolean
|
||||
TxReSample::nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx = 0)
|
||||
{
|
||||
/* NOTE: bpp must be one of the follwing: 8, 16, 24, 32 bits per pixel */
|
||||
|
||||
if (!*image || !*width || !*height || !bpp)
|
||||
return 0;
|
||||
|
||||
int row_bytes = ((*width * bpp) >> 3);
|
||||
int o_row_bytes = row_bytes;
|
||||
int o_width = *width;
|
||||
int n_width = *width;
|
||||
int o_height = *height;
|
||||
int n_height = *height;
|
||||
|
||||
/* HACKALERT: I have explicitly subtracted (n) from width/height to
|
||||
* adjust textures that have (n) pixel larger width/height than
|
||||
* power of 2 size. This is a dirty hack for textures that have
|
||||
* munged aspect ratio by (n) pixel to the original.
|
||||
*/
|
||||
if (n_width > 64) n_width -= 4;
|
||||
else if (n_width > 16) n_width -= 2;
|
||||
else if (n_width > 4) n_width -= 1;
|
||||
|
||||
if (n_height > 64) n_height -= 4;
|
||||
else if (n_height > 16) n_height -= 2;
|
||||
else if (n_height > 4) n_height -= 1;
|
||||
|
||||
n_width = nextPow2(n_width);
|
||||
n_height = nextPow2(n_height);
|
||||
row_bytes = (n_width * bpp) >> 3;
|
||||
|
||||
/* 3dfx Glide3 format, W:H aspect ratio range (8:1 - 1:8) */
|
||||
if (use_3dfx) {
|
||||
if (n_width > n_height) {
|
||||
if (n_width > (n_height << 3))
|
||||
n_height = n_width >> 3;
|
||||
} else {
|
||||
if (n_height > (n_width << 3)) {
|
||||
n_width = n_height >> 3;
|
||||
row_bytes = (n_width * bpp) >> 3;
|
||||
}
|
||||
}
|
||||
DBG_INFO(80, L"using 3dfx W:H aspect ratio range (8:1 - 1:8).\n");
|
||||
}
|
||||
|
||||
/* do we really need to do this ? */
|
||||
if (o_width == n_width && o_height == n_height)
|
||||
return 1; /* nope */
|
||||
|
||||
DBG_INFO(80, L"expand image to next power of 2 dimensions. %d x %d -> %d x %d\n",
|
||||
o_width, o_height, n_width, n_height);
|
||||
|
||||
if (o_width > n_width)
|
||||
o_width = n_width;
|
||||
|
||||
if (o_height > n_height)
|
||||
o_height = n_height;
|
||||
|
||||
/* allocate memory to read in image */
|
||||
uint8 *pow2image = (uint8*)malloc(row_bytes * n_height);
|
||||
|
||||
/* read in image */
|
||||
if (pow2image) {
|
||||
int i, j;
|
||||
uint8 *tmpimage = *image, *tmppow2image = pow2image;
|
||||
|
||||
for (i = 0; i < o_height; i++) {
|
||||
/* copy row */
|
||||
memcpy(tmppow2image, tmpimage, ((o_width * bpp) >> 3));
|
||||
|
||||
/* expand to pow2 size by replication */
|
||||
for(j = ((o_width * bpp) >> 3); j < row_bytes; j++)
|
||||
tmppow2image[j] = tmppow2image[j - (bpp >> 3)];
|
||||
|
||||
tmppow2image += row_bytes;
|
||||
tmpimage += o_row_bytes;
|
||||
}
|
||||
/* expand to pow2 size by replication */
|
||||
for (i = o_height; i < n_height; i++)
|
||||
memcpy(&pow2image[row_bytes * i], &pow2image[row_bytes * (i - 1)], row_bytes);
|
||||
|
||||
free(*image);
|
||||
|
||||
*image = pow2image;
|
||||
*height = n_height;
|
||||
*width = n_width;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ken Turkowski
|
||||
* Filters for Common Resampling Tasks
|
||||
* Apple Computer 1990
|
||||
*/
|
||||
double
|
||||
TxReSample::tent(double x)
|
||||
{
|
||||
if (x < 0.0) x = -x;
|
||||
if (x < 1.0) return (1.0 - x);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double
|
||||
TxReSample::gaussian(double x)
|
||||
{
|
||||
if (x < 0) x = -x;
|
||||
if (x < 2.0) return pow(2.0, -2.0 * x * x);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double
|
||||
TxReSample::sinc(double x)
|
||||
{
|
||||
if (x == 0) return 1.0;
|
||||
x *= M_PI;
|
||||
return (sin(x) / x);
|
||||
}
|
||||
|
||||
double
|
||||
TxReSample::lanczos3(double x)
|
||||
{
|
||||
if (x < 0) x = -x;
|
||||
if (x < 3.0) return (sinc(x) * sinc(x/3.0));
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* Don P. Mitchell and Arun N. Netravali
|
||||
* Reconstruction Filters in Computer Graphics
|
||||
* SIGGRAPH '88
|
||||
* Proceedings of the 15th annual conference on Computer
|
||||
* graphics and interactive techniques, pp221-228, 1988
|
||||
*/
|
||||
double
|
||||
TxReSample::mitchell(double x)
|
||||
{
|
||||
if (x < 0) x = -x;
|
||||
if (x < 2.0) {
|
||||
const double B = 1.0 / 3.0;
|
||||
const double C = 1.0 / 3.0;
|
||||
if (x < 1.0) {
|
||||
x = (((12.0 - 9.0 * B - 6.0 * C) * (x * x * x))
|
||||
+ ((-18.0 + 12.0 * B + 6.0 * C) * (x * x))
|
||||
+ (6.0 - 2.0 * B));
|
||||
} else {
|
||||
x = (((-1.0 * B - 6.0 * C) * (x * x * x))
|
||||
+ ((6.0 * B + 30.0 * C) * (x * x))
|
||||
+ ((-12.0 * B - 48.0 * C) * x)
|
||||
+ (8.0 * B + 24.0 * C));
|
||||
}
|
||||
return (x / 6.0);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* J. F. Kaiser and W. A. Reed
|
||||
* Data smoothing using low-pass digital filters
|
||||
* Rev. Sci. instrum. 48 (11), pp1447-1457, 1977
|
||||
*/
|
||||
double
|
||||
TxReSample::besselI0(double x)
|
||||
{
|
||||
/* zero-order modified bessel function of the first kind */
|
||||
const double eps_coeff = 1E-16; /* small enough */
|
||||
double xh, sum, pow, ds;
|
||||
xh = 0.5 * x;
|
||||
sum = 1.0;
|
||||
pow = 1.0;
|
||||
ds = 1.0;
|
||||
int k = 0;
|
||||
while (ds > sum * eps_coeff) {
|
||||
k++;
|
||||
pow *= (xh / k);
|
||||
ds = pow * pow;
|
||||
sum = sum + ds;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double
|
||||
TxReSample::kaiser(double x)
|
||||
{
|
||||
const double alpha = 4.0;
|
||||
const double half_window = 5.0;
|
||||
const double ratio = x / half_window;
|
||||
return sinc(x) * besselI0(alpha * sqrt(1 - ratio * ratio)) / besselI0(alpha);
|
||||
}
|
||||
|
||||
boolean
|
||||
TxReSample::minify(uint8 **src, int *width, int *height, int ratio)
|
||||
{
|
||||
/* NOTE: src must be ARGB8888, ratio is the inverse representation */
|
||||
|
||||
#if 0
|
||||
if (!*src || ratio < 2) return 0;
|
||||
|
||||
/* Box filtering.
|
||||
* It would be nice to do Kaiser filtering.
|
||||
* N64 uses narrow strip textures which makes it hard to filter effectively.
|
||||
*/
|
||||
|
||||
int x, y, x2, y2, offset, numtexel;
|
||||
uint32 A, R, G, B, texel;
|
||||
|
||||
int tmpwidth = *width / ratio;
|
||||
int tmpheight = *height / ratio;
|
||||
|
||||
uint8 *tmptex = (uint8*)malloc((tmpwidth * tmpheight) << 2);
|
||||
|
||||
if (tmptex) {
|
||||
numtexel = ratio * ratio;
|
||||
for (y = 0; y < tmpheight; y++) {
|
||||
offset = ratio * y * *width;
|
||||
for (x = 0; x < tmpwidth; x++) {
|
||||
A = R = G = B = 0;
|
||||
for (y2 = 0; y2 < ratio; y2++) {
|
||||
for (x2 = 0; x2 < ratio; x2++) {
|
||||
texel = ((uint32*)*src)[offset + *width * y2 + x2];
|
||||
A += (texel >> 24);
|
||||
R += ((texel >> 16) & 0x000000ff);
|
||||
G += ((texel >> 8) & 0x000000ff);
|
||||
B += (texel & 0x000000ff);
|
||||
}
|
||||
}
|
||||
A = (A + ratio) / numtexel;
|
||||
R = (R + ratio) / numtexel;
|
||||
G = (G + ratio) / numtexel;
|
||||
B = (B + ratio) / numtexel;
|
||||
((uint32*)tmptex)[y * tmpwidth + x] = ((A << 24) | (R << 16) | (G << 8) | B);
|
||||
offset += ratio;
|
||||
}
|
||||
}
|
||||
free(*src);
|
||||
*src = tmptex;
|
||||
*width = tmpwidth;
|
||||
*height = tmpheight;
|
||||
|
||||
DBG_INFO(80, L"minification ratio:%d -> %d x %d\n", ratio, *width, *height);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
DBG_INFO(80, L"Error: failed minification!\n");
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
if (!*src || ratio < 2) return 0;
|
||||
|
||||
/* Image Resampling */
|
||||
|
||||
/* half width of filter window.
|
||||
* NOTE: must be 1.0 or larger.
|
||||
*
|
||||
* kaiser-bessel 5, lanczos3 3, mitchell 2, gaussian 1.5, tent 1
|
||||
*/
|
||||
double half_window = 5.0;
|
||||
|
||||
int x, y, x2, y2, z;
|
||||
double A, R, G, B;
|
||||
uint32 texel;
|
||||
|
||||
int tmpwidth = *width / ratio;
|
||||
int tmpheight = *height / ratio;
|
||||
|
||||
/* resampled destination */
|
||||
uint8 *tmptex = (uint8*)malloc((tmpwidth * tmpheight) << 2);
|
||||
if (!tmptex) return 0;
|
||||
|
||||
/* work buffer. single row */
|
||||
uint8 *workbuf = (uint8*)malloc(*width << 2);
|
||||
if (!workbuf) {
|
||||
free(tmptex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* prepare filter lookup table. only half width required for symetric filters. */
|
||||
double *weight = (double*)malloc((int)((half_window * ratio) * sizeof(double)));
|
||||
if (!weight) {
|
||||
free(tmptex);
|
||||
free(workbuf);
|
||||
return 0;
|
||||
}
|
||||
for (x = 0; x < half_window * ratio; x++) {
|
||||
//weight[x] = tent((double)x / ratio) / ratio;
|
||||
//weight[x] = gaussian((double)x / ratio) / ratio;
|
||||
//weight[x] = lanczos3((double)x / ratio) / ratio;
|
||||
//weight[x] = mitchell((double)x / ratio) / ratio;
|
||||
weight[x] = kaiser((double)x / ratio) / ratio;
|
||||
}
|
||||
|
||||
/* linear convolution */
|
||||
for (y = 0; y < tmpheight; y++) {
|
||||
for (x = 0; x < *width; x++) {
|
||||
texel = ((uint32*)*src)[y * ratio * *width + x];
|
||||
A = (double)(texel >> 24) * weight[0];
|
||||
R = (double)((texel >> 16) & 0xff) * weight[0];
|
||||
G = (double)((texel >> 8) & 0xff) * weight[0];
|
||||
B = (double)((texel ) & 0xff) * weight[0];
|
||||
for (y2 = 1; y2 < half_window * ratio; y2++) {
|
||||
z = y * ratio + y2;
|
||||
if (z >= *height) z = *height - 1;
|
||||
texel = ((uint32*)*src)[z * *width + x];
|
||||
A += (double)(texel >> 24) * weight[y2];
|
||||
R += (double)((texel >> 16) & 0xff) * weight[y2];
|
||||
G += (double)((texel >> 8) & 0xff) * weight[y2];
|
||||
B += (double)((texel ) & 0xff) * weight[y2];
|
||||
z = y * ratio - y2;
|
||||
if (z < 0) z = 0;
|
||||
texel = ((uint32*)*src)[z * *width + x];
|
||||
A += (double)(texel >> 24) * weight[y2];
|
||||
R += (double)((texel >> 16) & 0xff) * weight[y2];
|
||||
G += (double)((texel >> 8) & 0xff) * weight[y2];
|
||||
B += (double)((texel ) & 0xff) * weight[y2];
|
||||
}
|
||||
if (A < 0) A = 0; else if (A > 255) A = 255;
|
||||
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||
((uint32*)workbuf)[x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B);
|
||||
}
|
||||
for (x = 0; x < tmpwidth; x++) {
|
||||
texel = ((uint32*)workbuf)[x * ratio];
|
||||
A = (double)(texel >> 24) * weight[0];
|
||||
R = (double)((texel >> 16) & 0xff) * weight[0];
|
||||
G = (double)((texel >> 8) & 0xff) * weight[0];
|
||||
B = (double)((texel ) & 0xff) * weight[0];
|
||||
for (x2 = 1; x2 < half_window * ratio; x2++) {
|
||||
z = x * ratio + x2;
|
||||
if (z >= *width) z = *width - 1;
|
||||
texel = ((uint32*)workbuf)[z];
|
||||
A += (double)(texel >> 24) * weight[x2];
|
||||
R += (double)((texel >> 16) & 0xff) * weight[x2];
|
||||
G += (double)((texel >> 8) & 0xff) * weight[x2];
|
||||
B += (double)((texel ) & 0xff) * weight[x2];
|
||||
z = x * ratio - x2;
|
||||
if (z < 0) z = 0;
|
||||
texel = ((uint32*)workbuf)[z];
|
||||
A += (double)(texel >> 24) * weight[x2];
|
||||
R += (double)((texel >> 16) & 0xff) * weight[x2];
|
||||
G += (double)((texel >> 8) & 0xff) * weight[x2];
|
||||
B += (double)((texel ) & 0xff) * weight[x2];
|
||||
}
|
||||
if (A < 0) A = 0; else if (A > 255) A = 255;
|
||||
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||
((uint32*)tmptex)[y * tmpwidth + x] = (((uint32)A << 24) | ((uint32)R << 16) | ((uint32)G << 8) | (uint32)B);
|
||||
}
|
||||
}
|
||||
|
||||
free(*src);
|
||||
*src = tmptex;
|
||||
free(weight);
|
||||
free(workbuf);
|
||||
*width = tmpwidth;
|
||||
*height = tmpheight;
|
||||
|
||||
DBG_INFO(80, L"minification ratio:%d -> %d x %d\n", ratio, *width, *height);
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Texture Filtering
|
||||
* Version: 1.0
|
||||
*
|
||||
* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.
|
||||
* Email koolsmoky(at)users.sourceforge.net
|
||||
* Web http://www.3dfxzone.it/koolsmoky
|
||||
*
|
||||
* this is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TXRESAMPLE_H__
|
||||
#define __TXRESAMPLE_H__
|
||||
|
||||
#include "TxInternal.h"
|
||||
|
||||
class TxReSample
|
||||
{
|
||||
private:
|
||||
double tent(double x);
|
||||
double gaussian(double x);
|
||||
double sinc(double x);
|
||||
double lanczos3(double x);
|
||||
double mitchell(double x);
|
||||
double besselI0(double x);
|
||||
double kaiser(double x);
|
||||
public:
|
||||
boolean minify(uint8 **src, int *width, int *height, int ratio);
|
||||
boolean nextPow2(uint8** image, int* width, int* height, int bpp, boolean use_3dfx);
|
||||
int nextPow2(int num);
|
||||
};
|
||||
|
||||
#endif /* __TXRESAMPLE_H__ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue