mirror of https://github.com/blawar/ooot.git
Compare commits
60 Commits
75e9f69086
...
abcf468126
Author | SHA1 | Date |
---|---|---|
RyzenDew | abcf468126 | |
frizzle101101 | da7b648ac1 | |
frizzle101101 | 8c39534f36 | |
frizzle101101 | f3d9427692 | |
frizzle101101 | 5f5413c74d | |
frizzle101101 | 0b63cefd17 | |
frizzle101101 | 61874050ef | |
frizzle101101 | 04919e884a | |
frizzle101101 | 3af4c65da3 | |
frizzle101101 | e8fd7b1d76 | |
frizzle101101 | 1ca70f0779 | |
frizzle101101 | 89b8364e13 | |
frizzle101101 | b9056ca5f1 | |
frizzle101101 | 852a68fbd2 | |
frizzle101101 | 8eeacf8c28 | |
frizzle101101 | d9aa86f1b1 | |
frizzle101101 | 20375fa4e4 | |
frizzle101101 | 780f7c2890 | |
frizzle101101 | 51ac9860f6 | |
frizzle101101 | 61709af219 | |
frizzle101101 | 72f8a4b509 | |
frizzle101101 | d0f9e36878 | |
frizzle101101 | a579fa71b0 | |
frizzle101101 | e1d82ff070 | |
frizzle101101 | 9980297ed3 | |
frizzle101101 | 0e81119b13 | |
frizzle101101 | 3bcb329f24 | |
frizzle101101 | 23177347bb | |
frizzle101101 | 3082d50aa6 | |
frizzle101101 | 23bbecc2f3 | |
frizzle101101 | 7d531b8b82 | |
frizzle101101 | d20c20df21 | |
frizzle101101 | 07b103a874 | |
frizzle101101 | c77573553e | |
frizzle101101 | 452f2b7785 | |
frizzle101101 | c5c4632de4 | |
frizzle101101 | 58053692db | |
frizzle101101 | f6d68b885a | |
frizzle101101 | 9a1ecc2d2f | |
frizzle101101 | de9179f355 | |
frizzle101101 | 9bd41b12d2 | |
frizzle101101 | 0141f68679 | |
frizzle101101 | 8006a360fd | |
frizzle101101 | 36447ca6c6 | |
frizzle101101 | a5951ddb7e | |
frizzle101101 | dc38f59c7a | |
frizzle101101 | a518141066 | |
frizzle101101 | 8d65be772d | |
frizzle101101 | daf51473e4 | |
frizzle101101 | 883ad5d026 | |
frizzle101101 | 7e847ab8dc | |
frizzle101101 | 7e18501d3a | |
frizzle101101 | 82c0c892f6 | |
frizzle101101 | 9c0b4d14f5 | |
frizzle101101 | 67b65eed1c | |
frizzle101101 | 39eba045cc | |
frizzle101101 | 033f57bfdb | |
frizzle101101 | c50f20df0e | |
frizzle101101 | 11cbc29b25 | |
frizzle101101 | 42eb8c6638 |
|
@ -31,7 +31,7 @@ jobs:
|
|||
run: Remove-Item roms -Recurse -Force -ErrorAction SilentlyContinue ; cp -r ../roms .
|
||||
|
||||
- name: Extract Assets
|
||||
run: python setup.py -b EUR_MQD
|
||||
run: python3 setup.py -b EUR_MQD
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
*.dll
|
||||
*.so
|
||||
*.o
|
||||
*.swp
|
||||
/projects/unix/_obj*/
|
||||
/hidapi-win
|
||||
/hidapi-win.zip
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 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,26 @@
|
|||
Mupen64Plus-Input-raphnetraw INSTALL
|
||||
-----------------------------
|
||||
|
||||
This text file was written to explain the installation process of the
|
||||
Mupen64Plus-Input-raphnetraw 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-Input-raphnetraw 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>
|
||||
|
||||
|
|
@ -0,0 +1,377 @@
|
|||
Mupen64Plus-input-raphnetraw LICENSE
|
||||
-----------------------------
|
||||
|
||||
Mupen64Plus-input-raphnetraw is licensed under the GNU General Public License version 2.
|
||||
|
||||
The author of Mupen64Plus-input-raphnetraw is:
|
||||
* Raphaël Assénat (raphnet)
|
||||
|
||||
Mupen64Plus-input-raphnetraw is based on Mupen64Plus-input-sdl, its authors being:
|
||||
* Richard Goedeken (Richard42)
|
||||
* Sven Eckelmann (ecsv)
|
||||
* John Chadwick (NMN)
|
||||
* James Hood (Ebenblues)
|
||||
* Scott Gorman (okaygo)
|
||||
* Scott Knauert (Tillin9)
|
||||
* Jesse Dean (DarkJezter)
|
||||
* Louai Al-Khanji (slougi)
|
||||
* Bob Forder (orbitaldecay)
|
||||
* Jason Espinosa (hasone)
|
||||
* Bobby Smiles (bsmiles32)
|
||||
* conchurnavid
|
||||
* Fayvel
|
||||
* HyperHacker
|
||||
* Nebuleon
|
||||
* s-verma
|
||||
* and others.
|
||||
|
||||
Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by:
|
||||
* Hacktarux
|
||||
* Dave2001
|
||||
* Zilmar
|
||||
* Gregor Anich (Blight)
|
||||
* Juha Luotio (JttL)
|
||||
* 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,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_PRINTF;_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck Condition="$(PlatformToolsetVersion)<140">true</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Debug"
|
||||
InheritedPropertySheets=".\Default.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG;DEBUG"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="false"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="false"
|
||||
EnableFiberSafeOptimizations="false"
|
||||
WholeProgramOptimization="false"
|
||||
BasicRuntimeChecks="3"
|
||||
SmallerTypeCheck="true"
|
||||
RuntimeLibrary="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
ProfileGuidedDatabase=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG;DEBUG"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG;DEBUG"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,183 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Default"
|
||||
OutputDirectory="$(Root)bin/$(ConfigurationName)"
|
||||
IntermediateDirectory="$(Root)build/$(ConfigurationName)/$(ProjectName)"
|
||||
InheritedPropertySheets=".\Root.vsprops"
|
||||
DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath)"
|
||||
BuildLogFile="$(IntDir)\BuildLog.htm"
|
||||
UseOfMFC="2"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile="$(OutDir)\$(ProjectName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UseUnicodeResponseFiles="true"
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS"
|
||||
IgnoreStandardIncludePath="false"
|
||||
GeneratePreprocessedFile="0"
|
||||
KeepComments="false"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="2"
|
||||
BasicRuntimeChecks="0"
|
||||
SmallerTypeCheck="false"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
FloatingPointExceptions="false"
|
||||
DisableLanguageExtensions="false"
|
||||
DefaultCharIsUnsigned="false"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="false"
|
||||
OpenMP="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="StdAfx.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
ExpandAttributedSource="false"
|
||||
AssemblerOutput="0"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
|
||||
GenerateXMLDocumentationFiles="false"
|
||||
XMLDocumentationFileName="$(IntDir)\"
|
||||
BrowseInformation="0"
|
||||
BrowseInformationFile="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
WarnAsError="false"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
CompileAs="0"
|
||||
ShowIncludes="false"
|
||||
UndefineAllPreprocessorDefinitions="false"
|
||||
EnablePREfast="false"
|
||||
UseFullPaths="false"
|
||||
OmitDefaultLibName="false"
|
||||
ErrorReporting="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\lib\$(ProjectName).lib"
|
||||
UseUnicodeResponseFiles="true"
|
||||
LinkLibraryDependencies="true"
|
||||
AdditionalLibraryDirectories=""
|
||||
SuppressStartupBanner="true"
|
||||
IgnoreAllDefaultLibraries="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RegisterOutput="false"
|
||||
PerUserRedirection="false"
|
||||
IgnoreImportLibrary="false"
|
||||
LinkLibraryDependencies="true"
|
||||
UseLibraryDependencyInputs="false"
|
||||
UseUnicodeResponseFiles="true"
|
||||
AdditionalOptions="/IGNORE:4199 /OPT:ICF=3"
|
||||
ShowProgress="0"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories=""
|
||||
ManifestFile="$(IntDir)\$(TargetFileName).intermediate.manifest"
|
||||
IgnoreAllDefaultLibraries="false"
|
||||
ModuleDefinitionFile=""
|
||||
DelayLoadDLLs="advapi32.dll;userenv.dll;shell32.dll;shlwapi.dll;ws2_32.dll;version.dll;wtsapi32.dll"
|
||||
IgnoreEmbeddedIDL="false"
|
||||
TypeLibraryResourceID="1"
|
||||
GenerateDebugInformation="true"
|
||||
AssemblyDebug="0"
|
||||
ProgramDatabaseFile="$(TargetDir)pdb/$(TargetName).pdb"
|
||||
GenerateMapFile="true"
|
||||
MapFileName="$(TargetDir)map/$(TargetName).map"
|
||||
MapExports="false"
|
||||
HeapReserveSize="0"
|
||||
HeapCommitSize="0"
|
||||
StackReserveSize="0"
|
||||
StackCommitSize="0"
|
||||
LargeAddressAware="0"
|
||||
TerminalServerAware="0"
|
||||
SwapRunFromCD="false"
|
||||
SwapRunFromNet="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ProfileGuidedDatabase=""
|
||||
ResourceOnlyDLL="false"
|
||||
SetChecksum="false"
|
||||
RandomizedBaseAddress="1"
|
||||
FixedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TurnOffAssemblyGeneration="false"
|
||||
SupportUnloadOfDelayLoadedDLL="false"
|
||||
ImportLibrary="$(TargetDir)lib/$(TargetName).lib"
|
||||
DelaySign="false"
|
||||
Profile="false"
|
||||
CLRThreadAttribute="0"
|
||||
CLRImageType="0"
|
||||
ErrorReporting="1"
|
||||
CLRUnmanagedCodeCheck="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
AdditionalIncludeDirectories=".;$(SRC);$(SRC)\3rd Party"
|
||||
IgnoreStandardIncludePath="false"
|
||||
MkTypLibCompatible="false"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
SuppressStartupBanner="true"
|
||||
DefaultCharType="0"
|
||||
GenerateStublessProxies="true"
|
||||
GenerateTypeLibrary="true"
|
||||
TypeLibraryName="$(IntDir)\$(InputName).tlb"
|
||||
HeaderFileName="$(InputName)_h.h"
|
||||
DLLDataFileName=""
|
||||
InterfaceIdentifierFileName="$(InputName)_i.c"
|
||||
ProxyFileName="$(InputName)_p.c"
|
||||
EnableErrorChecks="2"
|
||||
ErrorCheckAllocations="false"
|
||||
ErrorCheckBounds="false"
|
||||
ErrorCheckEnumRange="false"
|
||||
ErrorCheckRefPointers="false"
|
||||
ErrorCheckStubData="false"
|
||||
ValidateParameters="true"
|
||||
StructMemberAlignment="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
Culture="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
IgnoreStandardIncludePath="false"
|
||||
ShowProgress="false"
|
||||
ResourceOutputFileName="$(IntDir)\$(InputName).res"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
UseUnicodeResponseFiles="true"
|
||||
OutputManifestFile="$(IntDir)\$(TargetFileName).embed.manifest"
|
||||
ManifestResourceFile="$(IntDir)\$(TargetFileName).embed.manifest.res"
|
||||
EmbedManifest="true"
|
||||
DependencyInformationFile="$(IntDir)\mt.dep"
|
||||
UseFAT32Workaround="false"
|
||||
SuppressStartupBanner="true"
|
||||
VerboseOutput="false"
|
||||
GenerateCatalogFiles="false"
|
||||
UpdateFileHashes="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
UseUnicodeResponseFiles="true"
|
||||
DocumentLibraryDependencies="true"
|
||||
SuppressStartupBanner="true"
|
||||
ValidateIntelliSense="false"
|
||||
OutputDocumentFile="$(TargetDir)$(TargetName).xml"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,185 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<PropertyGroup Label="Configuration">
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ExtensionsToDeleteOnClean>*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
|
||||
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<LinkDelaySign>false</LinkDelaySign>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog.htm</Path>
|
||||
</BuildLog>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
|
||||
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>Not Set</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<FloatingPointExceptions>false</FloatingPointExceptions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<AdditionalOptions />
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>StdAfx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
<ExpandAttributedSource>false</ExpandAttributedSource>
|
||||
<AssemblerOutput />
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(VisualStudioVersion).pdb</ProgramDataBaseFileName>
|
||||
<GenerateXMLDocumentationFiles>false</GenerateXMLDocumentationFiles>
|
||||
<XMLDocumentationFileName>$(IntDir)</XMLDocumentationFileName>
|
||||
<BrowseInformation />
|
||||
<BrowseInformationFile>$(IntDir)</BrowseInformationFile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<ShowIncludes>false</ShowIncludes>
|
||||
<UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<OmitDefaultLibName>false</OmitDefaultLibName>
|
||||
<ErrorReporting>Prompt</ErrorReporting>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName).lib</OutputFile>
|
||||
<UseUnicodeResponseFiles>true</UseUnicodeResponseFiles>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
</Lib>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
<RegisterOutput>false</RegisterOutput>
|
||||
<PerUserRedirection>false</PerUserRedirection>
|
||||
<AdditionalOptions>/IGNORE:4199 /OPT:ICF=3 %(AdditionalOptions)</AdditionalOptions>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<ManifestFile>$(IntDir)$(TargetFileName).intermediate.manifest</ManifestFile>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<ModuleDefinitionFile />
|
||||
<DelayLoadDLLs>advapi32.dll;userenv.dll;shell32.dll;shlwapi.dll;ws2_32.dll;version.dll;wtsapi32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<IgnoreEmbeddedIDL>false</IgnoreEmbeddedIDL>
|
||||
<TypeLibraryResourceID>1</TypeLibraryResourceID>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AssemblyDebug />
|
||||
<ProgramDatabaseFile>$(TargetDir)pdb\$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapFileName>$(TargetDir)map\$(TargetName).map</MapFileName>
|
||||
<MapExports>false</MapExports>
|
||||
<HeapReserveSize>0</HeapReserveSize>
|
||||
<HeapCommitSize>0</HeapCommitSize>
|
||||
<StackReserveSize>0</StackReserveSize>
|
||||
<StackCommitSize>0</StackCommitSize>
|
||||
<LargeAddressAware />
|
||||
<TerminalServerAware />
|
||||
<SwapRunFromCD>false</SwapRunFromCD>
|
||||
<SwapRunFromNET>false</SwapRunFromNET>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ProfileGuidedDatabase />
|
||||
<NoEntryPoint>false</NoEntryPoint>
|
||||
<SetChecksum>false</SetChecksum>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<FixedBaseAddress>false</FixedBaseAddress>
|
||||
<DataExecutionPrevention />
|
||||
<TurnOffAssemblyGeneration>false</TurnOffAssemblyGeneration>
|
||||
<SupportUnloadOfDelayLoadedDLL>false</SupportUnloadOfDelayLoadedDLL>
|
||||
<ImportLibrary>$(TargetDir)lib\$(TargetName).lib</ImportLibrary>
|
||||
<Profile>false</Profile>
|
||||
<CLRThreadAttribute>DefaultThreadingAttribute</CLRThreadAttribute>
|
||||
<CLRImageType>Default</CLRImageType>
|
||||
<LinkErrorReporting>PromptImmediately</LinkErrorReporting>
|
||||
<CLRUnmanagedCodeCheck>false</CLRUnmanagedCodeCheck>
|
||||
<ProfileGuidedDatabase />
|
||||
</Link>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;$(SolutionDir)\3rd Party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||
<WarningLevel>3</WarningLevel>
|
||||
<WarnAsError>false</WarnAsError>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DefaultCharType>Unsigned</DefaultCharType>
|
||||
<GenerateStublessProxies>true</GenerateStublessProxies>
|
||||
<GenerateTypeLibrary>true</GenerateTypeLibrary>
|
||||
<TypeLibraryName>$(IntDir)%(Filename).tlb</TypeLibraryName>
|
||||
<HeaderFileName>%(Filename)_h.h</HeaderFileName>
|
||||
<DllDataFileName />
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
<EnableErrorChecks>All</EnableErrorChecks>
|
||||
<ErrorCheckAllocations>false</ErrorCheckAllocations>
|
||||
<ErrorCheckBounds>false</ErrorCheckBounds>
|
||||
<ErrorCheckEnumRange>false</ErrorCheckEnumRange>
|
||||
<ErrorCheckRefPointers>false</ErrorCheckRefPointers>
|
||||
<ErrorCheckStubData>false</ErrorCheckStubData>
|
||||
<ValidateAllParameters>true</ValidateAllParameters>
|
||||
<StructMemberAlignment>NotSet</StructMemberAlignment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0000</Culture>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<ShowProgress>false</ShowProgress>
|
||||
<ResourceOutputFileName>$(IntDir)%(Filename).res</ResourceOutputFileName>
|
||||
</ResourceCompile>
|
||||
<Manifest>
|
||||
<OutputManifestFile>$(IntDir)$(TargetFileName).embed.manifest</OutputManifestFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<VerboseOutput>false</VerboseOutput>
|
||||
<GenerateCatalogFiles>false</GenerateCatalogFiles>
|
||||
<UpdateFileHashes>false</UpdateFileHashes>
|
||||
</Manifest>
|
||||
<ManifestResourceCompile>
|
||||
<ResourceOutputFileName>$(IntDir)$(TargetFileName).embed.manifest.res</ResourceOutputFileName>
|
||||
</ManifestResourceCompile>
|
||||
<Xdcmake>
|
||||
<DocumentLibraryDependencies>true</DocumentLibraryDependencies>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>$(TargetDir)$(TargetName).xml</OutputFile>
|
||||
</Xdcmake>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!--Dummy Microsoft Common targets-->
|
||||
<Target Name="_ConvertPdbFiles" />
|
||||
<Target Name="_CollectPdbFiles" />
|
||||
<Target Name="_CollectMdbFiles" />
|
||||
<Target Name="_CopyMdbFiles" />
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Release"
|
||||
InheritedPropertySheets=".\Default.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="1"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="false"
|
||||
FavorSizeOrSpeed="2"
|
||||
OmitFramePointers="false"
|
||||
EnableFiberSafeOptimizations="false"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
SmallerTypeCheck="false"
|
||||
RuntimeLibrary="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
ProfileGuidedDatabase=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Win32.Debug"
|
||||
InheritedPropertySheets=".\Win32.vsprops;.\Debug.vsprops;"
|
||||
>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Win32.Release"
|
||||
InheritedPropertySheets=".\Win32.vsprops;.\Release.vsprops"
|
||||
>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="PlatformBase.props"/>
|
||||
</ImportGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ConfigurationType)'=='StaticLibrary'">
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<EnableEnhancedInstructionSet></EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;_WIN32;_WINDOWS;WIN32_LEAN_AND_MEAN"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Root"
|
||||
>
|
||||
<UserMacro
|
||||
Name="ROOT"
|
||||
Value="$(SolutionDir)"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="SRC"
|
||||
Value="$(ROOT)Source\"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="PlatformBase.props" />
|
||||
</ImportGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)64\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(Configuration)64\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ConfigurationType)'=='StaticLibrary'">
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)64\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,159 @@
|
|||
# Input plugin with direct N64 controller access for raphnet adapters
|
||||
|
||||
This mupen64plus plugin uses the direct controller access feature offered by my N64 to USB
|
||||
adapters (versions 3 and up) to let the emulated game communicate with the controllers directly.
|
||||
|
||||
* Perfect accuracy: The controller works exactly as it would on a N64 system, without any calibration or tweaking.
|
||||
* Rumble Pak and Controller Pak (mempak) support (and potentially other accesories too [not confirmed])
|
||||
* Support for other peripherals that connect to controller ports (eg: N64 mouse) [not confirmed]
|
||||
* Low latency
|
||||
|
||||
## Project homepage
|
||||
|
||||
* English: [Direct N64 controller access plugin mupen64plus](http://raphnet.net/programmation/mupen64plus-input-raphnetraw/index_en.php)
|
||||
* French: [Plugin d'accès direct aux manettes N64 pour mupen64plus](http://raphnet.net/programmation/mupen64plus-input-raphnetraw/index.php)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the GNU General Public License, version 2.
|
||||
Source code is available on the project homepage and on GitHub.
|
||||
|
||||
## How to use the plugin
|
||||
|
||||
Regardless of your operating system, you will need to install the plugin file(s)
|
||||
in a directory mupen64plus will search for plugins (eg: Along the other plugin files).
|
||||
Then, you must tell mupen64plus to use it. eg:
|
||||
|
||||
```
|
||||
mupen64plus --input mupen64plus-input-raphnetraw
|
||||
```
|
||||
|
||||
Where to obtain the plugin files is described below.
|
||||
|
||||
### Linux
|
||||
|
||||
Please compile it from sources (howto below). This will generate mupen64plus-input-raphnetraw.so
|
||||
for your architecture.
|
||||
|
||||
### Windows (32 and 64 bit)
|
||||
|
||||
You may use the releases distributed by raphnet in a zip file. The file contents will look
|
||||
like this:
|
||||
|
||||
```
|
||||
mupen64plus-input-raphnetraw-windows-0.9/
|
||||
mupen64plus-input-raphnetraw-windows-0.9/README.md
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win64/
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win64/libhidapi-0.dll
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win64/mupen64plus-input-raphnetraw.dll
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win32/
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win32/libhidapi-0.dll
|
||||
mupen64plus-input-raphnetraw-windows-0.9/dist_win32/mupen64plus-input-raphnetraw.dll
|
||||
```
|
||||
|
||||
If you use a 64-bit version of mupen64plus, copy the files from the `dist_win64` directory. For
|
||||
the 32-bit version, copy the files from the `dist_win32` directory.
|
||||
|
||||
## Compiling the Linux / Unix version
|
||||
|
||||
### Prerequesites
|
||||
|
||||
A Linux system such as Debian with the following packages installed: (non-exhaustive list)
|
||||
|
||||
* gcc
|
||||
* make
|
||||
* libhidapi-hidraw0
|
||||
* libhidapi-dev
|
||||
|
||||
### Environment
|
||||
|
||||
#### Directory layout
|
||||
|
||||
The input-raphnetraw plugin requires a checkout of mupen64plus-core (for the plugin api headers).
|
||||
|
||||
* ...somedir/mupen64plus-input-raphnetraw
|
||||
* ...somedir/mupen64plus-core
|
||||
|
||||
#### Compilation
|
||||
|
||||
```sh
|
||||
$ cd .../somedir/
|
||||
$ cd mupen64plus-input-raphnetraw/projects/unix
|
||||
$ make all
|
||||
|
||||
# then, assuming all went well:
|
||||
$ cp mupen64plus-input-raphnetraw.so /your/mupen64plus-plugin-directory
|
||||
|
||||
# or, if you passed an appropriate PREFIX to make, you can just:
|
||||
$ make install
|
||||
```
|
||||
|
||||
## Win32/64 cross-compilation under Linux
|
||||
|
||||
### System requirements
|
||||
|
||||
A Linux system such as Debian with the following packages installed: (non-exhaustive list)
|
||||
|
||||
* mingw-w64
|
||||
* autotools-dev
|
||||
* autoconf
|
||||
* automake
|
||||
* libtool
|
||||
* git
|
||||
* make
|
||||
|
||||
### Environment
|
||||
|
||||
#### Directory layout
|
||||
|
||||
The input-raphnetraw plugin requires a checkout of mupen64plus-core (for the plugin api headers) in the
|
||||
parent directory. Also, each version (32 or 64 bit) requires a matching hidapi build.
|
||||
|
||||
* ...somedir/mupen64plus-input-raphnetraw
|
||||
* ...somedir/mupen64plus-core
|
||||
* ...somedir/hidapi
|
||||
* ...somedir/hidapi64
|
||||
|
||||
#### preparing the hidapi build
|
||||
|
||||
The buildwin32.sh and buildwin64.sh scripts assume the following:
|
||||
|
||||
* For the 32-bit build an hidapi configured and compiled with --host i686-w64-mingw32 is required here: ../../../hidapi
|
||||
* For the 64-bit build an hidapi configured and compiled with --host x86_64-w64-mingw32 is required here: ../../../hidapi64
|
||||
|
||||
hidapi can be obtained like this:
|
||||
|
||||
```sh
|
||||
$ cd ...somedir
|
||||
$ git clone https://github.com/signal11/hidapi.git
|
||||
$ git clone hidapi hidapi64
|
||||
```
|
||||
|
||||
And then to compile the win32 version:
|
||||
```sh
|
||||
cd ...somedir/hidapi
|
||||
./bootstrap
|
||||
./configure --host i686-w64-mingw32
|
||||
make
|
||||
```
|
||||
|
||||
And the win64 version:
|
||||
```sh
|
||||
cd ...somedir/hidapi64
|
||||
./bootstrap
|
||||
./configure --host x86_64-w64-mingw32
|
||||
make
|
||||
```
|
||||
|
||||
#### Compilation
|
||||
|
||||
This would cross-compile the 32 and 64-bit windows versions.
|
||||
|
||||
```bash
|
||||
$ cd .../somedir/
|
||||
$ cd mupen64plus-input-raphnetraw/projects/unix
|
||||
|
||||
# 32-bit version
|
||||
$./buildwin32.sh
|
||||
$ ./buildwin64.sh
|
||||
```
|
|
@ -0,0 +1,43 @@
|
|||
# Raphnet raw Input plugin for Mupen64Plus
|
||||
--------------------------------
|
||||
|
||||
## v1.1.0 - July 16, 2019
|
||||
|
||||
* Update to input plugin API 2.1.0
|
||||
|
||||
## v1.0.2 - November 6, 2018
|
||||
|
||||
* Add support for the 3.6.x adapter firmware
|
||||
|
||||
## v1.0.1 - November 22, 2017
|
||||
|
||||
* Add support for the upcoming 3.5.x adapter firmware
|
||||
(2-player adapters won't work properly otherwise)
|
||||
|
||||
## v1.0.0 - January 15, 2017
|
||||
|
||||
* Support for multiple adapters
|
||||
|
||||
## v0.9.4 - December 3, 2016
|
||||
|
||||
* Improved structure and separation for easier maintenance of the code shared between the Project 64 and mupen64plus versions of this plugin.
|
||||
* Support for the upcoming 3.4.x adapter firmware (will provide even lower latency/overhead)
|
||||
|
||||
## v0.9.3 - November 26, 2016
|
||||
|
||||
* Only handle channels supported by the adapter. This increases performance (reduces lag) by
|
||||
preventing meaningless attempts to communicate with controllers connected to non-existing
|
||||
ports on the adapter. It also fixes issues where games would see more than one controller was present.
|
||||
|
||||
## v0.9.2 - November 24, 2016
|
||||
|
||||
* Protect against invalid commands received from emulator. This fixes some games that failed to start.
|
||||
|
||||
## v0.9.1 - November 23, 2016
|
||||
|
||||
* Polling is now disabled only while a ROM is open.
|
||||
|
||||
## v0.9.0 - November 20, 2016
|
||||
|
||||
* Initial release
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
# * Mupen64plus-input-raphnetraw - Makefile *
|
||||
# * Copyright (C) 2016 Raphael Assenat *
|
||||
# * *
|
||||
# * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU General Public License as published by *
|
||||
# * the Free Software Foundation; either version 2 of the License, or *
|
||||
# * (at your option) any later version. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU General Public 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 raphnetraw Input plugin in Mupen64plus
|
||||
|
||||
# detect operating system
|
||||
UNAME ?= $(shell uname -s)
|
||||
OS := NONE
|
||||
ifeq ("$(UNAME)","Linux")
|
||||
OS = LINUX
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifeq ("$(UNAME)","linux")
|
||||
OS = LINUX
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifneq ("$(filter GNU hurd,$(UNAME))","")
|
||||
OS = LINUX
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifeq ("$(UNAME)","Darwin")
|
||||
OS = OSX
|
||||
SO_EXTENSION = dylib
|
||||
SHARED = -bundle
|
||||
endif
|
||||
ifeq ("$(UNAME)","FreeBSD")
|
||||
OS = FREEBSD
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifeq ("$(UNAME)","OpenBSD")
|
||||
OS = FREEBSD
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","")
|
||||
OS = LINUX
|
||||
SO_EXTENSION = so
|
||||
SHARED = -shared
|
||||
endif
|
||||
ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW")
|
||||
OS = MINGW
|
||||
SO_EXTENSION = dll
|
||||
SHARED = -shared
|
||||
PIC = 0
|
||||
endif
|
||||
ifeq ("$(OS)","NONE")
|
||||
$(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
|
||||
endif
|
||||
|
||||
# detect system architecture, only if it matters for build flags
|
||||
HOST_CPU ?= $(shell uname -m)
|
||||
CPU := OTHER
|
||||
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
|
||||
ifeq ("$(CPU)","OTHER")
|
||||
PIC ?= 1
|
||||
endif
|
||||
|
||||
# base CFLAGS, LDLIBS, and LDFLAGS
|
||||
OPTFLAGS ?= -O3 -flto
|
||||
WARNFLAGS ?= -Wall
|
||||
CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src -D_GNU_SOURCE=1
|
||||
LDFLAGS += $(SHARED)
|
||||
LDLIBS += -lm
|
||||
|
||||
# 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
|
||||
|
||||
# tweak flags for 32-bit build on 64-bit system
|
||||
ifeq ($(ARCH_DETECTED), 64BITS_32)
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -Wl,-m,elf_i386
|
||||
endif
|
||||
|
||||
# set special flags per-system
|
||||
ifeq ($(OS), FREEBSD)
|
||||
ifeq ($(ARCH_DETECTED), 64BITS_32)
|
||||
$(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OS), LINUX)
|
||||
LDLIBS += -ldl
|
||||
endif
|
||||
ifeq ($(OS), OSX)
|
||||
#xcode-select has been around since XCode 3.0, i.e. OS X 10.5
|
||||
OSX_SDK_ROOT = $(shell xcode-select -print-path)/Platforms/MacOSX.platform/Developer/SDKs
|
||||
OSX_SDK_PATH = $(OSX_SDK_ROOT)/$(shell ls $(OSX_SDK_ROOT) | tail -1)
|
||||
|
||||
ifeq ($(CPU), X86)
|
||||
ifeq ($(ARCH_DETECTED), 64BITS)
|
||||
CFLAGS += -arch x86_64 -mmacosx-version-min=10.5 -isysroot $(OSX_SDK_PATH)
|
||||
LDLIBS += -ldl
|
||||
else
|
||||
CFLAGS += -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=10.5 -isysroot $(OSX_SDK_PATH)
|
||||
LDLIBS += -ldl -read_only_relocs suppress
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), LINUX)
|
||||
HIDAPI_NAME=hidapi-hidraw
|
||||
else
|
||||
HIDAPI_NAME=hidapi
|
||||
endif
|
||||
|
||||
# test for presence of HIDLIB
|
||||
ifeq ($(origin HID_CFLAGS) $(origin HID_LDLIBS), undefined undefined)
|
||||
HIDAPI_CONFIG = $(CROSS_COMPILE)pkg-config $(HIDAPI_NAME)
|
||||
ifeq ($(shell which $(HIDAPI_CONFIG) 2>/dev/null),)
|
||||
HIDAPI_CONFIG = $(CROSS_COMPILE)pkg-config $(HIDAPI_NAME)
|
||||
ifeq ($(shell which $(HIDAPI_CONFIG) 2>/dev/null),)
|
||||
$(error No HIDAPI development libraries found!)
|
||||
else
|
||||
$(warning Using HIDAPI libraries)
|
||||
endif
|
||||
endif
|
||||
HID_CFLAGS += $(shell $(HIDAPI_CONFIG) --cflags)
|
||||
HID_LDLIBS += $(shell $(HIDAPI_CONFIG) --libs)
|
||||
endif
|
||||
CFLAGS += $(HID_CFLAGS)
|
||||
LDLIBS += $(HID_LDLIBS)
|
||||
|
||||
# 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_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
|
||||
LINK.o = $(Q_LD)$(CC) $(CFLAGS) $(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 ($(PLUGINDBG), 1)
|
||||
CFLAGS += -D_DEBUG
|
||||
endif
|
||||
ifeq ($(PORTS_1_AND_4), 1)
|
||||
CFLAGS += -DPORTS_1_AND_4
|
||||
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)/plugin_front.c \
|
||||
$(SRCDIR)/plugin_back.c \
|
||||
$(SRCDIR)/gcn64lib.c \
|
||||
$(SRCDIR)/gcn64.c \
|
||||
$(SRCDIR)/hexdump.c
|
||||
|
||||
ifeq ($(OS),MINGW)
|
||||
SOURCE += $(SRCDIR)/osal_dynamiclib_win32.c
|
||||
else
|
||||
SOURCE += $(SRCDIR)/osal_dynamiclib_unix.c
|
||||
endif
|
||||
|
||||
# generate a list of object files build, make a temporary directory for them
|
||||
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(filter %.c, $(SOURCE)))
|
||||
OBJDIRS = $(dir $(OBJECTS))
|
||||
$(shell $(MKDIR) $(OBJDIRS))
|
||||
|
||||
# build targets
|
||||
TARGET = mupen64plus-input-raphnetraw$(POSTFIX).$(SO_EXTENSION)
|
||||
|
||||
targets:
|
||||
@echo "Mupen64Plus-input-raphnetraw makefile. "
|
||||
@echo " Targets:"
|
||||
@echo " all == Build Mupen64Plus raphnetraw input plugin"
|
||||
@echo " clean == remove object files"
|
||||
@echo " rebuild == clean and re-build all"
|
||||
@echo " install == Install Mupen64Plus raphnetraw input plugin"
|
||||
@echo " uninstall == Uninstall Mupen64Plus raphnetraw input plugin"
|
||||
@echo " Options:"
|
||||
@echo " BITS=32 == build 32-bit binaries on 64-bit machine"
|
||||
@echo " APIDIR=path == path to find Mupen64Plus Core headers"
|
||||
@echo " OPTFLAGS=flag == compiler optimization (default: -O3 -flto)"
|
||||
@echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)"
|
||||
@echo " PIC=(1|0) == Force enable/disable of position independent code"
|
||||
@echo " POSTFIX=name == String added to the name of the the build (default: '')"
|
||||
@echo " Install Options:"
|
||||
@echo " PREFIX=path == install/uninstall prefix (default: /usr/local)"
|
||||
@echo " 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 " PLUGINDBG=1 == print extra debugging information while running"
|
||||
@echo " V=1 == show verbose compiler output"
|
||||
@echo " Build Options, tweaks:"
|
||||
@echo " PORTS_1_AND_4 == N64 port 4 -> Adapter port 2"
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
install: $(TARGET)
|
||||
$(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
|
||||
$(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
|
||||
$(INSTALL) -d "$(DESTDIR)$(SHAREDIR)"
|
||||
|
||||
uninstall:
|
||||
$(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
|
||||
$(RM) "$(DESTDIR)$(SHAREDIR)/InputAutoCfg.ini"
|
||||
|
||||
clean:
|
||||
$(RM) -r $(OBJDIR) $(TARGET)
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
# build dependency files
|
||||
CFLAGS += -MD -MP
|
||||
-include $(OBJECTS:.o=.d)
|
||||
|
||||
# standard build rules
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||
$(COMPILE.c) -o $@ $<
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
|
||||
.PHONY: all clean install uninstall targets
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
HIDHOME=../../../hidapi
|
||||
UNAME=MINGW32
|
||||
DESTDIR=./dist_win32
|
||||
|
||||
HID_CFLAGS="-I $HIDHOME/hidapi"
|
||||
HID_LDLIBS="-L $HIDHOME/windows/.libs/ -lhidapi"
|
||||
TARGETS=all
|
||||
MAKEFILE=Makefile
|
||||
|
||||
make -f $MAKEFILE clean
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make -f $MAKEFILE CROSS_COMPILE=i686-w64-mingw32- UNAME=$UNAME HID_CFLAGS="$HID_CFLAGS" HID_LDLIBS="$HID_LDLIBS" $TARGETS V=1
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $DESTDIR
|
||||
cp mupen64plus-input-raphnetraw.dll $DESTDIR -v
|
||||
cp $HIDHOME/windows/.libs/*.dll $DESTDIR -v
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
|
||||
HIDHOME=../../../hidapi64
|
||||
UNAME=MINGW64
|
||||
DESTDIR=./dist_win64
|
||||
|
||||
HID_CFLAGS="-I $HIDHOME/hidapi"
|
||||
HID_LDLIBS="-L $HIDHOME/windows/.libs/ -lhidapi"
|
||||
TARGETS=all
|
||||
MAKEFILE=Makefile
|
||||
|
||||
make -f $MAKEFILE clean
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make -f $MAKEFILE CROSS_COMPILE=x86_64-w64-mingw32- UNAME=$UNAME HID_CFLAGS="$HID_CFLAGS" HID_LDLIBS="$HID_LDLIBS" $TARGETS V=1
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $DESTDIR
|
||||
cp mupen64plus-input-raphnetraw.dll $DESTDIR -v
|
||||
cp $HIDHOME/windows/.libs/*.dll $DESTDIR -v
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
|
||||
PREFIX=mupen64plus-input-raphnetraw
|
||||
HEXFILE=$PREFIX.hex
|
||||
|
||||
echo "Release script for $PREFIX"
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Syntax: ./release.sh version releasedir"
|
||||
echo
|
||||
echo "ex: './release 1.0' will produce $PREFIX-1.0.tar.gz in releasedir out of git HEAD,"
|
||||
echo "and place it in the release directory."
|
||||
echo
|
||||
echo "It will also create a tag named v1.0"
|
||||
exit
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
RELEASEDIR=$2
|
||||
DIRNAME=$PREFIX-$VERSION
|
||||
FILENAME=$PREFIX-$VERSION.tar.gz
|
||||
TAG=v$VERSION
|
||||
|
||||
echo "Version: $VERSION"
|
||||
echo "Filename: $FILENAME"
|
||||
echo "Release directory: $RELEASEDIR"
|
||||
echo "--------"
|
||||
echo "Ready? Press ENTER to go ahead (or CTRL+C to cancel)"
|
||||
|
||||
read
|
||||
|
||||
if [ -f $RELEASEDIR/$FILENAME ]; then
|
||||
echo "Release file already exists!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git tag $TAG -f
|
||||
git archive --format=tar --prefix=$DIRNAME/ HEAD | gzip > $RELEASEDIR/$FILENAME
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
|
||||
PROJECT=mupen64plus-input-raphnetraw-windows
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Syntax: ./release.sh version releasedir"
|
||||
echo
|
||||
exit
|
||||
fi
|
||||
|
||||
VERSION=$1
|
||||
RELEASEDIR=$2
|
||||
DIRNAME=$PROJECT-$VERSION
|
||||
FILENAME=$PROJECT-$VERSION.zip
|
||||
|
||||
if [ -d $RELEASEDIR/$DIRNAME ]; then
|
||||
echo "$RELEASEDIR/$DIRNAME already exists";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $RELEASEDIR/$DIRNAME
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not mkdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd projects/unix
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not chdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./buildwin32.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Win32 build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./buildwin64.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Win64 build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd .. # exit unix
|
||||
cd .. # exit projects
|
||||
|
||||
cp projects/unix/dist_win32 -rv $RELEASEDIR/$DIRNAME
|
||||
cp projects/unix/dist_win64 -rv $RELEASEDIR/$DIRNAME
|
||||
cp README.md -rv $RELEASEDIR/$DIRNAME
|
||||
cp README.md -rv $RELEASEDIR/$DIRNAME/readme.txt
|
||||
cp RELEASE -rv $RELEASEDIR/$DIRNAME/releases.txt
|
||||
|
||||
cd $RELEASEDIR
|
||||
|
||||
zip -r $FILENAME $DIRNAME
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo -------------------------------------
|
||||
ls -lh $FILENAME
|
||||
echo Done
|
|
@ -0,0 +1,371 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2017 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "gcn64.h"
|
||||
#include "gcn64_priv.h"
|
||||
#include "gcn64lib.h"
|
||||
#include "requests.h"
|
||||
|
||||
#include "hidapi.h"
|
||||
|
||||
static int dusbr_verbose = 0;
|
||||
|
||||
#define IS_VERBOSE() (dusbr_verbose)
|
||||
|
||||
struct supported_adapter {
|
||||
uint16_t vid, pid;
|
||||
int if_number;
|
||||
struct gcn64_adapter_caps caps;
|
||||
};
|
||||
|
||||
static struct supported_adapter supported_adapters[] = {
|
||||
/* vid, pid, if_no, { n_raw, bio_support } */
|
||||
|
||||
{ OUR_VENDOR_ID, 0x0017, 1, { 1, 0 } }, // GC/N64 USB v3.0, 3.1.0, 3.1.1
|
||||
{ OUR_VENDOR_ID, 0x001D, 1, { 1, 0 } }, // GC/N64 USB v3.2.0 ... v3.3.x
|
||||
{ OUR_VENDOR_ID, 0x0020, 1, { 1, 0 } }, // GCN64->USB v3.2.1 (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0021, 1, { 1, 0 } }, // GCN64->USB v3.2.1 (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x0022, 1, { 2, 0 } }, // GCN64->USB v3.3.x (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0030, 1, { 2, 0 } }, // GCN64->USB v3.3.0 (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0031, 1, { 2, 0 } }, // GCN64->USB v3.3.0 (2x GC-only mode)
|
||||
|
||||
{ OUR_VENDOR_ID, 0x0032, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0033, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0034, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x0035, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0036, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0037, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x GC-only mode)
|
||||
|
||||
// GC/N64 USB v3.5.x flavours
|
||||
{ OUR_VENDOR_ID, 0x0038, 1, { 1, 1 } }, // (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0039, 1, { 1, 1 } }, // (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x003A, 1, { 1, 1 } }, // (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x003B, 2, { 2, 1 } }, // (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x003C, 2, { 2, 1 } }, // (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x003D, 2, { 2, 1 } }, // (2x GC-only mode)
|
||||
|
||||
// GC/N64 USB v3.6.x flavours
|
||||
{ OUR_VENDOR_ID, 0x0060, 1, { 1, 1 } }, // (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0061, 1, { 1, 1 } }, // (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0063, 2, { 2, 1 } }, // (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0064, 2, { 2, 1 } }, // (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0067, 1, { 1, 1 } }, // (GC/N64 in GC keyboard mode)
|
||||
|
||||
{ }, // terminator
|
||||
};
|
||||
|
||||
int gcn64_init(int verbose)
|
||||
{
|
||||
dusbr_verbose = verbose;
|
||||
hid_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gcn64_shutdown(void)
|
||||
{
|
||||
hid_exit();
|
||||
}
|
||||
|
||||
static char isProductIdHandled(unsigned short pid, int interface_number, struct gcn64_adapter_caps *caps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; supported_adapters[i].vid; i++) {
|
||||
if (pid == supported_adapters[i].pid) {
|
||||
if (interface_number == supported_adapters[i].if_number) {
|
||||
if (caps) {
|
||||
memcpy(caps, &supported_adapters[i].caps, sizeof (struct gcn64_adapter_caps));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct gcn64_list_ctx *gcn64_allocListCtx(void)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
ctx = calloc(1, sizeof(struct gcn64_list_ctx));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void gcn64_freeListCtx(struct gcn64_list_ctx *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
if (ctx->devs) {
|
||||
hid_free_enumeration(ctx->devs);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int gcn64_countDevices(void)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
struct gcn64_info inf;
|
||||
int count = 0;
|
||||
|
||||
ctx = gcn64_allocListCtx();
|
||||
while (gcn64_listDevices(&inf, ctx)) {
|
||||
count++;
|
||||
}
|
||||
gcn64_freeListCtx(ctx);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief List instances of our rgbleds device on the USB busses.
|
||||
* \param info Pointer to gcn64_info structure to store data
|
||||
* \param dst Destination buffer for device serial number/id.
|
||||
* \param dstbuf_size Destination buffer size.
|
||||
*/
|
||||
struct gcn64_info *gcn64_listDevices(struct gcn64_info *info, struct gcn64_list_ctx *ctx)
|
||||
{
|
||||
struct gcn64_adapter_caps caps;
|
||||
|
||||
memset(info, 0, sizeof(struct gcn64_info));
|
||||
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "gcn64_listDevices: Passed null context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->devs)
|
||||
goto jumpin;
|
||||
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Start listing\n");
|
||||
}
|
||||
|
||||
ctx->devs = hid_enumerate(OUR_VENDOR_ID, 0x0000);
|
||||
if (!ctx->devs) {
|
||||
printf("Hid enumerate returned NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ctx->cur_dev = ctx->devs; ctx->cur_dev; ctx->cur_dev = ctx->cur_dev->next)
|
||||
{
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Considering 0x%04x:0x%04x\n", ctx->cur_dev->vendor_id, ctx->cur_dev->product_id);
|
||||
}
|
||||
if (isProductIdHandled(ctx->cur_dev->product_id, ctx->cur_dev->interface_number, &caps))
|
||||
{
|
||||
info->usb_vid = ctx->cur_dev->vendor_id;
|
||||
info->usb_pid = ctx->cur_dev->product_id;
|
||||
wcsncpy(info->str_prodname, ctx->cur_dev->product_string, PRODNAME_MAXCHARS-1);
|
||||
wcsncpy(info->str_serial, ctx->cur_dev->serial_number, SERIAL_MAXCHARS-1);
|
||||
strncpy(info->str_path, ctx->cur_dev->path, PATH_MAXCHARS-1);
|
||||
memcpy(&info->caps, &caps, sizeof(info->caps));
|
||||
return info;
|
||||
}
|
||||
|
||||
jumpin:
|
||||
// prevent 'error: label at end of compound statement'
|
||||
continue;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gcn64_hdl_t gcn64_openDevice(struct gcn64_info *dev)
|
||||
{
|
||||
hid_device *hdev;
|
||||
gcn64_hdl_t hdl;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Opening device path: '%s'\n", dev->str_path);
|
||||
}
|
||||
|
||||
hdev = hid_open_path(dev->str_path);
|
||||
if (!hdev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdl = malloc(sizeof(struct _gcn64_hdl_t));
|
||||
if (!hdl) {
|
||||
perror("malloc");
|
||||
hid_close(hdev);
|
||||
return NULL;
|
||||
}
|
||||
hdl->hdev = hdev;
|
||||
hdl->report_size = 63;
|
||||
memcpy(&hdl->caps, &dev->caps, sizeof(hdl->caps));
|
||||
|
||||
if (!dev->caps.bio_support) {
|
||||
printf("Pre-3.4 version detected. Setting report size to 40 bytes\n");
|
||||
hdl->report_size = 40;
|
||||
}
|
||||
|
||||
return hdl;
|
||||
}
|
||||
|
||||
gcn64_hdl_t gcn64_openBy(struct gcn64_info *dev, unsigned char flags)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
struct gcn64_info inf;
|
||||
gcn64_hdl_t h;
|
||||
|
||||
if (IS_VERBOSE())
|
||||
printf("gcn64_openBy, flags=0x%02x\n", flags);
|
||||
|
||||
ctx = gcn64_allocListCtx();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
while (gcn64_listDevices(&inf, ctx)) {
|
||||
if (IS_VERBOSE())
|
||||
printf("Considering '%s'\n", inf.str_path);
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_SERIAL) {
|
||||
if (wcscmp(inf.str_serial, dev->str_serial))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_PATH) {
|
||||
if (strcmp(inf.str_path, dev->str_path))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_VID) {
|
||||
if (inf.usb_vid != dev->usb_vid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_PID) {
|
||||
if (inf.usb_pid != dev->usb_pid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_VERBOSE())
|
||||
printf("Found device. opening...\n");
|
||||
|
||||
h = gcn64_openDevice(&inf);
|
||||
gcn64_freeListCtx(ctx);
|
||||
return h;
|
||||
}
|
||||
|
||||
gcn64_freeListCtx(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void gcn64_closeDevice(gcn64_hdl_t hdl)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
|
||||
if (hdev) {
|
||||
hid_close(hdev);
|
||||
}
|
||||
|
||||
free(hdl);
|
||||
}
|
||||
|
||||
int gcn64_send_cmd(gcn64_hdl_t hdl, const unsigned char *cmd, int cmdlen)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
unsigned char buffer[hdl->report_size+1];
|
||||
int n;
|
||||
|
||||
if (cmdlen > (sizeof(buffer)-1)) {
|
||||
fprintf(stderr, "Error: Command too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
buffer[0] = 0x00; // report ID set to 0 (device has only one)
|
||||
memcpy(buffer + 1, cmd, cmdlen);
|
||||
|
||||
n = hid_send_feature_report(hdev, buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Could not send feature report (%ls)\n", hid_error(hdev));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64_poll_result(gcn64_hdl_t hdl, unsigned char *cmd, int cmd_maxlen)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
unsigned char buffer[hdl->report_size+1];
|
||||
int res_len;
|
||||
int n;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
buffer[0] = 0x00; // report ID set to 0 (device has only one)
|
||||
|
||||
n = hid_get_feature_report(hdev, buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Could not send feature report (%ls)\n", hid_error(hdev));
|
||||
return -1;
|
||||
}
|
||||
if (n==0) {
|
||||
return 0;
|
||||
}
|
||||
res_len = n-1;
|
||||
|
||||
if (res_len>0) {
|
||||
int copy_len;
|
||||
|
||||
copy_len = res_len;
|
||||
if (copy_len > cmd_maxlen) {
|
||||
copy_len = cmd_maxlen;
|
||||
}
|
||||
if (cmd) {
|
||||
memcpy(cmd, buffer+1, copy_len);
|
||||
}
|
||||
}
|
||||
|
||||
return res_len;
|
||||
}
|
||||
|
||||
int gcn64_exchange(gcn64_hdl_t hdl, unsigned char *outcmd, int outlen, unsigned char *result, int result_max)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gcn64_send_cmd(hdl, outcmd, outlen);
|
||||
if (n<0) {
|
||||
fprintf(stderr, "Error sending command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Answer to the command comes later. For now, this is polled, but in
|
||||
* the future an interrupt-in transfer could be used. */
|
||||
do {
|
||||
n = gcn64_poll_result(hdl, result, result_max);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error\r\n");
|
||||
break;
|
||||
}
|
||||
if (n==0) {
|
||||
// printf("."); fflush(stdout);
|
||||
}
|
||||
|
||||
} while (n==0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2017 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "gcn64.h"
|
||||
#include "gcn64_priv.h"
|
||||
#include "gcn64lib.h"
|
||||
#include "requests.h"
|
||||
|
||||
#include "hidapi.h"
|
||||
|
||||
static int dusbr_verbose = 0;
|
||||
|
||||
#define IS_VERBOSE() (dusbr_verbose)
|
||||
|
||||
struct supported_adapter {
|
||||
uint16_t vid, pid;
|
||||
int if_number;
|
||||
struct gcn64_adapter_caps caps;
|
||||
};
|
||||
|
||||
static struct supported_adapter supported_adapters[] = {
|
||||
/* vid, pid, if_no, { n_raw, bio_support } */
|
||||
|
||||
{ OUR_VENDOR_ID, 0x0017, 1, { 1, 0 } }, // GC/N64 USB v3.0, 3.1.0, 3.1.1
|
||||
{ OUR_VENDOR_ID, 0x001D, 1, { 1, 0 } }, // GC/N64 USB v3.2.0 ... v3.3.x
|
||||
{ OUR_VENDOR_ID, 0x0020, 1, { 1, 0 } }, // GCN64->USB v3.2.1 (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0021, 1, { 1, 0 } }, // GCN64->USB v3.2.1 (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x0022, 1, { 2, 0 } }, // GCN64->USB v3.3.x (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0030, 1, { 2, 0 } }, // GCN64->USB v3.3.0 (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0031, 1, { 2, 0 } }, // GCN64->USB v3.3.0 (2x GC-only mode)
|
||||
|
||||
{ OUR_VENDOR_ID, 0x0032, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0033, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0034, 1, { 1, 1 } }, // GC/N64 USB v3.4.x (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x0035, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0036, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0037, 1, { 2, 1 } }, // GC/N64 USB v3.4.x (2x GC-only mode)
|
||||
|
||||
// GC/N64 USB v3.5.x flavours
|
||||
{ OUR_VENDOR_ID, 0x0038, 1, { 1, 1 } }, // (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0039, 1, { 1, 1 } }, // (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x003A, 1, { 1, 1 } }, // (GC mode)
|
||||
{ OUR_VENDOR_ID, 0x003B, 2, { 2, 1 } }, // (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x003C, 2, { 2, 1 } }, // (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x003D, 2, { 2, 1 } }, // (2x GC-only mode)
|
||||
|
||||
// GC/N64 USB v3.6.x flavours
|
||||
{ OUR_VENDOR_ID, 0x0060, 1, { 1, 1 } }, // (GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0061, 1, { 1, 1 } }, // (N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0063, 2, { 2, 1 } }, // (2x GC/N64 mode)
|
||||
{ OUR_VENDOR_ID, 0x0064, 2, { 2, 1 } }, // (2x N64-only mode)
|
||||
{ OUR_VENDOR_ID, 0x0067, 1, { 1, 1 } }, // (GC/N64 in GC keyboard mode)
|
||||
|
||||
{ }, // terminator
|
||||
};
|
||||
|
||||
int gcn64_init(int verbose)
|
||||
{
|
||||
dusbr_verbose = verbose;
|
||||
hid_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gcn64_shutdown(void)
|
||||
{
|
||||
hid_exit();
|
||||
}
|
||||
|
||||
static char isProductIdHandled(unsigned short pid, int interface_number, struct gcn64_adapter_caps *caps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; supported_adapters[i].vid; i++) {
|
||||
if (pid == supported_adapters[i].pid) {
|
||||
if (interface_number == supported_adapters[i].if_number) {
|
||||
if (caps) {
|
||||
memcpy(caps, &supported_adapters[i].caps, sizeof (struct gcn64_adapter_caps));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct gcn64_list_ctx *gcn64_allocListCtx(void)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
ctx = (gcn64_list_ctx*)calloc(1, sizeof(struct gcn64_list_ctx));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void gcn64_freeListCtx(struct gcn64_list_ctx *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
if (ctx->devs) {
|
||||
hid_free_enumeration(ctx->devs);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int gcn64_countDevices(void)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
struct gcn64_info inf;
|
||||
int count = 0;
|
||||
|
||||
ctx = gcn64_allocListCtx();
|
||||
while (gcn64_listDevices(&inf, ctx)) {
|
||||
count++;
|
||||
}
|
||||
gcn64_freeListCtx(ctx);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief List instances of our rgbleds device on the USB busses.
|
||||
* \param info Pointer to gcn64_info structure to store data
|
||||
* \param dst Destination buffer for device serial number/id.
|
||||
* \param dstbuf_size Destination buffer size.
|
||||
*/
|
||||
struct gcn64_info *gcn64_listDevices(struct gcn64_info *info, struct gcn64_list_ctx *ctx)
|
||||
{
|
||||
struct gcn64_adapter_caps caps;
|
||||
|
||||
memset(info, 0, sizeof(struct gcn64_info));
|
||||
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "gcn64_listDevices: Passed null context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->devs)
|
||||
goto jumpin;
|
||||
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Start listing\n");
|
||||
}
|
||||
|
||||
ctx->devs = hid_enumerate(OUR_VENDOR_ID, 0x0000);
|
||||
if (!ctx->devs) {
|
||||
printf("Hid enumerate returned NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ctx->cur_dev = ctx->devs; ctx->cur_dev; ctx->cur_dev = ctx->cur_dev->next)
|
||||
{
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Considering 0x%04x:0x%04x\n", ctx->cur_dev->vendor_id, ctx->cur_dev->product_id);
|
||||
}
|
||||
if (isProductIdHandled(ctx->cur_dev->product_id, ctx->cur_dev->interface_number, &caps))
|
||||
{
|
||||
info->usb_vid = ctx->cur_dev->vendor_id;
|
||||
info->usb_pid = ctx->cur_dev->product_id;
|
||||
wcsncpy_s(info->str_prodname, ctx->cur_dev->product_string, PRODNAME_MAXCHARS-1);
|
||||
wcsncpy_s(info->str_serial, ctx->cur_dev->serial_number, SERIAL_MAXCHARS-1);
|
||||
strncpy_s(info->str_path, ctx->cur_dev->path, PATH_MAXCHARS-1);
|
||||
memcpy(&info->caps, &caps, sizeof(info->caps));
|
||||
return info;
|
||||
}
|
||||
|
||||
jumpin:
|
||||
// prevent 'error: label at end of compound statement'
|
||||
continue;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gcn64_hdl_t gcn64_openDevice(struct gcn64_info *dev)
|
||||
{
|
||||
hid_device *hdev;
|
||||
gcn64_hdl_t hdl;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
if (IS_VERBOSE()) {
|
||||
printf("Opening device path: '%s'\n", dev->str_path);
|
||||
}
|
||||
|
||||
hdev = hid_open_path(dev->str_path);
|
||||
if (!hdev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdl = (_gcn64_hdl_t*)malloc(sizeof(struct _gcn64_hdl_t));
|
||||
if (!hdl) {
|
||||
perror("malloc");
|
||||
hid_close(hdev);
|
||||
return NULL;
|
||||
}
|
||||
hdl->hdev = hdev;
|
||||
hdl->report_size = 63;
|
||||
memcpy(&hdl->caps, &dev->caps, sizeof(hdl->caps));
|
||||
|
||||
if (!dev->caps.bio_support) {
|
||||
printf("Pre-3.4 version detected. Setting report size to 40 bytes\n");
|
||||
hdl->report_size = 40;
|
||||
}
|
||||
|
||||
return hdl;
|
||||
}
|
||||
|
||||
gcn64_hdl_t gcn64_openBy(struct gcn64_info *dev, unsigned char flags)
|
||||
{
|
||||
struct gcn64_list_ctx *ctx;
|
||||
struct gcn64_info inf;
|
||||
gcn64_hdl_t h;
|
||||
|
||||
if (IS_VERBOSE())
|
||||
printf("gcn64_openBy, flags=0x%02x\n", flags);
|
||||
|
||||
ctx = gcn64_allocListCtx();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
while (gcn64_listDevices(&inf, ctx)) {
|
||||
if (IS_VERBOSE())
|
||||
printf("Considering '%s'\n", inf.str_path);
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_SERIAL) {
|
||||
if (wcscmp(inf.str_serial, dev->str_serial))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_PATH) {
|
||||
if (strcmp(inf.str_path, dev->str_path))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_VID) {
|
||||
if (inf.usb_vid != dev->usb_vid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & GCN64_FLG_OPEN_BY_PID) {
|
||||
if (inf.usb_pid != dev->usb_pid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_VERBOSE())
|
||||
printf("Found device. opening...\n");
|
||||
|
||||
h = gcn64_openDevice(&inf);
|
||||
gcn64_freeListCtx(ctx);
|
||||
return h;
|
||||
}
|
||||
|
||||
gcn64_freeListCtx(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void gcn64_closeDevice(gcn64_hdl_t hdl)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
|
||||
if (hdev) {
|
||||
hid_close(hdev);
|
||||
}
|
||||
|
||||
free(hdl);
|
||||
}
|
||||
|
||||
int gcn64_send_cmd(gcn64_hdl_t hdl, const unsigned char *cmd, int cmdlen)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
unsigned char *buffer = new unsigned char[hdl->report_size + 1];
|
||||
int n;
|
||||
|
||||
if (cmdlen > (sizeof(buffer)-1)) {
|
||||
fprintf(stderr, "Error: Command too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
buffer[0] = 0x00; // report ID set to 0 (device has only one)
|
||||
memcpy(buffer + 1, cmd, cmdlen);
|
||||
|
||||
n = hid_send_feature_report(hdev, buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Could not send feature report (%ls)\n", hid_error(hdev));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64_poll_result(gcn64_hdl_t hdl, unsigned char *cmd, int cmd_maxlen)
|
||||
{
|
||||
hid_device *hdev = hdl->hdev;
|
||||
unsigned char *buffer = new unsigned char[hdl->report_size+1];
|
||||
int res_len;
|
||||
int n;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
buffer[0] = 0x00; // report ID set to 0 (device has only one)
|
||||
|
||||
n = hid_get_feature_report(hdev, buffer, sizeof(buffer));
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Could not send feature report (%ls)\n", hid_error(hdev));
|
||||
return -1;
|
||||
}
|
||||
if (n==0) {
|
||||
return 0;
|
||||
}
|
||||
res_len = n-1;
|
||||
|
||||
if (res_len>0) {
|
||||
int copy_len;
|
||||
|
||||
copy_len = res_len;
|
||||
if (copy_len > cmd_maxlen) {
|
||||
copy_len = cmd_maxlen;
|
||||
}
|
||||
if (cmd) {
|
||||
memcpy(cmd, buffer+1, copy_len);
|
||||
}
|
||||
}
|
||||
|
||||
return res_len;
|
||||
}
|
||||
|
||||
int gcn64_exchange(gcn64_hdl_t hdl, unsigned char *outcmd, int outlen, unsigned char *result, int result_max)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gcn64_send_cmd(hdl, outcmd, outlen);
|
||||
if (n<0) {
|
||||
fprintf(stderr, "Error sending command\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Answer to the command comes later. For now, this is polled, but in
|
||||
* the future an interrupt-in transfer could be used. */
|
||||
do {
|
||||
n = gcn64_poll_result(hdl, result, result_max);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error\r\n");
|
||||
break;
|
||||
}
|
||||
if (n==0) {
|
||||
// printf("."); fflush(stdout);
|
||||
}
|
||||
|
||||
} while (n==0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef _gcn64_h__
|
||||
#define _gcn64_h__
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#define OUR_VENDOR_ID 0x289b
|
||||
#define PRODNAME_MAXCHARS 256
|
||||
#define SERIAL_MAXCHARS 256
|
||||
#define PATH_MAXCHARS 256
|
||||
|
||||
struct gcn64_adapter_caps {
|
||||
int n_raw_channels;
|
||||
int bio_support;
|
||||
};
|
||||
|
||||
struct gcn64_info {
|
||||
wchar_t str_prodname[PRODNAME_MAXCHARS];
|
||||
wchar_t str_serial[SERIAL_MAXCHARS];
|
||||
char str_path[PATH_MAXCHARS];
|
||||
int usb_vid, usb_pid;
|
||||
int access; // True unless direct access to read serial/prodname failed due to permissions.
|
||||
struct gcn64_adapter_caps caps;
|
||||
};
|
||||
|
||||
struct gcn64_list_ctx;
|
||||
|
||||
typedef struct _gcn64_hdl_t *gcn64_hdl_t; // Cast from hid_device
|
||||
|
||||
int gcn64_init(int verbose);
|
||||
void gcn64_shutdown(void);
|
||||
|
||||
struct gcn64_list_ctx *gcn64_allocListCtx(void);
|
||||
void gcn64_freeListCtx(struct gcn64_list_ctx *ctx);
|
||||
struct gcn64_info *gcn64_listDevices(struct gcn64_info *info, struct gcn64_list_ctx *ctx);
|
||||
int gcn64_countDevices(void);
|
||||
|
||||
gcn64_hdl_t gcn64_openDevice(struct gcn64_info *dev);
|
||||
|
||||
#define GCN64_FLG_OPEN_BY_SERIAL 1 /** Serial must match */
|
||||
#define GCN64_FLG_OPEN_BY_PATH 2 /** Path must match */
|
||||
#define GCN64_FLG_OPEN_BY_VID 4 /** USB VID must match */
|
||||
#define GCN64_FLG_OPEN_BY_PID 8 /** USB PID MUST match */
|
||||
/**
|
||||
* \brief Open a device matching a serial number
|
||||
* \param dev The device structure
|
||||
* \param flags Flags
|
||||
* \return A handle to the opened device, or NULL if not found
|
||||
**/
|
||||
gcn64_hdl_t gcn64_openBy(struct gcn64_info *dev, unsigned char flags);
|
||||
|
||||
void gcn64_closeDevice(gcn64_hdl_t hdl);
|
||||
|
||||
int gcn64_send_cmd(gcn64_hdl_t hdl, const unsigned char *cmd, int len);
|
||||
int gcn64_poll_result(gcn64_hdl_t hdl, unsigned char *cmd, int cmdlen);
|
||||
|
||||
int gcn64_exchange(gcn64_hdl_t hdl, unsigned char *outcmd, int outlen, unsigned char *result, int result_max);
|
||||
|
||||
#endif // _gcn64_h__
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef _gcn64_priv_h__
|
||||
#define _gcn64_priv_h__
|
||||
|
||||
#include "hidapi.h"
|
||||
#include "gcn64.h"
|
||||
|
||||
struct gcn64_list_ctx {
|
||||
struct hid_device_info *devs, *cur_dev;
|
||||
};
|
||||
|
||||
typedef struct _gcn64_hdl_t {
|
||||
hid_device *hdev;
|
||||
int report_size;
|
||||
struct gcn64_adapter_caps caps;
|
||||
} *gcn64_hdl_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,166 @@
|
|||
#ifndef _gcn64_protocol_h__
|
||||
#define _gcn64_protocol_h__
|
||||
|
||||
#define CONTROLLER_IS_ABSENT 0
|
||||
#define CONTROLLER_IS_N64 1
|
||||
#define CONTROLLER_IS_GC 2
|
||||
#define CONTROLLER_IS_GC_KEYBOARD 3
|
||||
#define CONTROLLER_IS_UNKNOWN 4
|
||||
|
||||
|
||||
/* Return many unknown bits, but two are about the expansion port. */
|
||||
#define N64_GET_CAPABILITIES 0x00
|
||||
#define N64_RESET 0xFF
|
||||
#define N64_CAPS_REPLY_LENGTH 3
|
||||
|
||||
#define OFFSET_EXT_REMOVED 22
|
||||
#define OFFSET_EXT_PRESENT 23
|
||||
|
||||
/* Returns button states and axis values */
|
||||
#define N64_GET_STATUS 0x01
|
||||
#define N64_GET_STATUS_REPLY_LENGTH 4
|
||||
|
||||
/* Read from the expansion bus. */
|
||||
#define N64_EXPANSION_READ 0x02
|
||||
|
||||
/* Write to the expansion bus. */
|
||||
#define N64_EXPANSION_WRITE 0x03
|
||||
|
||||
/* Return information about controller. */
|
||||
#define GC_GETID 0x00
|
||||
#define GC_GETID_REPLY_LENGTH 3
|
||||
|
||||
/* 3-byte get status command. Returns axis and buttons. Also
|
||||
* controls motor. */
|
||||
#define GC_GETSTATUS1 0x40
|
||||
#define GC_GETSTATUS2 0x03
|
||||
#define GC_GETSTATUS3(rumbling) ((rumbling) ? 0x01 : 0x00)
|
||||
#define GC_GETSTATUS_REPLY_LENGTH 8
|
||||
|
||||
/* 3-byte poll keyboard command.
|
||||
* Source: http://hitmen.c02.at/files/yagcd/yagcd/chap9.html#sec9.3.3
|
||||
* */
|
||||
#define GC_POLL_KB1 0x54
|
||||
#define GC_POLL_KB2 0x00
|
||||
#define GC_POLL_KB3 0x00
|
||||
|
||||
/* Gamecube keycodes are from table 9.3.2:
|
||||
* http://hitmen.c02.at/files/yagcd/yagcd/chap9.html#sec9.3.2
|
||||
*
|
||||
* But the table appears to have been built using a PC keyboard
|
||||
* converted (Tototek).
|
||||
*
|
||||
* I was working with an ASCII keyboard so I made a few adjustments
|
||||
* to reflect the /real/ key functions. For instance:
|
||||
*
|
||||
* LWIN, RWIN and MENU are in fact the Henkan, muhenkan and katakana/hiragana keys.
|
||||
* They are equivalemnt to the HID keys International 4, International 5 and International 2.
|
||||
* The - key (code 0x3F) is also HID international 1.
|
||||
* The PrntScrn key (code 0x36) is in fact the Yen key (International 3).
|
||||
* The bracket/brace [{ and }] keys are at different places on this Japanese keyboard,
|
||||
* but following standard PC practice, some keycodes are named after the US usage. Hence,
|
||||
* the aforementioned keys are the 2 keys right of P, even if they are not labeled.
|
||||
*/
|
||||
#define GC_KEY_RESERVED 0x00 // No key
|
||||
|
||||
#define GC_KEY_HOME 0x06
|
||||
#define GC_KEY_END 0x07
|
||||
#define GC_KEY_PGUP 0x08
|
||||
#define GC_KEY_PGDN 0x09
|
||||
#define GC_KEY_SCROLL_LOCK 0x0A
|
||||
|
||||
#define GC_KEY_A 0x10
|
||||
#define GC_KEY_B 0x11
|
||||
#define GC_KEY_C 0x12
|
||||
#define GC_KEY_D 0x13
|
||||
#define GC_KEY_E 0x14
|
||||
#define GC_KEY_F 0x15
|
||||
#define GC_KEY_G 0x16
|
||||
#define GC_KEY_H 0x17
|
||||
#define GC_KEY_I 0x18
|
||||
#define GC_KEY_J 0x19
|
||||
#define GC_KEY_K 0x1A
|
||||
#define GC_KEY_L 0x1B
|
||||
#define GC_KEY_M 0x1C
|
||||
#define GC_KEY_N 0x1D
|
||||
#define GC_KEY_O 0x1E
|
||||
#define GC_KEY_P 0x1F
|
||||
#define GC_KEY_Q 0x20
|
||||
#define GC_KEY_R 0x21
|
||||
#define GC_KEY_S 0x22
|
||||
#define GC_KEY_T 0x23
|
||||
#define GC_KEY_U 0x24
|
||||
#define GC_KEY_V 0x25
|
||||
#define GC_KEY_W 0x26
|
||||
#define GC_KEY_X 0x27
|
||||
#define GC_KEY_Y 0x28
|
||||
#define GC_KEY_Z 0x29
|
||||
#define GC_KEY_1 0x2A
|
||||
#define GC_KEY_2 0x2B
|
||||
#define GC_KEY_3 0x2C
|
||||
#define GC_KEY_4 0x2D
|
||||
#define GC_KEY_5 0x2E
|
||||
#define GC_KEY_6 0x2F
|
||||
#define GC_KEY_7 0x30
|
||||
#define GC_KEY_8 0x31
|
||||
#define GC_KEY_9 0x32
|
||||
#define GC_KEY_0 0x33
|
||||
#define GC_KEY_DASH_UNDERSCORE 0x34 // Key next to 0
|
||||
#define GC_KEY_PLUS_EQUAL 0x35
|
||||
#define GC_KEY_YEN 0x36 // Yen on ascii keyboard. HID International 3.
|
||||
#define GC_KEY_OPEN_BRKT_BRACE 0x37 // 1st key right of P
|
||||
#define GC_KEY_CLOSE_BRKT_BRACE 0x38 // 2nd key right of P
|
||||
#define GC_KEY_SEMI_COLON_COLON 0x39 // ;:
|
||||
#define GC_KEY_QUOTES 0x3A // '"
|
||||
|
||||
// The 3rd key after 'L'. HID Keyboard non-us # and ~
|
||||
#define GC_KEY_BRACKET_MU 0x3B
|
||||
#define GC_KEY_COMMA_ST 0x3C // ,<
|
||||
#define GC_KEY_PERIOD_GT 0x3D // .>
|
||||
#define GC_KEY_SLASH_QUESTION 0x3E // /?
|
||||
|
||||
// (The extra key before right-shift on japanese keyboards.
|
||||
// HID code International 1 [HID usage tables Footnote 15-20]).
|
||||
#define GC_KEY_INTERNATIONAL1 0x3F
|
||||
#define GC_KEY_F1 0x40
|
||||
#define GC_KEY_F2 0x41
|
||||
#define GC_KEY_F3 0x42
|
||||
#define GC_KEY_F4 0x43
|
||||
#define GC_KEY_F5 0x44
|
||||
#define GC_KEY_F6 0x45
|
||||
#define GC_KEY_F7 0x46
|
||||
#define GC_KEY_F8 0x47
|
||||
#define GC_KEY_F9 0x48
|
||||
#define GC_KEY_F10 0x49
|
||||
#define GC_KEY_F11 0x4A
|
||||
#define GC_KEY_F12 0x4B
|
||||
#define GC_KEY_ESC 0x4C
|
||||
#define GC_KEY_INSERT 0x4D
|
||||
#define GC_KEY_DELETE 0x4E
|
||||
|
||||
// (Hankaku/zenkaku/kanji button). Also known as `~
|
||||
#define GC_KEY_HANKAKU 0x4F
|
||||
#define GC_KEY_BACKSPACE 0x50
|
||||
#define GC_KEY_TAB 0x51
|
||||
|
||||
#define GC_KEY_CAPS_LOCK 0x53
|
||||
#define GC_KEY_LEFT_SHIFT 0x54
|
||||
#define GC_KEY_RIGHT_SHIFT 0x55
|
||||
#define GC_KEY_LEFT_CTRL 0x56
|
||||
#define GC_KEY_LEFT_ALT 0x57
|
||||
#define GC_KEY_MUHENKAN 0x58 // HID international 5
|
||||
#define GC_KEY_SPACE 0x59
|
||||
#define GC_KEY_HENKAN 0x5A // HID international 4
|
||||
#define GC_KEY_KANA 0x5B // HID international 2
|
||||
#define GC_KEY_LEFT 0x5C
|
||||
#define GC_KEY_DOWN 0x5D
|
||||
#define GC_KEY_UP 0x5E
|
||||
#define GC_KEY_RIGHT 0x5F
|
||||
|
||||
#define GC_KEY_ENTER 0x61
|
||||
|
||||
void gcn64protocol_hwinit(void);
|
||||
int gcn64_detectController(void);
|
||||
unsigned char gcn64_transaction(const unsigned char *tx, int tx_len, unsigned char *rx, unsigned char rx_max);
|
||||
|
||||
#endif // _gcn64_protocol_h__
|
|
@ -0,0 +1,444 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2015 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "gcn64lib.h"
|
||||
#include "gcn64_priv.h"
|
||||
#include "requests.h"
|
||||
#include "gcn64_protocol.h"
|
||||
#include "hexdump.h"
|
||||
|
||||
int gcn64lib_getConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *rx, unsigned char rx_max)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_CONFIG_PARAM;
|
||||
cmd[1] = param;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, rx, rx_max);
|
||||
if (n<2)
|
||||
return n;
|
||||
|
||||
n -= 2;
|
||||
|
||||
// Drop the leading CMD and PARAM
|
||||
if (n) {
|
||||
memmove(rx, rx+2, n);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
int gcn64lib_setConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *data, unsigned char len)
|
||||
{
|
||||
unsigned char cmd[2 + len];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SET_CONFIG_PARAM;
|
||||
cmd[1] = param;
|
||||
memcpy(cmd + 2, data, len);
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2 + len, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_suspendPolling(gcn64_hdl_t hdl, unsigned char suspend)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SUSPEND_POLLING;
|
||||
cmd[1] = suspend;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_getVersion(gcn64_hdl_t hdl, char *dst, int dstmax)
|
||||
{
|
||||
unsigned char cmd[32];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dstmax <= 0)
|
||||
return -1;
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_VERSION;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 1, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
dst[0] = 0;
|
||||
if (n > 1) {
|
||||
strncpy(dst, (char*)cmd+1, n);
|
||||
}
|
||||
dst[dstmax-1] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_getControllerType(gcn64_hdl_t hdl, int chn)
|
||||
{
|
||||
unsigned char cmd[32];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_CONTROLLER_TYPE;
|
||||
cmd[1] = chn;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
if (n<3)
|
||||
return -1;
|
||||
|
||||
return cmd[2];
|
||||
}
|
||||
|
||||
const char *gcn64lib_controllerName(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case CTL_TYPE_NONE: return "No controller";
|
||||
case CTL_TYPE_N64: return "N64 Controller";
|
||||
case CTL_TYPE_GC: return "GC Controller";
|
||||
case CTL_TYPE_GCKB: return "GC Keyboard";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int gcn64lib_getSignature(gcn64_hdl_t hdl, char *dst, int dstmax)
|
||||
{
|
||||
unsigned char cmd[40];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dstmax <= 0)
|
||||
return -1;
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_SIGNATURE;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 1, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
dst[0] = 0;
|
||||
if (n > 1) {
|
||||
strncpy(dst, (char*)cmd+1, n);
|
||||
}
|
||||
dst[dstmax-1] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_forceVibration(gcn64_hdl_t hdl, unsigned char channel, unsigned char vibrate)
|
||||
{
|
||||
unsigned char cmd[3];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SET_VIBRATION;
|
||||
cmd[1] = channel;
|
||||
cmd[2] = vibrate;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 3, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_rawSiCommand(gcn64_hdl_t hdl, unsigned char channel, unsigned char *tx, unsigned char tx_len, unsigned char *rx, unsigned char max_rx)
|
||||
{
|
||||
unsigned char cmd[3 + tx_len];
|
||||
unsigned char rep[3 + 64];
|
||||
int cmdlen, rx_len, n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_RAW_SI_COMMAND;
|
||||
cmd[1] = channel;
|
||||
cmd[2] = tx_len;
|
||||
memcpy(cmd+3, tx, tx_len);
|
||||
cmdlen = 3 + tx_len;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, cmdlen, rep, sizeof(rep));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
rx_len = rep[2];
|
||||
if (rx) {
|
||||
memcpy(rx, rep + 3, rx_len);
|
||||
}
|
||||
|
||||
return rx_len;
|
||||
}
|
||||
|
||||
int gcn64lib_16bit_scan(gcn64_hdl_t hdl, unsigned short min, unsigned short max)
|
||||
{
|
||||
int id, n;
|
||||
unsigned char buf[64];
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (id = min; id<=max; id++) {
|
||||
buf[0] = id >> 8;
|
||||
buf[1] = id & 0xff;
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, buf, 2, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
printf("CMD 0x%04x answer: ", id);
|
||||
printHexBuf(buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_8bit_scan(gcn64_hdl_t hdl, unsigned char min, unsigned char max)
|
||||
{
|
||||
int id, n;
|
||||
unsigned char buf[64];
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (id = min; id<=max; id++) {
|
||||
buf[0] = id;
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, buf, 1, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
printf("CMD 0x%02x answer: ", id);
|
||||
printHexBuf(buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_bootloader(gcn64_hdl_t hdl)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
int cmdlen;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_JUMP_TO_BOOTLOADER;
|
||||
cmdlen = 1;
|
||||
|
||||
gcn64_exchange(hdl, cmd, cmdlen, cmd, sizeof(cmd));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_n64_expansionWrite(gcn64_hdl_t hdl, unsigned short addr, unsigned char *data, int len)
|
||||
{
|
||||
unsigned char cmd[3 + len];
|
||||
int cmdlen;
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = N64_EXPANSION_WRITE;
|
||||
cmd[1] = addr>>8; // Address high byte
|
||||
cmd[2] = addr&0xff; // Address low byte
|
||||
memcpy(cmd + 3, data, len);
|
||||
cmdlen = 3 + len;
|
||||
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, cmd, cmdlen, cmd, sizeof(cmd));
|
||||
if (n != 1) {
|
||||
printf("expansion write returned != 1 (%d)\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cmd[0];
|
||||
}
|
||||
|
||||
int gcn64lib_n64_expansionRead(gcn64_hdl_t hdl, unsigned short addr, unsigned char *dst, int max_len)
|
||||
{
|
||||
unsigned char cmd[3];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = N64_EXPANSION_READ;
|
||||
cmd[1] = addr>>8; // Address high byte
|
||||
cmd[2] = addr&0xff; // Address low byte
|
||||
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, cmd, 3, dst, max_len);
|
||||
if (n < 0)
|
||||
return n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int gcn64lib_blockIO_compat(gcn64_hdl_t hdl, struct blockio_op *iops, int n_iops)
|
||||
{
|
||||
int i;
|
||||
int res;
|
||||
|
||||
for (i=0; i<n_iops; i++) {
|
||||
res = gcn64lib_rawSiCommand(hdl, iops[i].chn, iops[i].tx_data, iops[i].tx_len, iops[i].rx_data, iops[i].rx_len);
|
||||
if (res <= 0) {
|
||||
// Timeout
|
||||
iops[i].rx_len &= BIO_RXTX_MASK;
|
||||
iops[i].rx_len |= BIO_RX_LEN_TIMEDOUT;
|
||||
} else if (res != iops[i].rx_len) {
|
||||
// Less bytes than expected
|
||||
iops[i].rx_len &= BIO_RXTX_MASK;
|
||||
iops[i].rx_len |= BIO_RX_LEN_TIMEDOUT;
|
||||
} else {
|
||||
// Read n bytes as expected.
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_blockIO(gcn64_hdl_t hdl, struct blockio_op *iops, int n_iops)
|
||||
{
|
||||
unsigned char iobuf[63];
|
||||
int p, i, n;
|
||||
if (!hdl)
|
||||
return -1;
|
||||
|
||||
if (!hdl->caps.bio_support) {
|
||||
return gcn64lib_blockIO_compat(hdl, iops, n_iops);
|
||||
}
|
||||
else {
|
||||
// Request format:
|
||||
//
|
||||
// RQ_GCN64_BLOCK_IO
|
||||
// chn, n_tx, n_rx, tx[]
|
||||
// ...
|
||||
//
|
||||
// The adapter stops processing the buffer when the
|
||||
// buffer ends or when a channel set to 0xff is encountered.
|
||||
//
|
||||
memset(iobuf, 0xff, sizeof(iobuf));
|
||||
iobuf[0] = RQ_GCN64_BLOCK_IO;
|
||||
for (p=1, i=0; i<n_iops; i++) {
|
||||
if (p + 3 + iops[i].tx_len > sizeof(iobuf)) {
|
||||
fprintf(stderr, "io blocks do not fit in buffer\n");
|
||||
return -1;
|
||||
}
|
||||
iobuf[p] = iops[i].chn;
|
||||
p++;
|
||||
iobuf[p] = iops[i].tx_len & BIO_RXTX_MASK;
|
||||
p++;
|
||||
iobuf[p] = iops[i].rx_len & BIO_RXTX_MASK;
|
||||
p++;
|
||||
|
||||
memcpy(iobuf + p, iops[i].tx_data, iops[i].tx_len);
|
||||
p += iops[i].tx_len;
|
||||
}
|
||||
#ifdef DEBUG_BLOCKIO
|
||||
fputs("blockIO request: ", stdout);
|
||||
printHexBuf(iobuf, sizeof(iobuf));
|
||||
#endif
|
||||
|
||||
n = gcn64_exchange(hdl, iobuf, sizeof(iobuf), iobuf, sizeof(iobuf));
|
||||
if (n < 0) {
|
||||
return n;
|
||||
}
|
||||
if (n != sizeof(iobuf)) {
|
||||
fprintf(stderr, "Unexpected iobuf reply size\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef DEBUG_BLOCKIO
|
||||
fputs("blockIO answer.: ", stdout);
|
||||
printHexBuf(iobuf, sizeof(iobuf));
|
||||
printf("\n");
|
||||
#endif
|
||||
// Answer format:
|
||||
//
|
||||
// RQ_GCN64_BLOCK_IO
|
||||
// n_rx, rx[n_rx]
|
||||
// ...
|
||||
//
|
||||
// n_rx will have bits set according to the result. See BIO_RX*. rx will always
|
||||
// occupy the number of bytes set in the request, regardless of the result.
|
||||
//
|
||||
if (iobuf[0] != RQ_GCN64_BLOCK_IO) {
|
||||
fprintf(stderr, "Invalid iobuf reply\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (p=1,i=0; i<n_iops; i++) {
|
||||
if (p >= sizeof(iobuf)) {
|
||||
fprintf(stderr, "blockIO: adapter reports too much received data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
iops[i].rx_len = iobuf[p];
|
||||
p++;
|
||||
if (p + (iops[i].rx_len & BIO_RXTX_MASK) >= sizeof(iobuf)) {
|
||||
fprintf(stderr, "blockIO: adapter reports too much received data\n");
|
||||
break;
|
||||
}
|
||||
memcpy(iops[i].rx_data, iobuf + p, iops[i].rx_len & BIO_RXTX_MASK);
|
||||
p += iops[i].rx_len & BIO_RXTX_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2015 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gcn64lib.h"
|
||||
#include "gcn64_priv.h"
|
||||
#include "requests.h"
|
||||
#include "gcn64_protocol.h"
|
||||
#include "hexdump.h"
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
int gcn64lib_getConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *rx, unsigned char rx_max)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_CONFIG_PARAM;
|
||||
cmd[1] = param;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, rx, rx_max);
|
||||
if (n<2)
|
||||
return n;
|
||||
|
||||
n -= 2;
|
||||
|
||||
// Drop the leading CMD and PARAM
|
||||
if (n) {
|
||||
memmove(rx, rx+2, n);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
int gcn64lib_setConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *data, unsigned char len)
|
||||
{
|
||||
unsigned char *cmd = new unsigned char[2 + len];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SET_CONFIG_PARAM;
|
||||
cmd[1] = param;
|
||||
memcpy(cmd + 2, data, len);
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2 + len, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_suspendPolling(gcn64_hdl_t hdl, unsigned char suspend)
|
||||
{
|
||||
unsigned char cmd[2];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SUSPEND_POLLING;
|
||||
cmd[1] = suspend;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//int gcn64lib_getVersion(gcn64_hdl_t hdl, char *dst, int dstmax)
|
||||
//{
|
||||
// unsigned char cmd[32];
|
||||
// int n;
|
||||
//
|
||||
// if (!hdl) {
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if (dstmax <= 0)
|
||||
// return -1;
|
||||
//
|
||||
// cmd[0] = RQ_GCN64_GET_VERSION;
|
||||
//
|
||||
// n = gcn64_exchange(hdl, cmd, 1, cmd, sizeof(cmd));
|
||||
// if (n<0)
|
||||
// return n;
|
||||
//
|
||||
// dst[0] = 0;
|
||||
// if (n > 1) {
|
||||
// strncpy(dst, (char*)cmd+1, n);
|
||||
// }
|
||||
// dst[dstmax-1] = 0;
|
||||
//
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
int gcn64lib_getControllerType(gcn64_hdl_t hdl, int chn)
|
||||
{
|
||||
unsigned char cmd[32];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_GET_CONTROLLER_TYPE;
|
||||
cmd[1] = chn;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 2, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
if (n<3)
|
||||
return -1;
|
||||
|
||||
return cmd[2];
|
||||
}
|
||||
|
||||
const char *gcn64lib_controllerName(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case CTL_TYPE_NONE: return "No controller";
|
||||
case CTL_TYPE_N64: return "N64 Controller";
|
||||
case CTL_TYPE_GC: return "GC Controller";
|
||||
case CTL_TYPE_GCKB: return "GC Keyboard";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
//int gcn64lib_getSignature(gcn64_hdl_t hdl, char *dst, int dstmax)
|
||||
//{
|
||||
// unsigned char cmd[40];
|
||||
// int n;
|
||||
//
|
||||
// if (!hdl) {
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// if (dstmax <= 0)
|
||||
// return -1;
|
||||
//
|
||||
// cmd[0] = RQ_GCN64_GET_SIGNATURE;
|
||||
//
|
||||
// n = gcn64_exchange(hdl, cmd, 1, cmd, sizeof(cmd));
|
||||
// if (n<0)
|
||||
// return n;
|
||||
//
|
||||
// dst[0] = 0;
|
||||
// if (n > 1) {
|
||||
// strncpy(dst, (char*)cmd+1, n);
|
||||
// }
|
||||
// dst[dstmax-1] = 0;
|
||||
//
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
int gcn64lib_forceVibration(gcn64_hdl_t hdl, unsigned char channel, unsigned char vibrate)
|
||||
{
|
||||
unsigned char cmd[3];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_SET_VIBRATION;
|
||||
cmd[1] = channel;
|
||||
cmd[2] = vibrate;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, 3, cmd, sizeof(cmd));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_rawSiCommand(gcn64_hdl_t hdl, unsigned char channel, unsigned char *tx, unsigned char tx_len, unsigned char *rx, unsigned char max_rx)
|
||||
{
|
||||
unsigned char *cmd = new unsigned char[3 + tx_len];
|
||||
unsigned char rep[3 + 64];
|
||||
int cmdlen, rx_len, n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_RAW_SI_COMMAND;
|
||||
cmd[1] = channel;
|
||||
cmd[2] = tx_len;
|
||||
memcpy(cmd+3, tx, tx_len);
|
||||
cmdlen = 3 + tx_len;
|
||||
|
||||
n = gcn64_exchange(hdl, cmd, cmdlen, rep, sizeof(rep));
|
||||
if (n<0)
|
||||
return n;
|
||||
|
||||
rx_len = rep[2];
|
||||
if (rx) {
|
||||
memcpy(rx, rep + 3, rx_len);
|
||||
}
|
||||
|
||||
return rx_len;
|
||||
}
|
||||
|
||||
int gcn64lib_16bit_scan(gcn64_hdl_t hdl, unsigned short min, unsigned short max)
|
||||
{
|
||||
int id, n;
|
||||
unsigned char buf[64];
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (id = min; id<=max; id++) {
|
||||
buf[0] = id >> 8;
|
||||
buf[1] = id & 0xff;
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, buf, 2, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
printf("CMD 0x%04x answer: ", id);
|
||||
printHexBuf(buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_8bit_scan(gcn64_hdl_t hdl, unsigned char min, unsigned char max)
|
||||
{
|
||||
int id, n;
|
||||
unsigned char buf[64];
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (id = min; id<=max; id++) {
|
||||
buf[0] = id;
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, buf, 1, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
printf("CMD 0x%02x answer: ", id);
|
||||
printHexBuf(buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_bootloader(gcn64_hdl_t hdl)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
int cmdlen;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = RQ_GCN64_JUMP_TO_BOOTLOADER;
|
||||
cmdlen = 1;
|
||||
|
||||
gcn64_exchange(hdl, cmd, cmdlen, cmd, sizeof(cmd));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_n64_expansionWrite(gcn64_hdl_t hdl, unsigned short addr, unsigned char *data, int len)
|
||||
{
|
||||
unsigned char *cmd = new unsigned char[3 + len];
|
||||
int cmdlen;
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = N64_EXPANSION_WRITE;
|
||||
cmd[1] = addr>>8; // Address high byte
|
||||
cmd[2] = addr&0xff; // Address low byte
|
||||
memcpy(cmd + 3, data, len);
|
||||
cmdlen = 3 + len;
|
||||
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, cmd, cmdlen, cmd, sizeof(cmd));
|
||||
if (n != 1) {
|
||||
printf("expansion write returned != 1 (%d)\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cmd[0];
|
||||
}
|
||||
|
||||
int gcn64lib_n64_expansionRead(gcn64_hdl_t hdl, unsigned short addr, unsigned char *dst, int max_len)
|
||||
{
|
||||
unsigned char cmd[3];
|
||||
int n;
|
||||
|
||||
if (!hdl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = N64_EXPANSION_READ;
|
||||
cmd[1] = addr>>8; // Address high byte
|
||||
cmd[2] = addr&0xff; // Address low byte
|
||||
|
||||
n = gcn64lib_rawSiCommand(hdl, 0, cmd, 3, dst, max_len);
|
||||
if (n < 0)
|
||||
return n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int gcn64lib_blockIO_compat(gcn64_hdl_t hdl, struct blockio_op *iops, int n_iops)
|
||||
{
|
||||
int i;
|
||||
int res;
|
||||
|
||||
for (i=0; i<n_iops; i++) {
|
||||
res = gcn64lib_rawSiCommand(hdl, iops[i].chn, iops[i].tx_data, iops[i].tx_len, iops[i].rx_data, iops[i].rx_len);
|
||||
if (res <= 0) {
|
||||
// Timeout
|
||||
iops[i].rx_len &= BIO_RXTX_MASK;
|
||||
iops[i].rx_len |= BIO_RX_LEN_TIMEDOUT;
|
||||
} else if (res != iops[i].rx_len) {
|
||||
// Less bytes than expected
|
||||
iops[i].rx_len &= BIO_RXTX_MASK;
|
||||
iops[i].rx_len |= BIO_RX_LEN_TIMEDOUT;
|
||||
} else {
|
||||
// Read n bytes as expected.
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gcn64lib_blockIO(gcn64_hdl_t hdl, struct blockio_op *iops, int n_iops)
|
||||
{
|
||||
unsigned char iobuf[63];
|
||||
int p, i, n;
|
||||
if (!hdl)
|
||||
return -1;
|
||||
|
||||
if (!hdl->caps.bio_support) {
|
||||
return gcn64lib_blockIO_compat(hdl, iops, n_iops);
|
||||
}
|
||||
else {
|
||||
// Request format:
|
||||
//
|
||||
// RQ_GCN64_BLOCK_IO
|
||||
// chn, n_tx, n_rx, tx[]
|
||||
// ...
|
||||
//
|
||||
// The adapter stops processing the buffer when the
|
||||
// buffer ends or when a channel set to 0xff is encountered.
|
||||
//
|
||||
memset(iobuf, 0xff, sizeof(iobuf));
|
||||
iobuf[0] = RQ_GCN64_BLOCK_IO;
|
||||
for (p=1, i=0; i<n_iops; i++) {
|
||||
if (p + 3 + iops[i].tx_len > sizeof(iobuf)) {
|
||||
fprintf(stderr, "io blocks do not fit in buffer\n");
|
||||
return -1;
|
||||
}
|
||||
iobuf[p] = iops[i].chn;
|
||||
p++;
|
||||
iobuf[p] = iops[i].tx_len & BIO_RXTX_MASK;
|
||||
p++;
|
||||
iobuf[p] = iops[i].rx_len & BIO_RXTX_MASK;
|
||||
p++;
|
||||
|
||||
memcpy(iobuf + p, iops[i].tx_data, iops[i].tx_len);
|
||||
p += iops[i].tx_len;
|
||||
}
|
||||
#ifdef DEBUG_BLOCKIO
|
||||
fputs("blockIO request: ", stdout);
|
||||
printHexBuf(iobuf, sizeof(iobuf));
|
||||
#endif
|
||||
|
||||
n = gcn64_exchange(hdl, iobuf, sizeof(iobuf), iobuf, sizeof(iobuf));
|
||||
if (n < 0) {
|
||||
return n;
|
||||
}
|
||||
if (n != sizeof(iobuf)) {
|
||||
fprintf(stderr, "Unexpected iobuf reply size\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef DEBUG_BLOCKIO
|
||||
fputs("blockIO answer.: ", stdout);
|
||||
printHexBuf(iobuf, sizeof(iobuf));
|
||||
printf("\n");
|
||||
#endif
|
||||
// Answer format:
|
||||
//
|
||||
// RQ_GCN64_BLOCK_IO
|
||||
// n_rx, rx[n_rx]
|
||||
// ...
|
||||
//
|
||||
// n_rx will have bits set according to the result. See BIO_RX*. rx will always
|
||||
// occupy the number of bytes set in the request, regardless of the result.
|
||||
//
|
||||
if (iobuf[0] != RQ_GCN64_BLOCK_IO) {
|
||||
fprintf(stderr, "Invalid iobuf reply\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (p=1,i=0; i<n_iops; i++) {
|
||||
if (p >= sizeof(iobuf)) {
|
||||
fprintf(stderr, "blockIO: adapter reports too much received data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
iops[i].rx_len = iobuf[p];
|
||||
p++;
|
||||
if (p + (iops[i].rx_len & BIO_RXTX_MASK) >= sizeof(iobuf)) {
|
||||
fprintf(stderr, "blockIO: adapter reports too much received data\n");
|
||||
break;
|
||||
}
|
||||
memcpy(iops[i].rx_data, iobuf + p, iops[i].rx_len & BIO_RXTX_MASK);
|
||||
p += iops[i].rx_len & BIO_RXTX_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef _gcn64_lib_h__
|
||||
#define _gcn64_lib_h__
|
||||
|
||||
#include "gcn64.h"
|
||||
|
||||
#define CTL_TYPE_NONE 0
|
||||
#define CTL_TYPE_N64 1
|
||||
#define CTL_TYPE_GC 2
|
||||
#define CTL_TYPE_GCKB 3
|
||||
|
||||
int gcn64lib_suspendPolling(gcn64_hdl_t hdl, unsigned char suspend);
|
||||
int gcn64lib_setConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *data, unsigned char len);
|
||||
int gcn64lib_getConfig(gcn64_hdl_t hdl, unsigned char param, unsigned char *rx, unsigned char rx_max);
|
||||
int gcn64lib_rawSiCommand(gcn64_hdl_t hdl, unsigned char channel, unsigned char *tx, unsigned char tx_len, unsigned char *rx, unsigned char max_rx);
|
||||
int gcn64lib_getVersion(gcn64_hdl_t hdl, char *dst, int dstmax);
|
||||
int gcn64lib_getSignature(gcn64_hdl_t hdl, char *dst, int dstmax);
|
||||
int gcn64lib_forceVibration(gcn64_hdl_t hdl, unsigned char channel, unsigned char vibrate);
|
||||
int gcn64lib_getControllerType(gcn64_hdl_t hdl, int chn);
|
||||
const char *gcn64lib_controllerName(int type);
|
||||
int gcn64lib_bootloader(gcn64_hdl_t hdl);
|
||||
|
||||
int gcn64lib_n64_expansionWrite(gcn64_hdl_t hdl, unsigned short addr, unsigned char *data, int len);
|
||||
int gcn64lib_n64_expansionRead(gcn64_hdl_t hdl, unsigned short addr, unsigned char *dst, int max_len);
|
||||
|
||||
int gcn64lib_8bit_scan(gcn64_hdl_t hdl, unsigned char min, unsigned char max);
|
||||
int gcn64lib_16bit_scan(gcn64_hdl_t hdl, unsigned short min, unsigned short max);
|
||||
|
||||
#define BIO_RXTX_MASK 0x3F
|
||||
#define BIO_RX_LEN_TIMEDOUT 0x80
|
||||
#define BIO_RX_LEN_PARTIAL 0x40
|
||||
|
||||
struct blockio_op {
|
||||
unsigned char chn;
|
||||
unsigned char tx_len;
|
||||
unsigned char *tx_data;
|
||||
unsigned char rx_len; // expected/max bytes
|
||||
unsigned char *rx_data;
|
||||
};
|
||||
|
||||
int gcn64lib_blockIO(gcn64_hdl_t hdl, struct blockio_op *iops, int n_iops);
|
||||
|
||||
#endif // _gcn64_lib_h__
|
|
@ -0,0 +1,29 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2015 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
void printHexBuf(unsigned char *buf, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware
|
||||
Copyright (C) 2007-2015 Raphael Assenat <raph@raphnet.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
void printHexBuf(unsigned char *buf, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
void printHexBuf(unsigned char *buf, int n);
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-core - osal/dynamiclib.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#if !defined(OSAL_DYNAMICLIB_H)
|
||||
#define OSAL_DYNAMICLIB_H
|
||||
|
||||
#include "m64p_types.h"
|
||||
|
||||
void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
|
||||
|
||||
#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 <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.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;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus - osal_preproc.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009 Richard Goedeken *
|
||||
* Copyright (C) 2002 Hacktarux *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* this header file is for system-dependent #defines, #includes, and typedefs */
|
||||
|
||||
#if !defined(OSAL_PREPROC_H)
|
||||
#define OSAL_PREPROC_H
|
||||
|
||||
#if defined(WIN32)
|
||||
#define strcasestr strstr
|
||||
#define strcasecmp _stricmp
|
||||
#endif // WIN32
|
||||
|
||||
#if defined(WIN32) && !defined(__MINGW32__)
|
||||
|
||||
// macros
|
||||
#define osal_inline __inline
|
||||
|
||||
#else /* Not WIN32 */
|
||||
|
||||
// macros
|
||||
#define osal_inline inline
|
||||
|
||||
#endif
|
||||
|
||||
#endif // OSAL_PREPROC_H
|
|
@ -0,0 +1,475 @@
|
|||
/* mupen64plus-input-raphnetraw
|
||||
*
|
||||
* Copyright (C) 2016-2017 Raphael Assenat
|
||||
*
|
||||
* An input plugin that lets the game under emulation communicate with
|
||||
* the controllers directly using the direct controller communication
|
||||
* feature of raphnet V3 adapters[1].
|
||||
*
|
||||
* [1] http://www.raphnet.net/electronique/gcn64_usb_adapter_gen3/index_en.php
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* plugin_back.c : Plugin back code (in contrast to the "front" emulator interface
|
||||
*
|
||||
* Revision history:
|
||||
* 28 Nov 2016 : Initial version
|
||||
* 1 Dec 2016 : Switch to block IO api
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "plugin_back.h"
|
||||
#include "gcn64.h"
|
||||
#include "gcn64lib.h"
|
||||
#include "version.h"
|
||||
#include "hexdump.h"
|
||||
|
||||
#undef ENABLE_TIMING
|
||||
|
||||
#ifdef ENABLE_TIMING
|
||||
#include <sys/time.h>
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#error Timing not supported under Windows
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef TIME_RAW_IO
|
||||
#undef TIME_COMMAND_TO_READ
|
||||
|
||||
#undef TRACE_BLOCK_IO
|
||||
// Filter
|
||||
#define EXTENSION_RW_ONLY 0
|
||||
|
||||
#define MAX_ADAPTERS 4
|
||||
#define MAX_CHANNELS 4
|
||||
|
||||
static void nodebug(int l, const char *m, ...) { }
|
||||
|
||||
static pb_debugFunc DebugMessage = nodebug;
|
||||
|
||||
|
||||
|
||||
#define MAX_OPS 64
|
||||
|
||||
struct adapter {
|
||||
gcn64_hdl_t handle;
|
||||
struct gcn64_info inf;
|
||||
struct blockio_op biops[MAX_OPS];
|
||||
int n_ops;
|
||||
};
|
||||
|
||||
static int g_n_adapters = 0;
|
||||
struct adapter g_adapters[MAX_ADAPTERS] = { };
|
||||
|
||||
struct rawChannel {
|
||||
struct adapter *adapter;
|
||||
int chn;
|
||||
};
|
||||
|
||||
/* Multiple adapters are supported, some are single player, others
|
||||
* two-player. As they are discovered during scan, their
|
||||
* channels (corresponding to physical controller ports) are added
|
||||
* to this table. Then, when plugin_front() calls functions in this
|
||||
* files with a specified channel, the channel is the index in this
|
||||
* table.
|
||||
*/
|
||||
static struct rawChannel g_channels[MAX_CHANNELS] = { };
|
||||
static int g_n_channels = 0;
|
||||
|
||||
int pb_init(pb_debugFunc debugFn)
|
||||
{
|
||||
DebugMessage = debugFn;
|
||||
gcn64_init(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pb_freeAllAdapters(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<g_n_adapters; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
/* RomClosed() should have done this, but just
|
||||
in case it is not always called, do this again here. */
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 0);
|
||||
gcn64_closeDevice(g_adapters[i].handle);
|
||||
}
|
||||
}
|
||||
|
||||
g_n_channels = 0;
|
||||
g_n_adapters = 0;
|
||||
memset(g_adapters, 0, sizeof(g_adapters));
|
||||
memset(g_channels, 0, sizeof(g_channels));
|
||||
}
|
||||
|
||||
int pb_shutdown(void)
|
||||
{
|
||||
pb_freeAllAdapters();
|
||||
gcn64_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return The number of channels available.
|
||||
*/
|
||||
int pb_scanControllers(void)
|
||||
{
|
||||
struct gcn64_list_ctx * lctx;
|
||||
int i, j;
|
||||
struct adapter *adap;
|
||||
|
||||
lctx = gcn64_allocListCtx();
|
||||
if (!lctx) {
|
||||
DebugMessage(PB_MSG_ERROR, "Could not allocate gcn64 list context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This may be called many times in the plugin's lifetime. For instance, each
|
||||
* time a new game is selected from the PJ64 menu. Freeing previously found
|
||||
* adapters here and creating a new list makes it possible to disconnect/replace
|
||||
* USB adapters without having to restart PJ64. */
|
||||
pb_freeAllAdapters();
|
||||
|
||||
/* Pass 1: Fill g_adapters[] with the adapters present on the system. */
|
||||
g_n_adapters = 0;
|
||||
adap = &g_adapters[g_n_adapters];
|
||||
while (gcn64_listDevices(&adap->inf, lctx)) {
|
||||
|
||||
adap->handle = gcn64_openDevice(&adap->inf);
|
||||
if (!adap->handle) {
|
||||
DebugMessage(PB_MSG_ERROR, "Could not open gcn64 device serial '%ls'. Skipping it.", adap->inf.str_serial);
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugMessage(PB_MSG_INFO, "Found USB device 0x%04x:0x%04x serial '%ls' name '%ls'",
|
||||
adap->inf.usb_vid, adap->inf.usb_pid, adap->inf.str_serial, adap->inf.str_prodname);
|
||||
DebugMessage(PB_MSG_INFO, "Adapter supports %d raw channel(s)", adap->inf.caps.n_raw_channels);
|
||||
|
||||
g_n_adapters++;
|
||||
if (g_n_adapters >= MAX_ADAPTERS)
|
||||
break;
|
||||
|
||||
adap = &g_adapters[g_n_adapters];
|
||||
}
|
||||
gcn64_freeListCtx(lctx);
|
||||
|
||||
/* Pass 2: Fill the g_channel[] array with the available raw channels.
|
||||
* For instance, if there are adapters A, B and C (where A and C are single-player
|
||||
* and B is dual-player), we get this:
|
||||
*
|
||||
* [0] = Adapter A, raw channel 0
|
||||
* [1] = Adapter B, raw channel 0
|
||||
* [2] = Adapter B, raw channel 1
|
||||
* [3] = Adapter C, raw channel 0
|
||||
*
|
||||
* */
|
||||
for (i=0; i<g_n_adapters; i++) {
|
||||
struct adapter *adap = &g_adapters[i];
|
||||
|
||||
if (adap->inf.caps.n_raw_channels <= 0)
|
||||
continue;
|
||||
|
||||
for (j=0; j<adap->inf.caps.n_raw_channels; j++) {
|
||||
if (g_n_channels >= MAX_CHANNELS) {
|
||||
return g_n_channels;
|
||||
}
|
||||
g_channels[g_n_channels].adapter = adap;
|
||||
g_channels[g_n_channels].chn = j;
|
||||
DebugMessage(PB_MSG_INFO, "Channel %d: Adapter '%ls' raw channel %d", g_n_channels, adap->inf.str_serial, j);
|
||||
g_n_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
return g_n_channels;
|
||||
}
|
||||
|
||||
int pb_romOpen(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_ADAPTERS; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pb_romClosed(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_ADAPTERS; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timing(int start, const char *label)
|
||||
{
|
||||
#ifdef ENABLE_TIMING
|
||||
static struct timeval tv_start;
|
||||
static int started = 0;
|
||||
struct timeval tv_now;
|
||||
|
||||
if (start) {
|
||||
gettimeofday(&tv_start, NULL);
|
||||
started = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (started) {
|
||||
gettimeofday(&tv_now, NULL);
|
||||
printf("%s: %ld us\n", label, (tv_now.tv_sec - tv_start.tv_sec) * 1000000 + (tv_now.tv_usec - tv_start.tv_usec) );
|
||||
started = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void debug_raw_commands_in(unsigned char *command, int channel_id)
|
||||
{
|
||||
int tx_len = command[0];
|
||||
int rx_len = command[1] & 0x3F;
|
||||
int i;
|
||||
|
||||
printf("chn %d: tx[%d] = {", channel_id, tx_len);
|
||||
for (i=0; i<tx_len; i++) {
|
||||
printf("0x%02x ", command[2+i]);
|
||||
}
|
||||
printf("}, expecting %d byte%c\n", rx_len, rx_len > 1 ? 's':' ');
|
||||
|
||||
}
|
||||
|
||||
static void debug_raw_commands_out(unsigned char *command, int channel_id)
|
||||
{
|
||||
int result = command[1];
|
||||
int i;
|
||||
|
||||
printf("chn %d: result: 0x%02x : ", channel_id, result);
|
||||
if (0 == (command[1] & 0xC0)) {
|
||||
for (i=0; i<result; i++) {
|
||||
printf("0x%02x ", command[2+i]);
|
||||
}
|
||||
} else {
|
||||
printf("error\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int pb_controllerCommand(int Control, unsigned char *Command)
|
||||
{
|
||||
// I thought of sending requests to the adapter from here, reading
|
||||
// the results later in readController.
|
||||
//
|
||||
// But unlike what I expected, controllerCommand is NOT always called
|
||||
// before readController... Will investigate later.
|
||||
#ifdef TIME_COMMAND_TO_READ
|
||||
timing(1, NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pb_performIo(void)
|
||||
{
|
||||
struct adapter *adap;
|
||||
struct blockio_op *biops;
|
||||
int j, i, res;
|
||||
int op_was_extio[MAX_OPS] = { };
|
||||
|
||||
for (j=0; j<g_n_channels; j++)
|
||||
{
|
||||
adap = &g_adapters[j];
|
||||
biops = adap->biops;
|
||||
|
||||
/* Skip adapters that do not have IO operations queued. */
|
||||
if (adap->n_ops <= 0)
|
||||
continue;
|
||||
|
||||
#ifdef TRACE_BLOCK_IO
|
||||
for (i=0; i<adap->n_ops; i++) {
|
||||
if (EXTENSION_RW_ONLY && (biops[i].tx_data[0] < 0x02))
|
||||
continue;
|
||||
op_was_extio[i] = 1;
|
||||
printf("Before blockIO: op %d, chn: %d, : tx: 0x%02x, rx: 0x%02x, data: ", i, biops[i].chn,
|
||||
biops[i].tx_len, biops[i].rx_len);
|
||||
printHexBuf(biops[i].tx_data, biops[i].tx_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIME_RAW_IO
|
||||
timing(1, NULL);
|
||||
#endif
|
||||
res = gcn64lib_blockIO(adap->handle, biops, adap->n_ops);
|
||||
#ifdef TIME_RAW_IO
|
||||
timing(0, "blockIO");
|
||||
#endif
|
||||
|
||||
if (res == 0) {
|
||||
// biops rx_data pointed into PIFram so data is there. But we need
|
||||
// to patch the RX length parameters (the two most significant bits
|
||||
// are error bits such as timeout..)
|
||||
for (i=0; i<adap->n_ops; i++) {
|
||||
// in PIFram, the read length is one byte before the tx data. A rare
|
||||
// occasion to use a negative array index ;)
|
||||
biops[i].tx_data[-1] = biops[i].rx_len;
|
||||
|
||||
#ifdef TRACE_BLOCK_IO
|
||||
if (EXTENSION_RW_ONLY && (!op_was_extio[i])) // Read
|
||||
continue;
|
||||
|
||||
printf("After blockIO: op %d, chn: %d, : tx: 0x%02x, rx: 0x%02x, data: ", i, biops[i].chn,
|
||||
biops[i].tx_len, biops[i].rx_len);
|
||||
if (biops[i].rx_len & BIO_RX_LEN_TIMEDOUT) {
|
||||
printf("Timeout\n");
|
||||
} else if (biops[i].rx_len & BIO_RX_LEN_PARTIAL) {
|
||||
printf("Incomplete\n");
|
||||
} else {
|
||||
printHexBuf(biops[i].rx_data, biops[i].rx_len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// For debugging
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
adap->n_ops = 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int pb_commandIsValid(int Control, unsigned char *Command)
|
||||
{
|
||||
if (Control < 0 || Control >= g_n_channels) {
|
||||
DebugMessage(PB_MSG_WARNING, "pb_readController called with Control=%d", Control);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Command) {
|
||||
DebugMessage(PB_MSG_WARNING, "pb_readController called with NULL Command pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When a CIC challenge took place in update_pif_write(), the pif ram
|
||||
// contains a bunch 0xFF followed by 0x00 at offsets 46 and 47. Offset
|
||||
// 48 onwards contains the challenge answer.
|
||||
//
|
||||
// Then when update_pif_read() is called, the 0xFF bytes are be skipped
|
||||
// up to the two 0x00 bytes that increase the channel to 2. Then the
|
||||
// challenge answer is (incorrectly) processed as if it were commands
|
||||
// for the third controller.
|
||||
//
|
||||
// This cause issues with the raphnetraw plugin since it modifies pif ram
|
||||
// to store the result or command error flags. This corrupts the reponse
|
||||
// and leads to challenge failure.
|
||||
//
|
||||
// As I know of no controller commands above 0x03, the filter below guards
|
||||
// against this condition...
|
||||
//
|
||||
if (Control == 2 && Command[2] > 0x03) {
|
||||
DebugMessage(PB_MSG_WARNING, "Invalid controller command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When Mario Kart 64 uses a controller pak, such PIF ram content
|
||||
// occurs:
|
||||
//
|
||||
// ff 03 21 02 01 f7 ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff 21
|
||||
// fe 00 00 00 00 00 00 00
|
||||
// 00 00 00 00 00 00 00 00
|
||||
// 00 00 00 00 00 00 00 00
|
||||
//
|
||||
// It results in this:
|
||||
// - Transmission of 3 bytes with a 33 bytes return on channel 0,
|
||||
// - Transmission of 33 bytes with 254 bytes in return on channel 1!?
|
||||
//
|
||||
// Obviously the second transaction is an error. The 0xFE (254) that follows
|
||||
// is where processing should actually stop. This happens to be an invalid length detectable
|
||||
// by looking at the two most significant bits..
|
||||
//
|
||||
if (Command[0] == 0xFE && Command[1] == 0x00) {
|
||||
DebugMessage(PB_MSG_WARNING, "Ignoring invalid io operation (T: 0x%02x, R: 0x%02x)",
|
||||
Command[0], Command[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pb_readController(int Control, unsigned char *Command)
|
||||
{
|
||||
struct rawChannel *channel;
|
||||
struct adapter *adap;
|
||||
struct blockio_op *biops;
|
||||
|
||||
// Called with -1 at the end of PIF ram.
|
||||
if (Control == -1) {
|
||||
return pb_performIo();
|
||||
}
|
||||
|
||||
/* Check for out of bounds Control parameter, for
|
||||
* NULL Command and filter various invalid conditions. */
|
||||
if (!pb_commandIsValid(Control, Command)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add the IO operation to the block io list of
|
||||
* the adapter serving this channel. */
|
||||
|
||||
channel = &g_channels[Control];
|
||||
adap = channel->adapter;
|
||||
|
||||
if (adap->n_ops >= MAX_OPS) {
|
||||
DebugMessage(PB_MSG_ERROR, "Too many io ops");
|
||||
} else {
|
||||
biops = adap->biops;
|
||||
|
||||
biops[adap->n_ops].chn = channel->chn; // Control;
|
||||
biops[adap->n_ops].tx_len = Command[0] & BIO_RXTX_MASK;
|
||||
biops[adap->n_ops].rx_len = Command[1] & BIO_RXTX_MASK;
|
||||
biops[adap->n_ops].tx_data = Command + 2;
|
||||
biops[adap->n_ops].rx_data = Command + 2 + biops[adap->n_ops].tx_len;
|
||||
|
||||
if (biops[adap->n_ops].tx_len == 0 || biops[adap->n_ops].rx_len == 0) {
|
||||
DebugMessage(PB_MSG_WARNING, "TX or RX was zero");
|
||||
return 0;
|
||||
}
|
||||
|
||||
adap->n_ops++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,482 @@
|
|||
/* mupen64plus-input-raphnetraw
|
||||
*
|
||||
* Copyright (C) 2016-2017 Raphael Assenat
|
||||
*
|
||||
* An input plugin that lets the game under emulation communicate with
|
||||
* the controllers directly using the direct controller communication
|
||||
* feature of raphnet V3 adapters[1].
|
||||
*
|
||||
* [1] http://www.raphnet.net/electronique/gcn64_usb_adapter_gen3/index_en.php
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* plugin_back.c : Plugin back code (in contrast to the "front" emulator interface
|
||||
*
|
||||
* Revision history:
|
||||
* 28 Nov 2016 : Initial version
|
||||
* 1 Dec 2016 : Switch to block IO api
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cstdarg>
|
||||
#include "plugin_back.h"
|
||||
#include "gcn64.h"
|
||||
#include "gcn64lib.h"
|
||||
#include "version.h"
|
||||
#include "hexdump.h"
|
||||
|
||||
#undef ENABLE_TIMING
|
||||
|
||||
#ifdef ENABLE_TIMING
|
||||
#include <sys/time.h>
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#error Timing not supported under Windows
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef TIME_RAW_IO
|
||||
#undef TIME_COMMAND_TO_READ
|
||||
|
||||
#undef TRACE_BLOCK_IO
|
||||
// Filter
|
||||
#define EXTENSION_RW_ONLY 0
|
||||
|
||||
#define MAX_ADAPTERS 4
|
||||
#define MAX_CHANNELS 4
|
||||
|
||||
static void nodebug(int l, const char* m, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, m);
|
||||
vprintf(m, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static pb_debugFunc DebugMessage = nodebug;
|
||||
|
||||
|
||||
|
||||
#define MAX_OPS 64
|
||||
|
||||
struct adapter {
|
||||
gcn64_hdl_t handle;
|
||||
struct gcn64_info inf;
|
||||
struct blockio_op biops[MAX_OPS];
|
||||
int n_ops;
|
||||
};
|
||||
|
||||
static int g_n_adapters = 0;
|
||||
struct adapter g_adapters[MAX_ADAPTERS] = { };
|
||||
|
||||
struct rawChannel {
|
||||
struct adapter *adapter;
|
||||
int chn;
|
||||
};
|
||||
|
||||
/* Multiple adapters are supported, some are single player, others
|
||||
* two-player. As they are discovered during scan, their
|
||||
* channels (corresponding to physical controller ports) are added
|
||||
* to this table. Then, when plugin_front() calls functions in this
|
||||
* files with a specified channel, the channel is the index in this
|
||||
* table.
|
||||
*/
|
||||
static struct rawChannel g_channels[MAX_CHANNELS] = { };
|
||||
static int g_n_channels = 0;
|
||||
|
||||
int pb_init(pb_debugFunc debugFn)
|
||||
{
|
||||
DebugMessage = debugFn;
|
||||
gcn64_init(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pb_freeAllAdapters(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<g_n_adapters; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
/* RomClosed() should have done this, but just
|
||||
in case it is not always called, do this again here. */
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 0);
|
||||
gcn64_closeDevice(g_adapters[i].handle);
|
||||
}
|
||||
}
|
||||
|
||||
g_n_channels = 0;
|
||||
g_n_adapters = 0;
|
||||
memset(g_adapters, 0, sizeof(g_adapters));
|
||||
memset(g_channels, 0, sizeof(g_channels));
|
||||
}
|
||||
|
||||
int pb_shutdown(void)
|
||||
{
|
||||
pb_freeAllAdapters();
|
||||
gcn64_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return The number of channels available.
|
||||
*/
|
||||
int pb_scanControllers(void)
|
||||
{
|
||||
struct gcn64_list_ctx * lctx;
|
||||
int i, j;
|
||||
struct adapter *adap;
|
||||
|
||||
lctx = gcn64_allocListCtx();
|
||||
if (!lctx) {
|
||||
DebugMessage(PB_MSG_ERROR, "Could not allocate gcn64 list context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This may be called many times in the plugin's lifetime. For instance, each
|
||||
* time a new game is selected from the PJ64 menu. Freeing previously found
|
||||
* adapters here and creating a new list makes it possible to disconnect/replace
|
||||
* USB adapters without having to restart PJ64. */
|
||||
pb_freeAllAdapters();
|
||||
|
||||
/* Pass 1: Fill g_adapters[] with the adapters present on the system. */
|
||||
g_n_adapters = 0;
|
||||
adap = &g_adapters[g_n_adapters];
|
||||
while (gcn64_listDevices(&adap->inf, lctx)) {
|
||||
|
||||
adap->handle = gcn64_openDevice(&adap->inf);
|
||||
if (!adap->handle) {
|
||||
DebugMessage(PB_MSG_ERROR, "Could not open gcn64 device serial '%ls'. Skipping it.", adap->inf.str_serial);
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugMessage(PB_MSG_INFO, "Found USB device 0x%04x:0x%04x serial '%ls' name '%ls'",
|
||||
adap->inf.usb_vid, adap->inf.usb_pid, adap->inf.str_serial, adap->inf.str_prodname);
|
||||
DebugMessage(PB_MSG_INFO, "Adapter supports %d raw channel(s)", adap->inf.caps.n_raw_channels);
|
||||
|
||||
g_n_adapters++;
|
||||
if (g_n_adapters >= MAX_ADAPTERS)
|
||||
break;
|
||||
|
||||
adap = &g_adapters[g_n_adapters];
|
||||
}
|
||||
gcn64_freeListCtx(lctx);
|
||||
|
||||
/* Pass 2: Fill the g_channel[] array with the available raw channels.
|
||||
* For instance, if there are adapters A, B and C (where A and C are single-player
|
||||
* and B is dual-player), we get this:
|
||||
*
|
||||
* [0] = Adapter A, raw channel 0
|
||||
* [1] = Adapter B, raw channel 0
|
||||
* [2] = Adapter B, raw channel 1
|
||||
* [3] = Adapter C, raw channel 0
|
||||
*
|
||||
* */
|
||||
for (i=0; i<g_n_adapters; i++) {
|
||||
struct adapter *adap = &g_adapters[i];
|
||||
|
||||
if (adap->inf.caps.n_raw_channels <= 0)
|
||||
continue;
|
||||
|
||||
for (j=0; j<adap->inf.caps.n_raw_channels; j++) {
|
||||
if (g_n_channels >= MAX_CHANNELS) {
|
||||
return g_n_channels;
|
||||
}
|
||||
g_channels[g_n_channels].adapter = adap;
|
||||
g_channels[g_n_channels].chn = j;
|
||||
DebugMessage(PB_MSG_INFO, "Channel %d: Adapter '%ls' raw channel %d", g_n_channels, adap->inf.str_serial, j);
|
||||
g_n_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
return g_n_channels;
|
||||
}
|
||||
|
||||
int pb_romOpen(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_ADAPTERS; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pb_romClosed(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_ADAPTERS; i++) {
|
||||
if (g_adapters[i].handle) {
|
||||
gcn64lib_suspendPolling(g_adapters[i].handle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timing(int start, const char *label)
|
||||
{
|
||||
#ifdef ENABLE_TIMING
|
||||
static struct timeval tv_start;
|
||||
static int started = 0;
|
||||
struct timeval tv_now;
|
||||
|
||||
if (start) {
|
||||
gettimeofday(&tv_start, NULL);
|
||||
started = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (started) {
|
||||
gettimeofday(&tv_now, NULL);
|
||||
printf("%s: %ld us\n", label, (tv_now.tv_sec - tv_start.tv_sec) * 1000000 + (tv_now.tv_usec - tv_start.tv_usec) );
|
||||
started = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void debug_raw_commands_in(unsigned char *command, int channel_id)
|
||||
{
|
||||
int tx_len = command[0];
|
||||
int rx_len = command[1] & 0x3F;
|
||||
int i;
|
||||
|
||||
printf("chn %d: tx[%d] = {", channel_id, tx_len);
|
||||
for (i=0; i<tx_len; i++) {
|
||||
printf("0x%02x ", command[2+i]);
|
||||
}
|
||||
printf("}, expecting %d byte%c\n", rx_len, rx_len > 1 ? 's':' ');
|
||||
|
||||
}
|
||||
|
||||
static void debug_raw_commands_out(unsigned char *command, int channel_id)
|
||||
{
|
||||
int result = command[1];
|
||||
int i;
|
||||
|
||||
printf("chn %d: result: 0x%02x : ", channel_id, result);
|
||||
if (0 == (command[1] & 0xC0)) {
|
||||
for (i=0; i<result; i++) {
|
||||
printf("0x%02x ", command[2+i]);
|
||||
}
|
||||
} else {
|
||||
printf("error\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int pb_controllerCommand(int Control, unsigned char *Command)
|
||||
{
|
||||
// I thought of sending requests to the adapter from here, reading
|
||||
// the results later in readController.
|
||||
//
|
||||
// But unlike what I expected, controllerCommand is NOT always called
|
||||
// before readController... Will investigate later.
|
||||
#ifdef TIME_COMMAND_TO_READ
|
||||
timing(1, NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pb_performIo(void)
|
||||
{
|
||||
struct adapter *adap;
|
||||
struct blockio_op *biops;
|
||||
int j, i, res;
|
||||
int op_was_extio[MAX_OPS] = { };
|
||||
|
||||
for (j=0; j<g_n_channels; j++)
|
||||
{
|
||||
adap = &g_adapters[j];
|
||||
biops = adap->biops;
|
||||
|
||||
/* Skip adapters that do not have IO operations queued. */
|
||||
if (adap->n_ops <= 0)
|
||||
continue;
|
||||
|
||||
#ifdef TRACE_BLOCK_IO
|
||||
for (i=0; i<adap->n_ops; i++) {
|
||||
if (EXTENSION_RW_ONLY && (biops[i].tx_data[0] < 0x02))
|
||||
continue;
|
||||
op_was_extio[i] = 1;
|
||||
printf("Before blockIO: op %d, chn: %d, : tx: 0x%02x, rx: 0x%02x, data: ", i, biops[i].chn,
|
||||
biops[i].tx_len, biops[i].rx_len);
|
||||
printHexBuf(biops[i].tx_data, biops[i].tx_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIME_RAW_IO
|
||||
timing(1, NULL);
|
||||
#endif
|
||||
res = gcn64lib_blockIO(adap->handle, biops, adap->n_ops);
|
||||
#ifdef TIME_RAW_IO
|
||||
timing(0, "blockIO");
|
||||
#endif
|
||||
|
||||
if (res == 0) {
|
||||
// biops rx_data pointed into PIFram so data is there. But we need
|
||||
// to patch the RX length parameters (the two most significant bits
|
||||
// are error bits such as timeout..)
|
||||
for (i=0; i<adap->n_ops; i++) {
|
||||
// in PIFram, the read length is one byte before the tx data. A rare
|
||||
// occasion to use a negative array index ;)
|
||||
biops[i].tx_data[-1] = biops[i].rx_len;
|
||||
|
||||
#ifdef TRACE_BLOCK_IO
|
||||
if (EXTENSION_RW_ONLY && (!op_was_extio[i])) // Read
|
||||
continue;
|
||||
|
||||
printf("After blockIO: op %d, chn: %d, : tx: 0x%02x, rx: 0x%02x, data: ", i, biops[i].chn,
|
||||
biops[i].tx_len, biops[i].rx_len);
|
||||
if (biops[i].rx_len & BIO_RX_LEN_TIMEDOUT) {
|
||||
printf("Timeout\n");
|
||||
} else if (biops[i].rx_len & BIO_RX_LEN_PARTIAL) {
|
||||
printf("Incomplete\n");
|
||||
} else {
|
||||
printHexBuf(biops[i].rx_data, biops[i].rx_len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// For debugging
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
adap->n_ops = 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int pb_commandIsValid(int Control, unsigned char *Command)
|
||||
{
|
||||
if (Control < 0 || Control >= g_n_channels) {
|
||||
DebugMessage(PB_MSG_WARNING, "pb_readController called with Control=%d", Control);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Command) {
|
||||
DebugMessage(PB_MSG_WARNING, "pb_readController called with NULL Command pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When a CIC challenge took place in update_pif_write(), the pif ram
|
||||
// contains a bunch 0xFF followed by 0x00 at offsets 46 and 47. Offset
|
||||
// 48 onwards contains the challenge answer.
|
||||
//
|
||||
// Then when update_pif_read() is called, the 0xFF bytes are be skipped
|
||||
// up to the two 0x00 bytes that increase the channel to 2. Then the
|
||||
// challenge answer is (incorrectly) processed as if it were commands
|
||||
// for the third controller.
|
||||
//
|
||||
// This cause issues with the raphnetraw plugin since it modifies pif ram
|
||||
// to store the result or command error flags. This corrupts the reponse
|
||||
// and leads to challenge failure.
|
||||
//
|
||||
// As I know of no controller commands above 0x03, the filter below guards
|
||||
// against this condition...
|
||||
//
|
||||
if (Control == 2 && Command[2] > 0x03) {
|
||||
DebugMessage(PB_MSG_WARNING, "Invalid controller command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When Mario Kart 64 uses a controller pak, such PIF ram content
|
||||
// occurs:
|
||||
//
|
||||
// ff 03 21 02 01 f7 ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff ff
|
||||
// ff ff ff ff ff ff ff 21
|
||||
// fe 00 00 00 00 00 00 00
|
||||
// 00 00 00 00 00 00 00 00
|
||||
// 00 00 00 00 00 00 00 00
|
||||
//
|
||||
// It results in this:
|
||||
// - Transmission of 3 bytes with a 33 bytes return on channel 0,
|
||||
// - Transmission of 33 bytes with 254 bytes in return on channel 1!?
|
||||
//
|
||||
// Obviously the second transaction is an error. The 0xFE (254) that follows
|
||||
// is where processing should actually stop. This happens to be an invalid length detectable
|
||||
// by looking at the two most significant bits..
|
||||
//
|
||||
if (Command[0] == 0xFE && Command[1] == 0x00) {
|
||||
DebugMessage(PB_MSG_WARNING, "Ignoring invalid io operation (T: 0x%02x, R: 0x%02x)",
|
||||
Command[0], Command[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pb_readController(int Control, unsigned char *Command)
|
||||
{
|
||||
struct rawChannel *channel;
|
||||
struct adapter *adap;
|
||||
struct blockio_op *biops;
|
||||
|
||||
// Called with -1 at the end of PIF ram.
|
||||
if (Control == -1) {
|
||||
return pb_performIo();
|
||||
}
|
||||
|
||||
/* Check for out of bounds Control parameter, for
|
||||
* NULL Command and filter various invalid conditions. */
|
||||
if (!pb_commandIsValid(Control, Command)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add the IO operation to the block io list of
|
||||
* the adapter serving this channel. */
|
||||
|
||||
channel = &g_channels[Control];
|
||||
adap = channel->adapter;
|
||||
|
||||
if (adap->n_ops >= MAX_OPS) {
|
||||
DebugMessage(PB_MSG_ERROR, "Too many io ops");
|
||||
} else {
|
||||
biops = adap->biops;
|
||||
|
||||
biops[adap->n_ops].chn = channel->chn; // Control;
|
||||
biops[adap->n_ops].tx_len = Command[0] & BIO_RXTX_MASK;
|
||||
biops[adap->n_ops].rx_len = Command[1] & BIO_RXTX_MASK;
|
||||
biops[adap->n_ops].tx_data = Command + 2;
|
||||
biops[adap->n_ops].rx_data = Command + 2 + biops[adap->n_ops].tx_len;
|
||||
|
||||
if (biops[adap->n_ops].tx_len == 0 || biops[adap->n_ops].rx_len == 0) {
|
||||
DebugMessage(PB_MSG_WARNING, "TX or RX was zero");
|
||||
return 0;
|
||||
}
|
||||
|
||||
adap->n_ops++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef _plugin_back_h__
|
||||
#define _plugin_back_h__
|
||||
|
||||
/* Those match mupen64plus levels */
|
||||
#define PB_MSG_ERROR 1
|
||||
#define PB_MSG_WARNING 2
|
||||
#define PB_MSG_INFO 3
|
||||
#define PB_MSG_STATUS 4
|
||||
#define PB_MSG_VERBOSE 5
|
||||
|
||||
typedef void (*pb_debugFunc)(int level, const char *message, ...);
|
||||
|
||||
int pb_init(pb_debugFunc debugFn);
|
||||
int pb_shutdown(void);
|
||||
int pb_scanControllers(void);
|
||||
int pb_readController(int Control, unsigned char *Command);
|
||||
int pb_controllerCommand(int Control, unsigned char *Command);
|
||||
int pb_romOpen(void);
|
||||
int pb_romClosed(void);
|
||||
|
||||
#endif // _plugin_back_h__
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
/* mupen64plus-input-raphnetraw
|
||||
*
|
||||
* Copyright (C) 2016 Raphael Assenat
|
||||
*
|
||||
* An input plugin that lets the game under emulation communicate with
|
||||
* the controllers directly using the direct controller communication
|
||||
* feature of raphnet V3 adapters[1].
|
||||
*
|
||||
* [1] http://www.raphnet.net/electronique/gcn64_usb_adapter_gen3/index_en.php
|
||||
*
|
||||
* Based on the Mupen64plus-input-sdl plugin (original banner below)
|
||||
*/
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-input-sdl - plugin.c *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2008-2011 Richard Goedeken *
|
||||
* Copyright (C) 2008 Tillin9 *
|
||||
* Copyright (C) 2002 Blight *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define M64P_PLUGIN_PROTOTYPES 1
|
||||
#include "config.h"
|
||||
#include "m64p_common.h"
|
||||
#include "m64p_config.h"
|
||||
#include "m64p_plugin.h"
|
||||
#include "m64p_types.h"
|
||||
#include "osal_dynamiclib.h"
|
||||
#include "plugin_front.h"
|
||||
#include "plugin_back.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#endif /* __linux__ */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define MAX_CONTROLLERS 4
|
||||
|
||||
#ifdef PORTS_1_AND_4
|
||||
static int emu2adap_portmap[MAX_CONTROLLERS] = { 0, 2, 3, 1 };
|
||||
#undef PLUGIN_NAME
|
||||
#define PLUGIN_NAME "raphnetraw ports 1 and 4"
|
||||
#else
|
||||
static int emu2adap_portmap[MAX_CONTROLLERS] = { 0, 1, 2, 3 };
|
||||
#endif
|
||||
|
||||
#define EMU_2_ADAP_PORT(a) ((a) == -1 ? -1 : emu2adap_portmap[a])
|
||||
|
||||
#if 0
|
||||
/* definitions of pointers to Core config functions */
|
||||
ptr_ConfigOpenSection ConfigOpenSection = NULL;
|
||||
ptr_ConfigDeleteSection ConfigDeleteSection = NULL;
|
||||
ptr_ConfigSaveSection ConfigSaveSection = NULL;
|
||||
ptr_ConfigListParameters ConfigListParameters = NULL;
|
||||
ptr_ConfigSaveFile ConfigSaveFile = NULL;
|
||||
ptr_ConfigSetParameter ConfigSetParameter = NULL;
|
||||
ptr_ConfigGetParameter ConfigGetParameter = NULL;
|
||||
ptr_ConfigGetParameterHelp ConfigGetParameterHelp = NULL;
|
||||
ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL;
|
||||
ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL;
|
||||
ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL;
|
||||
ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL;
|
||||
ptr_ConfigGetParamInt ConfigGetParamInt = NULL;
|
||||
ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;
|
||||
ptr_ConfigGetParamBool ConfigGetParamBool = NULL;
|
||||
ptr_ConfigGetParamString ConfigGetParamString = NULL;
|
||||
|
||||
ptr_ConfigGetSharedDataFilepath ConfigGetSharedDataFilepath = NULL;
|
||||
ptr_ConfigGetUserConfigPath ConfigGetUserConfigPath = NULL;
|
||||
ptr_ConfigGetUserDataPath ConfigGetUserDataPath = NULL;
|
||||
ptr_ConfigGetUserCachePath ConfigGetUserCachePath = NULL;
|
||||
#endif
|
||||
|
||||
/* static data definitions */
|
||||
static void (*l_DebugCallback)(void *, int, const char *) = NULL;
|
||||
static void *l_DebugCallContext = NULL;
|
||||
static int l_PluginInit = 0;
|
||||
|
||||
/* Global functions */
|
||||
static void DebugMessage(int level, const char *message, ...)
|
||||
{
|
||||
char msgbuf[1024];
|
||||
va_list args;
|
||||
|
||||
if (!l_DebugCallback) {
|
||||
printf("No debug callback!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(args, message);
|
||||
vsnprintf(msgbuf, sizeof(msgbuf), message, args);
|
||||
|
||||
(*l_DebugCallback)(l_DebugCallContext, level, msgbuf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
/* Mupen64Plus plugin functions */
|
||||
EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
|
||||
void (*DebugCallback)(void *, int, const char *))
|
||||
{
|
||||
ptr_CoreGetAPIVersions CoreAPIVersionFunc;
|
||||
|
||||
int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion;
|
||||
|
||||
if (l_PluginInit) {
|
||||
return M64ERR_ALREADY_INIT;
|
||||
}
|
||||
|
||||
l_DebugCallback = DebugCallback;
|
||||
l_DebugCallContext = Context;
|
||||
|
||||
/* attach and call the CoreGetAPIVersions function, check Config API version for compatibility */
|
||||
CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions");
|
||||
if (CoreAPIVersionFunc == NULL)
|
||||
{
|
||||
DebugMessage(M64MSG_ERROR, "Core emulator broken; no CoreAPIVersionFunc() function found.");
|
||||
return M64ERR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
(*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL);
|
||||
if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000) || ConfigAPIVersion < CONFIG_API_VERSION)
|
||||
{
|
||||
DebugMessage(M64MSG_ERROR, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)",
|
||||
VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION));
|
||||
return M64ERR_INCOMPATIBLE;
|
||||
}
|
||||
#if 0
|
||||
/* Get the core config function pointers from the library handle */
|
||||
ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection");
|
||||
ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreLibHandle, "ConfigDeleteSection");
|
||||
ConfigSaveFile = (ptr_ConfigSaveFile) osal_dynlib_getproc(CoreLibHandle, "ConfigSaveFile");
|
||||
ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreLibHandle, "ConfigSaveSection");
|
||||
ConfigListParameters = (ptr_ConfigListParameters) osal_dynlib_getproc(CoreLibHandle, "ConfigListParameters");
|
||||
ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter");
|
||||
ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter");
|
||||
ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt");
|
||||
ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat");
|
||||
ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool");
|
||||
ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString");
|
||||
ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt");
|
||||
ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");
|
||||
ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");
|
||||
ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");
|
||||
|
||||
ConfigGetSharedDataFilepath = (ptr_ConfigGetSharedDataFilepath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetSharedDataFilepath");
|
||||
ConfigGetUserConfigPath = (ptr_ConfigGetUserConfigPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserConfigPath");
|
||||
ConfigGetUserDataPath = (ptr_ConfigGetUserDataPath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserDataPath");
|
||||
ConfigGetUserCachePath = (ptr_ConfigGetUserCachePath) osal_dynlib_getproc(CoreLibHandle, "ConfigGetUserCachePath");
|
||||
|
||||
if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSaveFile || !ConfigSaveSection || !ConfigSetParameter || !ConfigGetParameter ||
|
||||
!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
|
||||
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString ||
|
||||
!ConfigGetSharedDataFilepath || !ConfigGetUserConfigPath || !ConfigGetUserDataPath || !ConfigGetUserCachePath)
|
||||
{
|
||||
DebugMessage(M64MSG_ERROR, "Couldn't connect to Core configuration functions");
|
||||
return M64ERR_INCOMPATIBLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
pb_init(DebugMessage);
|
||||
|
||||
l_PluginInit = 1;
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginShutdown(void)
|
||||
{
|
||||
if (!l_PluginInit) {
|
||||
return M64ERR_NOT_INIT;
|
||||
}
|
||||
|
||||
/* reset some local variables */
|
||||
l_DebugCallback = NULL;
|
||||
l_DebugCallContext = NULL;
|
||||
|
||||
pb_shutdown();
|
||||
|
||||
l_PluginInit = 0;
|
||||
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)
|
||||
{
|
||||
/* set version info */
|
||||
if (PluginType != NULL)
|
||||
*PluginType = M64PLUGIN_INPUT;
|
||||
|
||||
if (PluginVersion != NULL)
|
||||
*PluginVersion = PLUGIN_VERSION;
|
||||
|
||||
if (APIVersion != NULL)
|
||||
*APIVersion = INPUT_PLUGIN_API_VERSION;
|
||||
|
||||
if (PluginNamePtr != NULL)
|
||||
*PluginNamePtr = PLUGIN_NAME;
|
||||
|
||||
if (Capabilities != NULL)
|
||||
{
|
||||
*Capabilities = 0;
|
||||
}
|
||||
|
||||
return M64ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Function: InitiateControllers
|
||||
Purpose: This function initialises how each of the controllers
|
||||
should be handled.
|
||||
input: - The handle to the main window.
|
||||
- A controller structure that needs to be filled for
|
||||
the emulator to know how to handle each controller.
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo)
|
||||
{
|
||||
int i, n_controllers, adap_port;
|
||||
|
||||
n_controllers = pb_scanControllers();
|
||||
|
||||
if (n_controllers <= 0) {
|
||||
DebugMessage(PB_MSG_ERROR, "No adapters detected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_CONTROLLERS; i++) {
|
||||
adap_port = EMU_2_ADAP_PORT(i);
|
||||
|
||||
if (adap_port < n_controllers) {
|
||||
ControlInfo.Controls[i].RawData = 1;
|
||||
|
||||
/* Setting this is currently required or we
|
||||
* won't be called at all.
|
||||
*
|
||||
* Look at pif.c update_pif_write() to see why.
|
||||
*/
|
||||
ControlInfo.Controls[i].Present = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DebugMessage(PB_MSG_INFO, "%s version %i.%i.%i %s(compiled "__DATE__" "__TIME__") initialized.", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION),
|
||||
#ifdef _DEBUG
|
||||
"DEBUG "
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
Function: ReadController
|
||||
Purpose: To process the raw data in the pif ram that is about to
|
||||
be read.
|
||||
input: - Controller Number (0 to 3) and -1 signalling end of
|
||||
processing the pif ram.
|
||||
- Pointer of data to be processed.
|
||||
output: none
|
||||
note: This function is only needed if the DLL is allowing raw
|
||||
data.
|
||||
*******************************************************************/
|
||||
EXPORT void CALL ReadController(int Control, unsigned char *Command)
|
||||
{
|
||||
pb_readController(EMU_2_ADAP_PORT(Control), Command);
|
||||
}
|
||||
|
||||
EXPORT void CALL ControllerCommand(int Control, unsigned char *Command)
|
||||
{
|
||||
pb_controllerCommand(EMU_2_ADAP_PORT(Control), Command);
|
||||
}
|
||||
|
||||
EXPORT void CALL GetKeys( int Control, BUTTONS *Keys )
|
||||
{
|
||||
}
|
||||
|
||||
EXPORT void CALL RomClosed(void)
|
||||
{
|
||||
pb_romClosed();
|
||||
}
|
||||
|
||||
EXPORT int CALL RomOpen(void)
|
||||
{
|
||||
pb_romOpen();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Function: SDL_KeyDown
|
||||
Purpose: To pass the SDL_KeyDown message from the emulator to the
|
||||
plugin.
|
||||
input: keymod and keysym of the SDL_KEYDOWN message.
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL SDL_KeyDown(int keymod, int keysym)
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Function: SDL_KeyUp
|
||||
Purpose: To pass the SDL_KeyUp message from the emulator to the
|
||||
plugin.
|
||||
input: keymod and keysym of the SDL_KEYUP message.
|
||||
output: none
|
||||
*******************************************************************/
|
||||
EXPORT void CALL SDL_KeyUp(int keymod, int keysym)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-input-sdl - plugin.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2008-2009 Richard Goedeken *
|
||||
* Copyright (C) 2008 Tillin9 *
|
||||
* Copyright (C) 2002 Blight *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public 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 __PLUGIN_H__
|
||||
#define __PLUGIN_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define M64P_PLUGIN_PROTOTYPES 1
|
||||
#include "m64p_config.h"
|
||||
#include "m64p_plugin.h"
|
||||
|
||||
#define DEVICE_NO_JOYSTICK (-1)
|
||||
|
||||
// Some stuff from n-rage plugin
|
||||
#define RD_GETSTATUS 0x00 // get status
|
||||
#define RD_READKEYS 0x01 // read button values
|
||||
#define RD_READPAK 0x02 // read from controllerpack
|
||||
#define RD_WRITEPAK 0x03 // write to controllerpack
|
||||
#define RD_RESETCONTROLLER 0xff // reset controller
|
||||
#define RD_READEEPROM 0x04 // read eeprom
|
||||
#define RD_WRITEEPROM 0x05 // write eeprom
|
||||
|
||||
#define PAK_IO_RUMBLE 0xC000 // the address where rumble-commands are sent to
|
||||
|
||||
/* declarations of pointers to Core config functions */
|
||||
extern ptr_ConfigListSections ConfigListSections;
|
||||
extern ptr_ConfigOpenSection ConfigOpenSection;
|
||||
extern ptr_ConfigDeleteSection ConfigDeleteSection;
|
||||
extern ptr_ConfigListParameters ConfigListParameters;
|
||||
extern ptr_ConfigSaveFile ConfigSaveFile;
|
||||
extern ptr_ConfigSaveSection ConfigSaveSection;
|
||||
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;
|
||||
|
||||
#endif // __PLUGIN_H__
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _gcn64_requests_h__
|
||||
#define _gcn64_requests_h__
|
||||
|
||||
/* Commands */
|
||||
#define RQ_GCN64_SET_CONFIG_PARAM 0x01
|
||||
#define RQ_GCN64_GET_CONFIG_PARAM 0x02
|
||||
#define RQ_GCN64_SUSPEND_POLLING 0x03
|
||||
#define RQ_GCN64_GET_VERSION 0x04
|
||||
#define RQ_GCN64_GET_SIGNATURE 0x05
|
||||
#define RQ_GCN64_GET_CONTROLLER_TYPE 0x06
|
||||
#define RQ_GCN64_SET_VIBRATION 0x07
|
||||
#define RQ_GCN64_RAW_SI_COMMAND 0x80
|
||||
#define RQ_GCN64_BLOCK_IO 0x81
|
||||
#define RQ_GCN64_JUMP_TO_BOOTLOADER 0xFF
|
||||
|
||||
/* Configuration parameters and constants */
|
||||
#define CFG_PARAM_MODE 0x00
|
||||
|
||||
/* Values for mode */
|
||||
#define CFG_MODE_STANDARD 0x00
|
||||
#define CFG_MODE_N64_ONLY 0x01
|
||||
#define CFG_MODE_GC_ONLY 0x02
|
||||
|
||||
#define CFG_PARAM_SERIAL 0x01
|
||||
|
||||
#define CFG_PARAM_POLL_INTERVAL0 0x10
|
||||
#define CFG_PARAM_POLL_INTERVAL1 0x11
|
||||
#define CFG_PARAM_POLL_INTERVAL2 0x12
|
||||
#define CFG_PARAM_POLL_INTERVAL3 0x13
|
||||
|
||||
#define CFG_PARAM_N64_SQUARE 0x20 // Not implemented
|
||||
#define CFG_PARAM_GC_MAIN_SQUARE 0x21 // Not implemented
|
||||
#define CFG_PARAM_GC_CSTICK_SQUARE 0x22 // Not implemented
|
||||
#define CFG_PARAM_FULL_SLIDERS 0x23
|
||||
#define CFG_PARAM_INVERT_TRIG 0x24
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Mupen64plus-input-sdl - version.h *
|
||||
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
||||
* Copyright (C) 2009-2012 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. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/* This header file is for versioning information
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
#define PLUGIN_NAME "Mupen64Plus raphnetraw Input Plugin"
|
||||
#define PLUGIN_VERSION 0x010100
|
||||
//#define INPUT_PLUGIN_API_VERSION 0x020000
|
||||
#define INPUT_PLUGIN_API_VERSION 0x020100
|
||||
#define CONFIG_API_VERSION 0x020100
|
||||
|
||||
#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
|
||||
|
||||
#endif /* #define VERSION_H */
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
#pragma once
|
||||
#include "ultra64/thread.h"
|
||||
|
||||
struct AudioMgr;
|
||||
struct SchedContext;
|
||||
struct IrqMgr;
|
||||
|
@ -8,4 +10,5 @@ void AudioMgr_HandleRetrace(AudioMgr* audioMgr);
|
|||
void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedContext* sched, IrqMgr* irqMgr);
|
||||
void AudioMgr_ThreadEntry(void* arg0);
|
||||
void AudioMgr_Unlock(AudioMgr* audioMgr);
|
||||
void AudioMgr_Shutdown();
|
||||
void AudioMgr_Shutdown();
|
||||
void AudioMgr_Pause(bool pauseOn);
|
|
@ -10,3 +10,9 @@ void GfxPrint_SetBasePosPx(GfxPrint* pthis, s32 x, s32 y, u8 multiplier = 4);
|
|||
void GfxPrint_SetColor(GfxPrint* pthis, u8 r, u8 g, u8 b, u8 a);
|
||||
void GfxPrint_SetPos(GfxPrint* pthis, s32 x, s32 y);
|
||||
void GfxPrint_SetPosPx(GfxPrint* pthis, s32 x, s32 y);
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
void Debug_Clear();
|
||||
void Debug_Print(const char* String);
|
||||
void Debug_Draw(GraphicsContext* gfxCtx);
|
||||
#endif
|
|
@ -12,6 +12,7 @@ void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src);
|
|||
void Lib_MemSet(u8* dest, size_t size, u8 val);
|
||||
void Math_ApproachF(f32* pValue, f32 target, f32 fraction, const Step& step);
|
||||
void Math_ApproachF(CounterF* pValue, f32 target, f32 fraction, const Step& step);
|
||||
void Math_ApproachF(Rotation* pValue, f32 target, f32 fraction, const Step& step);
|
||||
void Math_ApproachS(s16* pValue, s16 target, s16 scale, const Step& step);
|
||||
void Math_ApproachS(Rotation* pValue, s16 target, s16 scale, const FStep& step);
|
||||
void Math_ApproachZeroF(f32* pValue, f32 fraction, const Step& step);
|
||||
|
@ -19,10 +20,12 @@ f32 Math_ApproachZeroF(f32 pValue, f32 fraction, const Step& step);
|
|||
void Math_ApproachZeroF(CounterF* pValue, f32 fraction, const Step& step);
|
||||
s32 Math_AsymStepToF(f32* pValue, f32 target, const Step& incrStep, const Step& decrStep);
|
||||
s32 Math_AsymStepToF(CounterF* pValue, f32 target, const Step& incrStep, const Step& decrStep);
|
||||
f32 Math_CosS(s16 angle);
|
||||
s32 Math_ScaledStepToS(s16* pValue, s16 target, const FStep& step);
|
||||
s32 Math_ScaledStepToS(Rotation* pValue, s16 target, const FStep& step);
|
||||
f32 Math_CosS(s16 angle);
|
||||
f32 Math_SinS(s16 angle);
|
||||
f32 Math_AccurateCosS(s16 angle);
|
||||
f32 Math_AccurateSinS(s16 angle);
|
||||
f32 Math_SmoothStepToDegF(f32* pValue, f32 target, f32 fraction, const Step& step, const Step& minStep);
|
||||
f32 Math_SmoothStepToF(f32* pValue, f32 target, f32 fraction, const Step& step, const Step& minStep);
|
||||
f32 Math_SmoothStepToF(Rotation* pValue, f32 target, f32 fraction, const FStep& step, const FStep& minStep);
|
||||
|
@ -46,6 +49,7 @@ s32 Math_StepUntilF(CounterF* pValue, f32 limit, const Step& step);
|
|||
s32 Math_StepUntilS(s16* pValue, s16 limit, const Step& step);
|
||||
s32 Math_StepUntilS(Rotation* pValue, s16 limit, const FStep& step);
|
||||
void Math_Vec3f_Copy(Vec3f* dest, Vec3f* src);
|
||||
void Math_VecPos_Copy(VecPos* dest, Vec3f* src);
|
||||
void Math_Vec3f_Diff(Vec3f* a, Vec3f* b, Vec3f* dest);
|
||||
f32 Math_Vec3f_DistXYZ(Vec3f* a, Vec3f* b);
|
||||
f32 Math_Vec3f_DistXYZAndStoreDiff(Vec3f* a, Vec3f* b, Vec3f* dest);
|
||||
|
|
|
@ -56,8 +56,8 @@ void Player_UpdateBottleHeld(GlobalContext* globalCtx, Player* player, s32 item,
|
|||
s32 Player_IsTargetingAnActor(Player* player);
|
||||
void func_8008EC70(Player* player);
|
||||
void Player_ClearZTarget(Player* player);
|
||||
void func_8008EE08(Player* player);
|
||||
void func_8008EEAC(GlobalContext* globalCtx, Actor* actor);
|
||||
void SetFlagsForClearZTarget(Player* player);
|
||||
void StartInvolintaryZtarget(GlobalContext* globalCtx, Actor* actor);
|
||||
s32 func_8008EF44(GlobalContext* globalCtx, s32 ammo);
|
||||
s32 Player_HoldingHookshot(Player* player);
|
||||
s32 func_8008F2BC(Player* player, s32 actionParam);
|
||||
|
|
|
@ -562,12 +562,14 @@ class CounterF
|
|||
|
||||
CounterF& operator+=(float f)
|
||||
{
|
||||
m_counterScaler = FRAMERATE_SCALER_INV;
|
||||
m_counter += f / m_counterScaler;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CounterF& operator-=(float f)
|
||||
{
|
||||
m_counterScaler = FRAMERATE_SCALER_INV;
|
||||
m_counter -= f / m_counterScaler;
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -433,11 +433,10 @@ struct TargetContext
|
|||
/* 0x3C */ Actor* targetedActor;
|
||||
/* 0x40 */ f32 unk_40;
|
||||
/* 0x44 */ f32 unk_44;
|
||||
/* 0x48 */ s16 unk_48;
|
||||
/* 0x48 */ TimerS16 unk_48;
|
||||
/* 0x4A */ u8 activeCategory;
|
||||
/* 0x4B */ Counter unk_4B;
|
||||
/* 0x4C */ s8 unk_4C;
|
||||
/* 0x4D */ char unk_4D[0x03];
|
||||
/* 0x4B */ TimerU8 unk_4B;
|
||||
/* 0x4C */ TimerS8 unk_4C;
|
||||
/* 0x50 */ TargetContextEntry arr_50[3];
|
||||
/* 0x8C */ Actor* unk_8C;
|
||||
/* 0x90 */ Actor* bgmEnemy; // The nearest enemy to player with the right flags that will trigger NA_BGM_ENEMY
|
||||
|
|
|
@ -848,9 +848,9 @@ typedef struct
|
|||
#ifdef LITTLE_ENDIAN
|
||||
struct
|
||||
{
|
||||
u8 arg2;
|
||||
u8 arg1;
|
||||
u8 arg0;
|
||||
u8 scriptIndex;
|
||||
u8 seqPlayerChannelIndex;
|
||||
u8 seqPlayerIndex;
|
||||
u8 op;
|
||||
};
|
||||
#else
|
||||
|
|
|
@ -216,8 +216,8 @@ struct Normal1Anim
|
|||
/* 0x20 */ f32 unk_20;
|
||||
/* 0x24 */ s16 slopePitchAdj;
|
||||
/* 0x26 */ s16 swingYawTarget;
|
||||
/* 0x28 */ s16 distTimer;
|
||||
/* 0x2A */ s16 startSwingTimer;
|
||||
/* 0x28 */ TimerS16 distTimer;
|
||||
/* 0x2A */ TimerS16 startSwingTimer;
|
||||
}; // size = 0x2C
|
||||
|
||||
struct Normal1
|
||||
|
@ -340,7 +340,7 @@ struct Jump2Anim
|
|||
/* 0x6 */ s16 initYawDiff; // unused, set but not read.
|
||||
/* 0x8 */ s16 yawAdj;
|
||||
/* 0xA */ s16 onFloor; // unused, set but not read
|
||||
/* 0xC */ s16 animTimer;
|
||||
/* 0xC */ TimerS16 animTimer;
|
||||
}; // size = 0x10
|
||||
|
||||
struct Jump2
|
||||
|
@ -413,7 +413,7 @@ struct Battle1
|
|||
|
||||
struct Battle4Anim
|
||||
{
|
||||
/* 0x0000 */ s16 animTimer;
|
||||
/* 0x0000 */ TimerS16 animTimer;
|
||||
}; // size = 0x2
|
||||
|
||||
struct Battle4
|
||||
|
@ -434,11 +434,11 @@ struct Keep1Anim
|
|||
/* 0x00 */ f32 unk_00;
|
||||
/* 0x04 */ f32 unk_04;
|
||||
/* 0x08 */ f32 unk_08;
|
||||
/* 0x0C */ struct Actor* unk_0C;
|
||||
/* 0x0C */ struct Actor* currentTarget;
|
||||
/* 0x10 */ s16 unk_10;
|
||||
/* 0x12 */ s16 unk_12;
|
||||
/* 0x14 */ s16 unk_14;
|
||||
/* 0x16 */ s16 unk_16;
|
||||
/* 0x16 */ TimerS16 unk_16;
|
||||
}; // size = 0x18
|
||||
|
||||
struct KeepOn1
|
||||
|
@ -591,7 +591,7 @@ struct Subj3Anim
|
|||
/* 0x0 */ f32 r;
|
||||
/* 0x4 */ s16 yaw;
|
||||
/* 0x6 */ s16 pitch;
|
||||
/* 0x8 */ s16 animTimer;
|
||||
/* 0x8 */ TimerS16 animTimer;
|
||||
}; // size = 0xC
|
||||
|
||||
struct Subj3
|
||||
|
@ -645,9 +645,9 @@ struct Data4
|
|||
struct Unique1Anim
|
||||
{
|
||||
/* 0x0 */ f32 unk_00; // unused
|
||||
/* 0x4 */ s16 yawTarget;
|
||||
/* 0x4 */ Rotation yawTarget;
|
||||
/* 0x6 */ s16 yawTargetAdj;
|
||||
/* 0x8 */ s16 timer;
|
||||
/* 0x8 */ TimerS16 timer;
|
||||
}; // size = 0xC
|
||||
|
||||
struct Unique1
|
||||
|
@ -695,9 +695,9 @@ struct DoorParams
|
|||
{
|
||||
/* 0x0 */ struct Actor* doorActor;
|
||||
/* 0x4 */ s16 camDataIdx;
|
||||
/* 0x6 */ s16 timer1;
|
||||
/* 0x8 */ s16 timer2;
|
||||
/* 0xA */ s16 timer3;
|
||||
/* 0x6 */ TimerS16 timer1;
|
||||
/* 0x8 */ TimerS16 timer2;
|
||||
/* 0xA */ TimerS16 timer3;
|
||||
}; // size = 0xC
|
||||
|
||||
struct Unique3
|
||||
|
@ -818,8 +818,8 @@ struct Demo1
|
|||
struct Demo3Anim
|
||||
{
|
||||
/* 0x00 */ Vec3f initialAt;
|
||||
/* 0x0C */ f32 unk_0C;
|
||||
/* 0x10 */ s16 animFrame;
|
||||
/* 0x0C */ TimerF32 stepScale;
|
||||
/* 0x10 */ TimerS16 animFrame;
|
||||
/* 0x12 */ s16 yawDir;
|
||||
}; // size = 0x14
|
||||
|
||||
|
@ -850,7 +850,7 @@ struct Demo9Anim
|
|||
/* 0x4 */ s16 keyframe;
|
||||
/* 0x6 */ s16 doLERPAt;
|
||||
/* 0x8 */ s16 finishAction;
|
||||
/* 0xA */ s16 animTimer;
|
||||
/* 0xA */ TimerS16 animTimer;
|
||||
}; // size = 0xC
|
||||
|
||||
struct Demo9
|
||||
|
@ -1011,7 +1011,7 @@ struct Camera
|
|||
/* 0x166 */ s16 prevCamDataIdx;
|
||||
/* 0x168 */ s16 csId;
|
||||
/* 0x16A */ s16 unk_16A;
|
||||
/* 0x16C */ s16 startControlTimer;
|
||||
/* 0x16C */ TimerS16 startControlTimer;
|
||||
}; // size = 0x16C
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,10 +23,10 @@ struct EffectStatus
|
|||
|
||||
struct EffectSparkElement
|
||||
{
|
||||
/* 0x00 */ Vec3f velocity;
|
||||
/* 0x0C */ Vec3f position;
|
||||
/* 0x18 */ Vec3s unkVelocity;
|
||||
/* 0x1E */ Vec3s unkPosition;
|
||||
/* 0x00 */ VecPosF velocity;
|
||||
/* 0x0C */ VecPosF position;
|
||||
/* 0x18 */ VecPos unkVelocity;
|
||||
/* 0x1E */ VecPos unkPosition;
|
||||
}; // size = 0x24
|
||||
|
||||
struct EffectSparkInit
|
||||
|
@ -40,7 +40,7 @@ struct EffectSparkInit
|
|||
/* 0x498 */ u32 vDiv; // "v_div"
|
||||
/* 0x49C */ Color_RGBA8 colorStart[4];
|
||||
/* 0x4AC */ Color_RGBA8 colorEnd[4];
|
||||
/* 0x4BC */ s32 timer;
|
||||
/* 0x4BC */ TimerS32 timer;
|
||||
/* 0x4C0 */ s32 duration;
|
||||
}; // size = 0x4C4
|
||||
|
||||
|
@ -55,14 +55,14 @@ struct EffectSpark
|
|||
/* 0x498 */ u32 vDiv; // "v_div"
|
||||
/* 0x49C */ Color_RGBA8 colorStart[4];
|
||||
/* 0x4AC */ Color_RGBA8 colorEnd[4];
|
||||
/* 0x4BC */ s32 timer;
|
||||
/* 0x4BC */ TimerS32 timer;
|
||||
/* 0x4C0 */ s32 duration;
|
||||
}; // size = 0x4C4
|
||||
|
||||
struct EffectBlureElement
|
||||
{
|
||||
/* 0x00 */ s32 state;
|
||||
/* 0x04 */ s32 timer;
|
||||
/* 0x04 */ TimerS32 timer;
|
||||
/* 0x08 */ Vec3s p1;
|
||||
/* 0x0E */ Vec3s p2;
|
||||
/* 0x14 */ u16 flags;
|
||||
|
@ -162,7 +162,7 @@ struct EffectShieldParticle
|
|||
/* 0x1A8 */ f32 maxInitialSpeed;
|
||||
/* 0x1AC */ f32 lengthCutoff;
|
||||
/* 0x1B0 */ u8 duration;
|
||||
/* 0x1B1 */ u8 timer;
|
||||
/* 0x1B1 */ TimerU8 timer;
|
||||
/* 0x1B2 */ LightInfo lightInfo;
|
||||
/* 0x1C0 */ LightNode* lightNode;
|
||||
/* 0x1C4 */ s32 lightDecay; // halves light radius every frame when set to 1
|
||||
|
@ -242,7 +242,7 @@ struct EffectSs
|
|||
/* 0x3C */ struct Actor* actor; // interfacing actor, usually the actor that spawned the effect
|
||||
/* 0x40 */ s32 regs[13]; // specific per effect
|
||||
/* 0x74 */ u16 flags;
|
||||
/* 0x76 */ s16 life; // -1 means this entry is free
|
||||
/* 0x76 */ s16 life;//TimerS16 but causing some to last longer then normal // -1 means this entry is free
|
||||
/* 0x78 */ u8 priority; // Lower value means higher priority
|
||||
/* 0x79 */ u8 type;
|
||||
}; // size = 0x7A
|
||||
|
|
|
@ -45,7 +45,7 @@ struct LightningStrike
|
|||
/* 0x02 */ u8 flashGreen;
|
||||
/* 0x03 */ u8 flashBlue;
|
||||
/* 0x04 */ u8 flashAlphaTarget;
|
||||
/* 0x08 */ f32 delayTimer;
|
||||
/* 0x08 */ TimerF32 delayTimer;
|
||||
}; // size = 0xC
|
||||
|
||||
// describes what skybox files and blending modes to use depending on time of day
|
||||
|
@ -122,9 +122,9 @@ struct EnvironmentContext
|
|||
/* 0xD8 */ f32 unk_D8; // indoor light blend weight?
|
||||
/* 0xDC */ u8 unk_DC;
|
||||
/* 0xDD */ u8 gloomySkyMode;
|
||||
/* 0xDE */ u8 unk_DE; // gloomy sky state
|
||||
/* 0xDE */ u8 skyState; // gloomy sky state
|
||||
/* 0xDF */ u8 lightningMode;
|
||||
/* 0xE0 */ u8 unk_E0; // env sounds state
|
||||
/* 0xE0 */ u8 dayState; // env sounds state
|
||||
/* 0xE1 */ u8 fillScreen;
|
||||
/* 0xE2 */ u8 screenFillColor[4];
|
||||
/* 0xE6 */ u8 sandstormState;
|
||||
|
|
|
@ -22,7 +22,7 @@ struct Vec2f
|
|||
|
||||
struct Vec3f
|
||||
{
|
||||
f32 x, y, z;
|
||||
f32 x, y, z;
|
||||
}; // size = 0x0C
|
||||
|
||||
struct Vec3us
|
||||
|
@ -64,6 +64,22 @@ struct VecPosF
|
|||
CounterF x, y, z;
|
||||
};
|
||||
*/
|
||||
struct VecCounterF
|
||||
{
|
||||
VecCounterF();
|
||||
VecCounterF(const CounterF& x, const CounterF& y, const CounterF& z);
|
||||
VecCounterF(const Vec3s& vec);
|
||||
VecCounterF(const Vec3f& vec);
|
||||
VecCounterF(Vec3f* vec);
|
||||
VecCounterF(const Vec3f* vec);
|
||||
//Vec3f* operator&();
|
||||
//VecPosF(const Vec3f* vec);
|
||||
operator Vec3s() const;
|
||||
operator Vec3f() const;
|
||||
operator Vec3f*();
|
||||
operator Vec3f*() const;
|
||||
CounterF x, y, z;
|
||||
};
|
||||
|
||||
typedef VecRot VecPos;
|
||||
typedef Vec3f VecRotF;
|
||||
|
|
|
@ -46,7 +46,7 @@ struct SkyboxContext
|
|||
/* 0x138 */ Gfx* unk_138;
|
||||
/* 0x13C */ Vtx* roomVtx;
|
||||
/* 0x140 */ s16 unk_140;
|
||||
/* 0x144 */ Vec3f rot;
|
||||
/* 0x144 */ VecRot rot;
|
||||
/* 0x150 */ char unk_150[0x10];
|
||||
}; // size = 0x160
|
||||
|
||||
|
|
|
@ -754,7 +754,7 @@ struct RoomContext
|
|||
/* 0x34 */ void* unk_34;
|
||||
/* 0x38 */ DmaRequest dmaRequest;
|
||||
/* 0x70 */ OSMesg loadMsg;
|
||||
/* 0x74 */ s16 unk_74[2]; // context-specific data used by the current scene draw config
|
||||
/* 0x74 */ TimerS16 unk_74[2]; // context-specific data used by the current scene draw config
|
||||
}; // size = 0x78
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -2699,7 +2699,7 @@ void Audio_UpdateAll(void)
|
|||
Audio_ProcessSeqCmds();
|
||||
Audio_UpdateActiveSounds();
|
||||
func_800FA3DC();
|
||||
AudioDebug_SetInput();
|
||||
//AudioDebug_SetInput();
|
||||
AudioDebug_ProcessInput();
|
||||
Audio_ScheduleProcessCmds();
|
||||
sAudioUpdateTaskEnd = gAudioContext.totalTaskCnt;
|
||||
|
@ -2707,6 +2707,7 @@ void Audio_UpdateAll(void)
|
|||
}
|
||||
}
|
||||
|
||||
//unused
|
||||
void func_800F314C(s8 arg0)
|
||||
{
|
||||
Audio_QueueCmdS32(CHAN_LOAD_UKN_82 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | (((u8)arg0 & 0xFF) << 8), 1);
|
||||
|
@ -2936,6 +2937,7 @@ f32 Audio_ComputeSoundFreqScale(u8 bankId, u8 entryIdx)
|
|||
return freq;
|
||||
}
|
||||
|
||||
//filter related?
|
||||
u8 func_800F37B8(f32 behindScreenZ, SoundBankEntry* arg1, s8 arg2)
|
||||
{
|
||||
s8 phi_v0;
|
||||
|
|
|
@ -96,6 +96,7 @@ void audio_int()
|
|||
|
||||
static AudioTask* g_currentAudioTask = nullptr;
|
||||
static bool g_aziInit = false;
|
||||
static bool g_aziPause = false;
|
||||
|
||||
void audio_thread()
|
||||
{
|
||||
|
@ -107,7 +108,7 @@ void audio_thread()
|
|||
auto targetTime = std::chrono::high_resolution_clock::now() + interval;
|
||||
while(g_aziInit)
|
||||
{
|
||||
if(std::chrono::high_resolution_clock::now() > targetTime)
|
||||
if(std::chrono::high_resolution_clock::now() > targetTime && !g_aziPause)
|
||||
{
|
||||
auto task = getAudioTask();
|
||||
|
||||
|
@ -190,3 +191,8 @@ void AudioMgr_Shutdown()
|
|||
if(t1.joinable())
|
||||
t1.join();
|
||||
}
|
||||
|
||||
void AudioMgr_Pause(bool pauseOn)
|
||||
{
|
||||
g_aziPause = pauseOn;
|
||||
}
|
||||
|
|
|
@ -217,25 +217,25 @@ void Audio_ProcessLoadCmd(AudioCmd* cmd)
|
|||
switch(cmd->op)
|
||||
{
|
||||
case CHAN_LOAD_UKN_81:
|
||||
AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2);
|
||||
AudioLoad_SyncLoadSeqParts(cmd->seqPlayerChannelIndex, cmd->scriptIndex);
|
||||
return;
|
||||
case CHAN_LOAD_UKN_82:
|
||||
AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2);
|
||||
Audio_LoadSetFadeInTimer(cmd->arg0, (s32)cmd->data);
|
||||
AudioLoad_SyncInitSeqPlayer(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->scriptIndex);
|
||||
Audio_LoadSetFadeInTimer(cmd->seqPlayerIndex, (s32)cmd->data);
|
||||
return;
|
||||
case CHAN_LOAD_UKN_85:
|
||||
AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, (s32)cmd->data);
|
||||
AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, (s32)cmd->data);
|
||||
return;
|
||||
case CHAN_LOAD_DISABLE_SEQUENCE:
|
||||
if(gAudioContext.seqPlayers[cmd->arg0].enabled)
|
||||
if(gAudioContext.seqPlayers[cmd->seqPlayerIndex].enabled)
|
||||
{
|
||||
if(cmd->asInt == 0)
|
||||
{
|
||||
AudioSeq_SequencePlayerDisableAsFinished(&gAudioContext.seqPlayers[cmd->arg0]);
|
||||
AudioSeq_SequencePlayerDisableAsFinished(&gAudioContext.seqPlayers[cmd->seqPlayerIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Audio_LoadSetFadeOutTimer(cmd->arg0, cmd->asInt);
|
||||
Audio_LoadSetFadeOutTimer(cmd->seqPlayerIndex, cmd->asInt);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -276,22 +276,22 @@ void Audio_ProcessLoadCmd(AudioCmd* cmd)
|
|||
|
||||
return;
|
||||
case CHAN_LOAD_INSTRUMENT_ASYNC:
|
||||
AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2);
|
||||
AudioLoad_SyncLoadInstrument(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->scriptIndex);
|
||||
return;
|
||||
case CHAN_LOAD_BANK_ASYNC:
|
||||
AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, nullptr);
|
||||
AudioLoad_AsyncLoadSampleBank(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->scriptIndex, nullptr);
|
||||
return;
|
||||
case CHAN_LOAD_FONT_ASYNC:
|
||||
AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, nullptr);
|
||||
AudioLoad_AsyncLoadFont(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->scriptIndex, nullptr);
|
||||
return;
|
||||
case CHAN_LOAD_UKN_FC:
|
||||
AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, nullptr);
|
||||
AudioLoad_AsyncLoadSeq(cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->scriptIndex, nullptr);
|
||||
return;
|
||||
case CHAN_LOAD_DISCARD_SEQ_FONTS:
|
||||
AudioLoad_DiscardSeqFonts(cmd->arg1);
|
||||
AudioLoad_DiscardSeqFonts(cmd->seqPlayerChannelIndex);
|
||||
return;
|
||||
case CHAN_LOAD_UKN_90:
|
||||
gAudioContext.unk_5BDC[cmd->arg0] = cmd->asUShort;
|
||||
gAudioContext.unk_5BDC[cmd->seqPlayerIndex] = cmd->asUShort;
|
||||
return;
|
||||
case CHAN_LOAD_RESET_LOAD_SPECID:
|
||||
gAudioContext.resetStatus = 5;
|
||||
|
@ -303,7 +303,7 @@ void Audio_ProcessLoadCmd(AudioCmd* cmd)
|
|||
case CHAN_LOAD_SET_FONT_INSTRUMENT0:
|
||||
case CHAN_LOAD_SET_FONT_INSTRUMENT1:
|
||||
case CHAN_LOAD_SET_FONT_INSTRUMENT:
|
||||
Audio_SetFontInstrument(cmd->op - 0xE0, cmd->arg0, cmd->arg1, cmd->data);
|
||||
Audio_SetFontInstrument(cmd->op - 0xE0, cmd->seqPlayerIndex, cmd->seqPlayerChannelIndex, cmd->data);
|
||||
return;
|
||||
case CHAN_LOAD_UKN_FE:
|
||||
temp_t7 = cmd->asUInt;
|
||||
|
@ -444,9 +444,9 @@ void Audio_ProcessCmd(AudioCmd* cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if(cmd->arg0 < gAudioContext.audioBufferParameters.numSequencePlayers)
|
||||
if(cmd->seqPlayerIndex < gAudioContext.audioBufferParameters.numSequencePlayers)
|
||||
{
|
||||
seqPlayer = &gAudioContext.seqPlayers[cmd->arg0];
|
||||
seqPlayer = &gAudioContext.seqPlayers[cmd->seqPlayerIndex];
|
||||
if(cmd->op & 0x80)
|
||||
{
|
||||
Audio_ProcessLoadCmd(cmd);
|
||||
|
@ -458,14 +458,14 @@ void Audio_ProcessCmd(AudioCmd* cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if(cmd->arg1 < 0x10)
|
||||
if(cmd->seqPlayerChannelIndex < 0x10)
|
||||
{
|
||||
Audio_ProcessChannelCmd(seqPlayer->channels[cmd->arg1], cmd);
|
||||
Audio_ProcessChannelCmd(seqPlayer->channels[cmd->seqPlayerChannelIndex], cmd);
|
||||
return;
|
||||
}
|
||||
if(cmd->arg1 == 0xFF)
|
||||
if(cmd->seqPlayerChannelIndex == 0xFF)
|
||||
{
|
||||
phi_v0 = gAudioContext.unk_5BDC[cmd->arg0];
|
||||
phi_v0 = gAudioContext.unk_5BDC[cmd->seqPlayerIndex];
|
||||
for(i = 0; i < 0x10; i++)
|
||||
{
|
||||
if(phi_v0 & 1)
|
||||
|
@ -654,13 +654,13 @@ void Audio_ProcessSequenceCmd(SequencePlayer* seqPlayer, AudioCmd* cmd)
|
|||
seqPlayer->transposition = cmd->asSbyte;
|
||||
return;
|
||||
case SEQ_CMD_UKN_46:
|
||||
seqPlayer->soundScriptIO[cmd->arg2] = cmd->asSbyte;
|
||||
seqPlayer->soundScriptIO[cmd->scriptIndex] = cmd->asSbyte;
|
||||
return;
|
||||
case SEQ_CMD_UKN_4A:
|
||||
fadeVolume = (s32)cmd->arg1 / 127.0f;
|
||||
fadeVolume = (s32)cmd->seqPlayerChannelIndex / 127.0f;
|
||||
goto block_11;
|
||||
case SEQ_CMD_UKN_4B:
|
||||
fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume;
|
||||
fadeVolume = ((s32)cmd->seqPlayerChannelIndex / 100.0f) * seqPlayer->fadeVolume;
|
||||
block_11:
|
||||
if(seqPlayer->state != 2)
|
||||
{
|
||||
|
@ -753,9 +753,13 @@ void Audio_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd)
|
|||
}
|
||||
return;
|
||||
case CHAN_UPD_SCRIPT_IO:
|
||||
if(cmd->arg2 < 8)
|
||||
if(cmd->seqPlayerChannelIndex==0x0b)
|
||||
{
|
||||
channel->soundScriptIO[cmd->arg2] = cmd->asSbyte;
|
||||
cmd->seqPlayerChannelIndex = 0x0b;
|
||||
}
|
||||
if(cmd->scriptIndex < 8)
|
||||
{
|
||||
channel->soundScriptIO[cmd->scriptIndex] = cmd->asSbyte;
|
||||
}
|
||||
return;
|
||||
case CHAN_UPD_STOP_SOMETHING2:
|
||||
|
|
|
@ -873,11 +873,11 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd)
|
|||
freqScale2 = temp_f14;
|
||||
break;
|
||||
default:
|
||||
freqScale = temp_f2;
|
||||
freqScale2 = temp_f2;
|
||||
break;
|
||||
}
|
||||
|
||||
freqScale = temp_f2;
|
||||
portamento->extent = (freqScale2 / freqScale) - 1.0f;
|
||||
|
||||
if(PORTAMENTO_IS_SPECIAL(*portamento))
|
||||
|
@ -1332,7 +1332,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel)
|
|||
break;
|
||||
case 0xDB:
|
||||
signedParam = (s8)parameters[0];
|
||||
channel->transposition = signedParam;
|
||||
channel->transposition = signedParam;
|
||||
break;
|
||||
case 0xDA:
|
||||
offset = (u16)parameters[0];
|
||||
|
|
|
@ -22,7 +22,7 @@ u8 SKIP_GFX_FRAME_MASK = 0;
|
|||
#endif
|
||||
|
||||
static bool g_force20FPS = false;
|
||||
static float g_force20FPSLast = 20.0f;
|
||||
static float g_force20FPSLastMaxFps = 20.0f;
|
||||
|
||||
static FramerateProfile g_profile = PROFILE_BOOT;
|
||||
|
||||
|
@ -102,14 +102,12 @@ namespace oot
|
|||
|
||||
void setMaxFramerate(float targetFramerate)
|
||||
{
|
||||
const float framerate = g_force20FPS ? 20.0f : targetFramerate;
|
||||
|
||||
if(framerate == SET_FRAMERATE)
|
||||
if(targetFramerate == SET_FRAMERATE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#ifndef STATIC_FRAMERATE
|
||||
switch((s32)framerate)
|
||||
switch((s32)targetFramerate)
|
||||
{
|
||||
case 240:
|
||||
SET_FRAMERATE = 240.0f;
|
||||
|
@ -160,6 +158,26 @@ namespace oot
|
|||
INTERPOLATE_ANIM = true;
|
||||
SKIP_GFX_FRAME_MASK = 0;
|
||||
|
||||
g_profileRates[0] = FRAMERATE_30FPS; // PROFILE_BOOT
|
||||
g_profileRates[1] = FRAMERATE_60FPS; // PROFILE_PAUSE
|
||||
g_profileRates[2] = FRAMERATE_60FPS; // PROFILE_GAMEPLAY
|
||||
g_profileRates[3] = FRAMERATE_60FPS; // PROFILE_UNKNOWN1
|
||||
g_profileRates[4] = FRAMERATE_60FPS; // PROFILE_UNKNOWN2
|
||||
g_profileRates[5] = FRAMERATE_60FPS; // PROFILE_SAMPLE
|
||||
g_profileRates[6] = FRAMERATE_60FPS; // PROFILE_OPENING
|
||||
g_profileRates[7] = FRAMERATE_60FPS; // PROFILE_SELECT
|
||||
g_profileRates[8] = FRAMERATE_60FPS; // PROFILE_TITLE
|
||||
g_profileRates[9] = FRAMERATE_60FPS; // PROFILE_FILE_CHOOSE
|
||||
break;
|
||||
case 40:
|
||||
SET_FRAMERATE = 40.0f;
|
||||
TICK_RATE = 60.0f;
|
||||
UPDATE_SCALER = 40.0f / 60.0f;
|
||||
GAME_SPEED_RATIO = 60.0f / 40.0f;
|
||||
DEKU_NUT_SPAWN_SCALER = 1.2f;
|
||||
INTERPOLATE_ANIM = true;
|
||||
SKIP_GFX_FRAME_MASK = 0;
|
||||
|
||||
g_profileRates[0] = FRAMERATE_30FPS; // PROFILE_BOOT
|
||||
g_profileRates[1] = FRAMERATE_60FPS; // PROFILE_PAUSE
|
||||
g_profileRates[2] = FRAMERATE_60FPS; // PROFILE_GAMEPLAY
|
||||
|
@ -174,11 +192,11 @@ namespace oot
|
|||
case 30:
|
||||
SET_FRAMERATE = 30.0f;
|
||||
TICK_RATE = 60.0f;
|
||||
UPDATE_SCALER = 1.0f;
|
||||
GAME_SPEED_RATIO = 1.0f;
|
||||
UPDATE_SCALER = 30.0f / 60.0f;
|
||||
GAME_SPEED_RATIO = 60.0f / 30.0f;
|
||||
DEKU_NUT_SPAWN_SCALER = 1.2f;
|
||||
INTERPOLATE_ANIM = true;
|
||||
SKIP_GFX_FRAME_MASK = 1;
|
||||
SKIP_GFX_FRAME_MASK = 0;
|
||||
|
||||
g_profileRates[0] = FRAMERATE_30FPS; // PROFILE_BOOT
|
||||
g_profileRates[1] = FRAMERATE_60FPS; // PROFILE_PAUSE
|
||||
|
@ -237,6 +255,7 @@ namespace oot
|
|||
FRAMERATE_SCALER = (20.0f * GAME_SPEED_RATIO / TICK_RATE);
|
||||
FRAMERATE_SCALER_INV = TICK_RATE / (20.0f * GAME_SPEED_RATIO);
|
||||
R_UPDATE_RATE = framerate_divider();
|
||||
osSyncPrintf("Framerate: %d\n", (s32)targetFramerate);
|
||||
|
||||
config().save();
|
||||
#endif
|
||||
|
@ -264,12 +283,25 @@ float Round(float value)
|
|||
return roundf(value * 100) / 100.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a lazy function, for anywhere you dont want the high fps to effect game mechanics. This should only be used as a temporary measure
|
||||
/// </summary>
|
||||
/// <param name="force"></param>
|
||||
void force20FPS(bool force)
|
||||
{
|
||||
if(force)
|
||||
{
|
||||
g_force20FPSLast = oot::getMaxFramerate();
|
||||
g_force20FPS = true;
|
||||
//enable force 20fps remember last fps
|
||||
g_force20FPSLastMaxFps = oot::getMaxFramerate();
|
||||
oot::setMaxFramerate(20.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!g_force20FPS)
|
||||
g_force20FPSLastMaxFps = oot::getMaxFramerate();
|
||||
g_force20FPS = false;
|
||||
//disable force 20fps and set last fps
|
||||
oot::setMaxFramerate(g_force20FPSLastMaxFps);
|
||||
}
|
||||
g_force20FPS = force;
|
||||
oot::setMaxFramerate(g_force20FPSLast);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "def/gamealloc.h"
|
||||
#include "def/gettime.h"
|
||||
#include "def/graph.h"
|
||||
#include "def/gfxprint.h"
|
||||
#include "def/idle.h"
|
||||
#include "def/logutils.h"
|
||||
#include "def/recvmesg.h"
|
||||
|
@ -406,6 +407,10 @@ void GameState_Update(GameState* gameState)
|
|||
func_800C49F4(gfxCtx);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
Debug_Draw(gfxCtx);
|
||||
#endif
|
||||
|
||||
gameState->frames++;
|
||||
}
|
||||
#include <string.h>
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "global.h"
|
||||
#include "gfx.h"
|
||||
#include "gfxprint.h"
|
||||
#include "def/z_rcp.h"
|
||||
#include "def/graph.h"
|
||||
#include "def/gfxprint.h"
|
||||
#include "def/printutils.h"
|
||||
#include "def/xprintf.h"
|
||||
|
@ -363,13 +365,6 @@ s32 GfxPrint_Printf(GfxPrint* pthis, const char* fmt, ...)
|
|||
|
||||
// Debug printf
|
||||
#ifdef DEBUG_PRINT
|
||||
|
||||
Gfx* func_8009411C(Gfx* gfx);
|
||||
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line);
|
||||
void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line);
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char gDebugLines[20][512];
|
||||
int gDebugCurrentLine = 0;
|
||||
|
||||
|
@ -405,7 +400,7 @@ void Debug_Draw(GraphicsContext* gfxCtx)
|
|||
for(int i = 0; i < gDebugCurrentLine; i++)
|
||||
{
|
||||
GfxPrint_SetColor(printer, 255, 255, 255, 255);
|
||||
GfxPrint_SetPos(printer, -5, i);
|
||||
GfxPrint_SetPos(printer, 0, i);
|
||||
|
||||
GfxPrint_Printf(printer, gDebugLines[i]);
|
||||
}
|
||||
|
|
|
@ -424,6 +424,9 @@ void Graph_ThreadEntry(void* arg0)
|
|||
|
||||
gfx_wait_ready();
|
||||
|
||||
if(!isRunning())
|
||||
break;
|
||||
|
||||
if(gNextGameState)
|
||||
{
|
||||
gCurrentGameState = std::move(gNextGameState);
|
||||
|
|
|
@ -104,7 +104,7 @@ VecPosF::VecPosF() : x(0), y(0), z(0)
|
|||
{
|
||||
}
|
||||
|
||||
VecPosF::VecPosF(const Rotation& x, const Rotation& y, const Rotation& z) : x(x), y(y), z(z)
|
||||
VecPosF::VecPosF(const CounterF& x, const CounterF& y, const CounterF& z) : x(x), y(y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -137,4 +137,64 @@ VecPosF::operator Vec3f() const
|
|||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
VecCounterF::VecCounterF() : x(0), y(0), z(0)
|
||||
{
|
||||
}
|
||||
|
||||
VecCounterF::VecCounterF(const CounterF& x, const CounterF& y, const CounterF& z) : x(x), y(y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
VecCounterF::VecCounterF(const Vec3s& vec) : x(vec.x), y(vec.y), z(vec.z)
|
||||
{
|
||||
}
|
||||
|
||||
VecCounterF::VecCounterF(const Vec3f& vec) : x(vec.x), y(vec.y), z(vec.z)
|
||||
{
|
||||
}
|
||||
|
||||
VecCounterF::VecCounterF(Vec3f* vec) : x(vec->x), y(vec->y), z(vec->z)
|
||||
{
|
||||
}
|
||||
VecCounterF::VecCounterF(const Vec3f* vec)
|
||||
{
|
||||
}
|
||||
|
||||
VecCounterF::operator Vec3s() const
|
||||
{
|
||||
Vec3s vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
VecCounterF::operator Vec3f() const
|
||||
{
|
||||
Vec3f vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
VecCounterF::operator Vec3f*()
|
||||
{
|
||||
Vec3f vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return &vec;
|
||||
}
|
||||
|
||||
VecCounterF::operator Vec3f*() const
|
||||
{
|
||||
Vec3f vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return &vec;
|
||||
}
|
|
@ -384,7 +384,7 @@ void func_8002C124(TargetContext* targetCtx, GlobalContext* globalCtx)
|
|||
{
|
||||
TargetContextEntry* entry;
|
||||
Player* player;
|
||||
s16 spCE;
|
||||
TimerS16 spCE;
|
||||
f32 temp1;
|
||||
Vec3f spBC;
|
||||
s32 spB8;
|
||||
|
@ -601,6 +601,7 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Gl
|
|||
targetCtx->unk_48 = 0;
|
||||
}
|
||||
|
||||
//switching between targets sound
|
||||
lockOnSfxId = CHECK_FLAG_ALL(actorArg->flags, ACTOR_FLAG_VISIBLE | ACTOR_FLAG_2) ? NA_SE_SY_LOCK_ON : NA_SE_SY_LOCK_ON_HUMAN;
|
||||
Common_PlaySfx(lockOnSfxId);
|
||||
}
|
||||
|
@ -1270,6 +1271,7 @@ void func_8002DF90(DynaPolyActor* dynaActor)
|
|||
dynaActor->unk_150 = 0.0f;
|
||||
}
|
||||
|
||||
//related to moving a block
|
||||
void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2)
|
||||
{
|
||||
dynaActor->unk_150 += arg1;
|
||||
|
|
|
@ -1489,7 +1489,7 @@ s16 Camera_CalcDefaultPitch(Camera* camera, s16 arg1, s16 arg2, s16 arg3)
|
|||
pad = Camera_InterpolateCurve(0.8f, 1.0f - t);
|
||||
phi_a2 = (1.0f / camera->pitchUpdateRateInv) * pad;
|
||||
}
|
||||
return Camera_LERPCeilS(sp1C, arg1, phi_a2, 0xA);
|
||||
return Camera_LERPCeilS(sp1C, arg1, phi_a2 / FRAMERATE_SCALER_INV, 0xA);
|
||||
}
|
||||
|
||||
s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 accel)
|
||||
|
@ -1500,6 +1500,7 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc
|
|||
f32 speedT;
|
||||
f32 velFactor;
|
||||
f32 yawUpdRate;
|
||||
f32 result;
|
||||
|
||||
if(camera->xzSpeed > 0.001f)
|
||||
{
|
||||
|
@ -1508,7 +1509,7 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc
|
|||
}
|
||||
else
|
||||
{
|
||||
angDelta = target - BINANG_ROT180(cur);
|
||||
angDelta = target - (BINANG_ROT180(cur));
|
||||
speedT = PCT(OREG(48));
|
||||
}
|
||||
|
||||
|
@ -1521,63 +1522,54 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc
|
|||
velocity = 0.0f;
|
||||
}
|
||||
|
||||
velFactor = Camera_InterpolateCurve(0.5f, camera->speedRatio);
|
||||
yawUpdRate = 1.0f / camera->yawUpdateRateInv;
|
||||
|
||||
velFactor = Camera_InterpolateCurve(0.5f, camera->speedRatio * FRAMERATE_SCALER_INV);
|
||||
yawUpdRate = FRAMERATE_SCALER / camera->yawUpdateRateInv;
|
||||
return cur + (s16)(angDelta * velocity * velFactor * yawUpdRate);
|
||||
}
|
||||
|
||||
#include "../port/controller/controller.h"
|
||||
#include "../port/player/players.h"
|
||||
|
||||
s16 Camera_CalcControllerPitch(Camera* camera, s16 cur, s16 target, s16 arg3)
|
||||
s16 Camera_CalcControllerPitchDiff(Camera* camera)
|
||||
{
|
||||
f32 pitchUpdRate;
|
||||
f32 pitchUpdRate = 1.0f / 24.0f;//camera->pitchUpdateRateInv;
|
||||
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
s16 rStickY = (s16)controller.state().r_stick_y * (s16)-150;
|
||||
s32 rStickY = -controller.state().r_stick_y;
|
||||
|
||||
if(rStickY != 0)
|
||||
{
|
||||
camera->startControlTimer = 250; // 10s
|
||||
camera->startControlTimer = 250; //250 = 10s
|
||||
}
|
||||
|
||||
pitchUpdRate = 1.0f / camera->pitchUpdateRateInv;
|
||||
return cur + (s16)(rStickY * pitchUpdRate * oot::config().camera().scalerY() * FRAMERATE_SCALER);
|
||||
return CLAMP((s16)(rStickY * pitchUpdRate * oot::config().camera().scalerY() * FRAMERATE_SCALER), -0x7FFF, 0x7FFF);
|
||||
}
|
||||
|
||||
s16 Camera_CalcControllerYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 accel)
|
||||
s16 Camera_CalcControllerYawDiff(Camera* camera)
|
||||
{
|
||||
if(oot::state.center_camera)
|
||||
{
|
||||
return BINANG_ROT180(target);
|
||||
}
|
||||
f32 yawUpdRate = 1.0f / 24.0f;//camera->yawUpdateRateInv;
|
||||
|
||||
f32 yawUpdRate;
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
s16 rStickX = (s16)controller.state().r_stick_x * (s16)-375;
|
||||
s32 rStickX = -controller.state().r_stick_x;
|
||||
|
||||
if(rStickX != 0)
|
||||
{
|
||||
camera->startControlTimer = 250; // 10s
|
||||
camera->startControlTimer = 250; //250 = 10s
|
||||
}
|
||||
yawUpdRate = 1.0f / camera->yawUpdateRateInv;
|
||||
return cur + (s16)(rStickX * yawUpdRate * oot::config().camera().scalerX() * FRAMERATE_SCALER);
|
||||
|
||||
return CLAMP((s16)(rStickX * yawUpdRate * oot::config().camera().scalerX() * FRAMERATE_SCALER), -0x7FFF, 0x7FFF);
|
||||
}
|
||||
|
||||
void StepControlTimer(Camera* camera)
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
if(camera->xzSpeed > 0.001f && (controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0))
|
||||
{
|
||||
camera->startControlTimer = 250; // 10s
|
||||
}
|
||||
if(camera->startControlTimer > 0)
|
||||
{
|
||||
camera->startControlTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80046E20(Camera* camera, VecSph* eyeAdjustment, f32 minDist, f32 arg3, f32* arg4, SwingAnimation* anim)
|
||||
void FollowPlayerWithCollision(Camera* camera, VecSph* eyeAdjustment, f32 minDist, f32 arg3, f32* arg4, SwingAnimation* anim)
|
||||
{
|
||||
static CamColChk atEyeColChk;
|
||||
static CamColChk eyeAtColChk;
|
||||
|
@ -1757,13 +1749,16 @@ s32 Camera_Normal1(Camera* camera)
|
|||
anim->swing.swingUpdateRateTimer = 0;
|
||||
anim->swingYawTarget = atEyeGeo.yaw;
|
||||
sUpdateCameraDirection = 0;
|
||||
anim->startSwingTimer = OREG(50) + OREG(51);
|
||||
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
if(camera->animState != 0)
|
||||
{
|
||||
camera->startControlTimer = OREG(50) + OREG(51);
|
||||
}
|
||||
anim->startSwingTimer = OREG(50) + OREG(51);
|
||||
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
camera->startControlTimer = OREG(50) + OREG(51);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1794,10 +1789,14 @@ s32 Camera_Normal1(Camera* camera)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(anim->startSwingTimer > 0)
|
||||
if(camera->xzSpeed > 0.001f)
|
||||
{
|
||||
anim->startSwingTimer = OREG(50) + OREG(51);
|
||||
}
|
||||
else if(anim->startSwingTimer > 0)
|
||||
{
|
||||
if(anim->startSwingTimer > OREG(50))
|
||||
{
|
||||
{
|
||||
anim->swingYawTarget = atEyeGeo.yaw + (BINANG_SUB(BINANG_ROT180(camera->playerPosRot.rot.y), atEyeGeo.yaw) / anim->startSwingTimer);
|
||||
}
|
||||
anim->startSwingTimer--;
|
||||
|
@ -1871,7 +1870,23 @@ s32 Camera_Normal1(Camera* camera)
|
|||
|
||||
camera->dist = eyeAdjustment.r = Camera_ClampDist(camera, eyeAdjustment.r, norm1->distMin, norm1->distMax, anim->distTimer);
|
||||
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
|
||||
if(oot::state.center_camera)
|
||||
{
|
||||
eyeAdjustment.pitch = atEyeNextGeo.pitch;
|
||||
eyeAdjustment.yaw = Camera_LERPCeilS(BINANG_ROT180(camera->playerPosRot.rot.y), atEyeNextGeo.yaw, 3.0f / camera->yawUpdateRateInv, 0xA);
|
||||
}
|
||||
else if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeAdjustment.yaw = atEyeNextGeo.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
eyeAdjustment.pitch = atEyeNextGeo.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
}
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
if(anim->startSwingTimer <= 0)
|
||||
{
|
||||
|
@ -1890,26 +1905,6 @@ s32 Camera_Normal1(Camera* camera)
|
|||
eyeAdjustment.pitch = Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeAdjustment.yaw = Camera_CalcControllerYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94);
|
||||
eyeAdjustment.pitch = Camera_CalcControllerPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj);
|
||||
}
|
||||
else if(anim->swing.unk_18 != 0)
|
||||
{
|
||||
eyeAdjustment.yaw = Camera_LERPCeilS(anim->swing.unk_16, atEyeNextGeo.yaw, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
eyeAdjustment.pitch = Camera_LERPCeilS(anim->swing.unk_14, atEyeNextGeo.pitch, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
}
|
||||
else if(anim->startSwingTimer <= 0 && camera->startControlTimer <= 0)
|
||||
{
|
||||
eyeAdjustment.yaw = Camera_CalcDefaultYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94);
|
||||
eyeAdjustment.pitch = Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj);
|
||||
}
|
||||
}
|
||||
|
||||
// set eyeAdjustment pitch from 79.65 degrees to -85 degrees
|
||||
if(eyeAdjustment.pitch > 0x38A4)
|
||||
|
@ -1925,35 +1920,36 @@ s32 Camera_Normal1(Camera* camera)
|
|||
if((camera->status == CAM_STAT_ACTIVE) && (!(norm1->interfaceFlags & 0x10)))
|
||||
{
|
||||
anim->swingYawTarget = BINANG_ROT180(camera->playerPosRot.rot.y);
|
||||
if(anim->startSwingTimer > 0)
|
||||
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
{
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
if(anim->startSwingTimer > 0)
|
||||
{
|
||||
anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f;
|
||||
FollowPlayerWithCollision(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing);
|
||||
}
|
||||
func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing);
|
||||
}
|
||||
else
|
||||
{
|
||||
sp88 = *eyeNext;
|
||||
anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f;
|
||||
if(Camera_BGCheck(camera, at, &sp88))
|
||||
else
|
||||
{
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
sp88 = *eyeNext;
|
||||
anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f;
|
||||
if(Camera_BGCheck(camera, at, &sp88))
|
||||
{
|
||||
anim->swingYawTarget = atEyeNextGeo.yaw;
|
||||
anim->startSwingTimer = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing);
|
||||
*eye = *eyeNext;
|
||||
}
|
||||
anim->swing.unk_18 = 0;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if(anim->startSwingTimer <= 0)
|
||||
{
|
||||
*eye = *eyeNext;
|
||||
anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f;
|
||||
}
|
||||
anim->swing.unk_18 = 0;
|
||||
FollowPlayerWithCollision(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing);
|
||||
}
|
||||
|
||||
if(anim->swing.unk_18 != 0)
|
||||
|
@ -2333,8 +2329,8 @@ s32 Camera_Normal3(Camera* camera)
|
|||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
sp84.yaw = Camera_CalcControllerYaw(camera, sp74.yaw, playerPosRot->rot.y, norm3->yOffset, 0.0f);
|
||||
sp84.pitch = Camera_CalcControllerPitch(camera, sp74.pitch, norm3->pitchTarget, 0);
|
||||
sp84.yaw = sp74.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
sp84.pitch = sp74.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
else if(camera->startControlTimer <= 0)
|
||||
{
|
||||
|
@ -2352,7 +2348,7 @@ s32 Camera_Normal3(Camera* camera)
|
|||
|
||||
if(camera->status == CAM_STAT_ACTIVE)
|
||||
{
|
||||
func_80046E20(camera, &sp84, norm3->distMin, norm3->yawUpdateSpeed, &sp8C, &anim->swing);
|
||||
FollowPlayerWithCollision(camera, &sp84, norm3->distMin, norm3->yawUpdateSpeed, &sp8C, &anim->swing);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2377,7 +2373,7 @@ s32 Camera_Normal0(Camera* camera)
|
|||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
// z toggle camera
|
||||
// z target camera with no target
|
||||
s32 Camera_Parallel1(Camera* camera)
|
||||
{
|
||||
Vec3f* eye = &camera->eye;
|
||||
|
@ -2399,6 +2395,8 @@ s32 Camera_Parallel1(Camera* camera)
|
|||
f32 playerHeight;
|
||||
s32 pad3;
|
||||
|
||||
camera->startControlTimer = 0;
|
||||
|
||||
playerHeight = Player_GetHeight(camera->player);
|
||||
if(RELOAD_PARAMS)
|
||||
{
|
||||
|
@ -2406,7 +2404,6 @@ s32 Camera_Parallel1(Camera* camera)
|
|||
f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight));
|
||||
|
||||
para1->unk_00 = NEXTPCT * playerHeight * yNormal;
|
||||
;
|
||||
para1->distTarget = NEXTPCT * playerHeight * yNormal;
|
||||
para1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING);
|
||||
para1->yawTarget = DEGF_TO_BINANG(NEXTSETTING);
|
||||
|
@ -2526,13 +2523,14 @@ s32 Camera_Parallel1(Camera* camera)
|
|||
}
|
||||
else
|
||||
{
|
||||
//somting to do with jumping off ledge
|
||||
func_800458D4(camera, &atToEyeNextDir, para1->unk_18, &anim->yTarget, para1->interfaceFlags & 1);
|
||||
}
|
||||
|
||||
if(anim->animTimer != 0)
|
||||
{
|
||||
camera->unk_14C |= 0x20;
|
||||
tangle = (((anim->animTimer + 1) * anim->animTimer) >> 1);
|
||||
tangle = ((s16)((anim->animTimer + 1) * anim->animTimer) >> 1);
|
||||
spA8.yaw = atToEyeDir.yaw + ((BINANG_SUB(anim->yawTarget, atToEyeDir.yaw) / tangle) * anim->animTimer);
|
||||
spA8.pitch = atToEyeDir.pitch;
|
||||
spA8.r = atToEyeDir.r;
|
||||
|
@ -2729,34 +2727,24 @@ s32 Camera_Jump1(Camera* camera)
|
|||
|
||||
eyeDiffSph.r = Camera_LERPCeilF(eyeDiffTarget.r, eyeAtOffset.r, PCT(OREG(29)), 1.0f);
|
||||
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
eyeDiffSph.pitch = Camera_LERPCeilS(eyeDiffTarget.pitch, eyeAtOffset.pitch, PCT(OREG(29)), 0xA);
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeDiffSph.yaw = eyeNextAtOffset.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
eyeDiffSph.pitch = eyeNextAtOffset.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
}
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
if(anim->swing.unk_18)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
eyeDiffSph.pitch = Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
}
|
||||
else
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, 0, 0.0f);
|
||||
eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, 0, 0);
|
||||
}
|
||||
else if(anim->swing.unk_18)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
eyeDiffSph.pitch = Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
}
|
||||
else if(camera->startControlTimer <= 0)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f);
|
||||
eyeDiffSph.pitch = Camera_LERPCeilS(eyeDiffTarget.pitch, eyeAtOffset.pitch, PCT(OREG(29)), 0xA);
|
||||
|
@ -2789,7 +2777,7 @@ s32 Camera_Jump1(Camera* camera)
|
|||
eyeNext->y += (newEye.y - eyeNext->y) * PCT(OREG(31));
|
||||
if((camera->status == CAM_STAT_ACTIVE) && !(jump1->interfaceFlags & 0x10))
|
||||
{
|
||||
func_80046E20(camera, &eyeDiffSph, jump1->distMin, jump1->yawUpateRateTarget, &spA4, &anim->swing);
|
||||
FollowPlayerWithCollision(camera, &eyeDiffSph, jump1->distMin, jump1->yawUpateRateTarget, &spA4, &anim->swing);
|
||||
if(jump1->interfaceFlags & 4)
|
||||
{
|
||||
camera->inputDir.x = -eyeAtOffset.pitch;
|
||||
|
@ -2947,7 +2935,22 @@ s32 Camera_Jump2(Camera* camera)
|
|||
bgChkPos.y = playerPosRot->pos.y + (playerHeight * 2.2f);
|
||||
bgChkPos.z = playerPosRot->pos.z + (Math_CosS(playerPosRot->rot.y) * 25.0f);
|
||||
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
adjAtToEyeDir.yaw = atToEyeNextDir.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
adjAtToEyeDir.pitch = atToEyeNextDir.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
else if(camera->startControlTimer <= 0)
|
||||
{
|
||||
adjAtToEyeDir.yaw = Camera_CalcDefaultYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f);
|
||||
adjAtToEyeDir.pitch = Camera_CalcDefaultPitch(camera, atToEyeNextDir.pitch, 0, 0);
|
||||
}
|
||||
}
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
sp90 = Camera_GetFloorYNorm(camera, &floorNorm, &bgChkPos, &bgId);
|
||||
if((sp90 != BGCHECK_Y_MIN) && (playerPosRot->pos.y < sp90))
|
||||
|
@ -2975,7 +2978,7 @@ s32 Camera_Jump2(Camera* camera)
|
|||
{
|
||||
anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y);
|
||||
anim->animTimer--;
|
||||
adjAtToEyeDir.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.5f, 0xA);
|
||||
adjAtToEyeDir.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.1f, 0xA);
|
||||
}
|
||||
else if(anim->yawAdj < ABS(yawDiff))
|
||||
{
|
||||
|
@ -2984,22 +2987,7 @@ s32 Camera_Jump2(Camera* camera)
|
|||
}
|
||||
else
|
||||
{
|
||||
adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.25f, 0xA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
adjAtToEyeDir.yaw = Camera_CalcControllerYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f);
|
||||
adjAtToEyeDir.pitch = Camera_CalcControllerPitch(camera, atToEyeNextDir.pitch, 0, 0);
|
||||
}
|
||||
else if(camera->startControlTimer <= 0)
|
||||
{
|
||||
adjAtToEyeDir.yaw = Camera_CalcDefaultYaw(camera, atToEyeNextDir.yaw, playerPosRot->rot.y, 0, 0.0f);
|
||||
adjAtToEyeDir.pitch = Camera_CalcDefaultPitch(camera, atToEyeNextDir.pitch, 0, 0);
|
||||
adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.05f, 0xA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3210,7 +3198,17 @@ s32 Camera_Jump3(Camera* camera)
|
|||
}
|
||||
}
|
||||
|
||||
if(oot::config().camera().useClassicCamera())
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeDiffSph.yaw = eyeNextAtOffset.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
eyeDiffSph.pitch = eyeNextAtOffset.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
}
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
if(anim->swing.unk_18 != 0)
|
||||
{
|
||||
|
@ -3223,26 +3221,6 @@ s32 Camera_Jump3(Camera* camera)
|
|||
eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_CalcControllerYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f);
|
||||
eyeDiffSph.pitch = Camera_CalcControllerPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0);
|
||||
}
|
||||
else if(anim->swing.unk_18 != 0)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
eyeDiffSph.pitch = Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA);
|
||||
}
|
||||
else if(camera->startControlTimer <= 0)
|
||||
{
|
||||
eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f);
|
||||
eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(eyeDiffSph.pitch > R_CAM_MAX_PHI)
|
||||
{
|
||||
|
@ -3257,7 +3235,7 @@ s32 Camera_Jump3(Camera* camera)
|
|||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeDiffSph);
|
||||
if((camera->status == CAM_STAT_ACTIVE) && !(jump3->interfaceFlags & 0x10))
|
||||
{
|
||||
func_80046E20(camera, &eyeDiffSph, jump3->distMin, jump3->swingUpdateRate, &spBC, &anim->swing);
|
||||
FollowPlayerWithCollision(camera, &eyeDiffSph, jump3->distMin, jump3->swingUpdateRate, &spBC, &anim->swing);
|
||||
if(jump3->interfaceFlags & 4)
|
||||
{
|
||||
camera->inputDir.x = -eyeAtOffset.pitch;
|
||||
|
@ -3290,11 +3268,13 @@ s32 Camera_Jump3(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Jump4(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Jump0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -3584,11 +3564,13 @@ s32 Camera_Battle1(Camera* camera)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Battle2(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Battle3(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -3611,6 +3593,7 @@ s32 Camera_BattleChargeSpinAttack(Camera* camera)
|
|||
Battle4Anim* anim = &batt4->anim;
|
||||
s32 pad;
|
||||
f32 playerHeight;
|
||||
PosRot* playerPosRot = &camera->playerPosRot;
|
||||
|
||||
playerHeight = Player_GetHeight(camera->player);
|
||||
if(RELOAD_PARAMS)
|
||||
|
@ -3653,18 +3636,34 @@ s32 Camera_BattleChargeSpinAttack(Camera* camera)
|
|||
camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, PCT(OREG(26)) * camera->speedRatio, 0.1f);
|
||||
camera->fovUpdateRate = 0.0001f;
|
||||
Camera_CalcAtDefault(camera, &eyeNextAtOffset, batt4->yOffset, 1);
|
||||
if(anim->animTimer != 0)
|
||||
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtOffset.yaw;
|
||||
eyeNextOffset.pitch = eyeAtOffset.pitch;
|
||||
eyeNextOffset.r = eyeAtOffset.r;
|
||||
anim->animTimer--;
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtOffset.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
eyeNextOffset.pitch = eyeAtOffset.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
eyeNextOffset.r = eyeAtOffset.r;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtOffset.yaw;
|
||||
eyeNextOffset.pitch = Camera_LERPCeilS(batt4->pitchTarget, eyeAtOffset.pitch, batt4->lerpUpdateRate, 2);
|
||||
eyeNextOffset.r = Camera_LERPCeilF(batt4->rTarget, eyeAtOffset.r, batt4->lerpUpdateRate, 0.001f);
|
||||
if(anim->animTimer != 0)
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtOffset.yaw;
|
||||
eyeNextOffset.pitch = eyeAtOffset.pitch;
|
||||
eyeNextOffset.r = eyeAtOffset.r;
|
||||
anim->animTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtOffset.yaw;
|
||||
eyeNextOffset.pitch = Camera_LERPCeilS(batt4->pitchTarget, eyeAtOffset.pitch, batt4->lerpUpdateRate, 2);
|
||||
eyeNextOffset.r = Camera_LERPCeilF(batt4->rTarget, eyeAtOffset.r, batt4->lerpUpdateRate, 0.001f);
|
||||
}
|
||||
}
|
||||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeNextOffset);
|
||||
*eye = *eyeNext;
|
||||
|
@ -3675,12 +3674,13 @@ s32 Camera_BattleChargeSpinAttack(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Battle0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
// Targeting non-enemy
|
||||
//z targeting non-enemy
|
||||
s32 Camera_KeepOn1(Camera* camera)
|
||||
{
|
||||
Vec3f* eye = &camera->eye;
|
||||
|
@ -3762,7 +3762,7 @@ s32 Camera_KeepOn1(Camera* camera)
|
|||
camera->animState++;
|
||||
anim->unk_10 = 0;
|
||||
anim->unk_04 = 0.0f;
|
||||
anim->unk_0C = camera->target;
|
||||
anim->currentTarget = camera->target;
|
||||
anim->unk_16 = R_DEFA_CAM_ANIM_TIME + OREG(24);
|
||||
anim->unk_12 = spC0.yaw;
|
||||
anim->unk_14 = spC0.pitch;
|
||||
|
@ -3797,9 +3797,9 @@ s32 Camera_KeepOn1(Camera* camera)
|
|||
Actor_GetFocus(&camera->targetPosRot, camera->target);
|
||||
}
|
||||
Actor_GetFocus(&camera->targetPosRot, camera->target);
|
||||
if(anim->unk_0C != camera->target)
|
||||
if(anim->currentTarget != camera->target)
|
||||
{
|
||||
anim->unk_0C = camera->target;
|
||||
anim->currentTarget = camera->target;
|
||||
camera->atLERPStepScale = 0.0f;
|
||||
}
|
||||
camera->xzOffsetUpdateRate = Camera_LERPCeilF(1.0f, camera->xzOffsetUpdateRate, PCT(OREG(25)) * camera->speedRatio, 0.1f);
|
||||
|
@ -3807,7 +3807,7 @@ s32 Camera_KeepOn1(Camera* camera)
|
|||
camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->fovUpdateRate, camera->speedRatio * 0.05f, 0.1f);
|
||||
goto cont;
|
||||
case 0x10:
|
||||
anim->unk_0C = NULL;
|
||||
anim->currentTarget = NULL;
|
||||
cont:
|
||||
if(camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || camera->player->stateFlags1 & PLAYER_STATE1_21)
|
||||
{
|
||||
|
@ -3828,7 +3828,7 @@ s32 Camera_KeepOn1(Camera* camera)
|
|||
default:
|
||||
*at = playerPosRot->pos;
|
||||
at->y += playerHeight;
|
||||
anim->unk_0C = NULL;
|
||||
anim->currentTarget = NULL;
|
||||
break;
|
||||
}
|
||||
OLib_Vec3fDiffToVecSphGeo(&spD8, at, eyeNext);
|
||||
|
@ -4913,16 +4913,19 @@ s32 Camera_Fixed4(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Fixed0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Subj1(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Subj2(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -5208,27 +5211,32 @@ s32 Camera_Subj4(Camera* camera)
|
|||
return 1;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Subj0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Data0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//normal1 data?
|
||||
s32 Camera_Data1(Camera* camera)
|
||||
{
|
||||
osSyncPrintf("chau!chau!\n");
|
||||
return Camera_Normal1(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Data2(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Data3(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -5311,7 +5319,7 @@ s32 Camera_Data4(Camera* camera)
|
|||
}
|
||||
|
||||
/**
|
||||
* Hanging off of a ledge
|
||||
* Hanging off of a ledge/climbing ledge
|
||||
*/
|
||||
s32 Camera_Unique1(Camera* camera)
|
||||
{
|
||||
|
@ -5319,11 +5327,10 @@ s32 Camera_Unique1(Camera* camera)
|
|||
Vec3f* at = &camera->at;
|
||||
Vec3f* eyeNext = &camera->eyeNext;
|
||||
Vec3f playerBodyPart0;
|
||||
s16 phiTarget;
|
||||
VecSph sp8C;
|
||||
VecSph unk908PlayerPosOffset;
|
||||
VecSph eyeNextOffset;
|
||||
VecSph PlayerPosOffset;
|
||||
VecSph eyeAtOffset;
|
||||
VecSph eyeNextAtOffset;
|
||||
VecSph eyeAtNextOffset;
|
||||
PosRot* playerPosRot = &camera->playerPosRot;
|
||||
PosRot playerhead;
|
||||
Unique1* uniq1 = (Unique1*)camera->paramData;
|
||||
|
@ -5354,19 +5361,19 @@ s32 Camera_Unique1(Camera* camera)
|
|||
sUpdateCameraDirection = 1;
|
||||
|
||||
OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye);
|
||||
OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext);
|
||||
OLib_Vec3fDiffToVecSphGeo(&eyeAtNextOffset, at, eyeNext);
|
||||
|
||||
sCameraInterfaceFlags = uniq1->interfaceFlags;
|
||||
|
||||
if(camera->animState == 0)
|
||||
{
|
||||
camera->posOffset.y = camera->posOffset.y - camera->playerPosDelta.y;
|
||||
anim->yawTarget = eyeNextAtOffset.yaw;
|
||||
anim->yawTarget = eyeAtNextOffset.yaw;
|
||||
anim->unk_00 = 0.0f;
|
||||
playerBodyPart0 = camera->player->bodyPartsPos[0];
|
||||
OLib_Vec3fDiffToVecSphGeo(&unk908PlayerPosOffset, &playerPosRot->pos, &playerBodyPart0);
|
||||
OLib_Vec3fDiffToVecSphGeo(&PlayerPosOffset, &playerPosRot->pos, &playerBodyPart0);
|
||||
anim->timer = R_DEFA_CAM_ANIM_TIME;
|
||||
anim->yawTargetAdj = ABS(BINANG_SUB(unk908PlayerPosOffset.yaw, eyeAtOffset.yaw)) < 0x3A98 ? 0 : ((BINANG_SUB(unk908PlayerPosOffset.yaw, eyeAtOffset.yaw) / anim->timer) / 4) * 3;
|
||||
anim->yawTargetAdj = ABS(BINANG_SUB(PlayerPosOffset.yaw, eyeAtOffset.yaw)) < 0x3A98 ? 0 : ((BINANG_SUB(PlayerPosOffset.yaw, eyeAtOffset.yaw) / anim->timer) / 4) * 3;
|
||||
camera->animState++;
|
||||
}
|
||||
|
||||
|
@ -5378,31 +5385,52 @@ s32 Camera_Unique1(Camera* camera)
|
|||
camera->yOffsetUpdateRate = Camera_LERPCeilF(0.01f, camera->yOffsetUpdateRate, OREG(26) * 0.01f, 0.01f);
|
||||
camera->fovUpdateRate = Camera_LERPCeilF(OREG(4) * 0.01f, camera->fovUpdateRate, 0.05f, 0.1f);
|
||||
|
||||
Camera_CalcAtDefault(camera, &eyeNextAtOffset, uniq1->yOffset, 1);
|
||||
OLib_Vec3fDiffToVecSphGeo(&sp8C, at, eyeNext);
|
||||
|
||||
camera->dist = Camera_LERPClampDist(camera, sp8C.r, uniq1->distMin, uniq1->distMax);
|
||||
|
||||
phiTarget = uniq1->pitchTarget;
|
||||
sp8C.pitch = Camera_LERPCeilS(phiTarget, eyeNextAtOffset.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA);
|
||||
|
||||
if(sp8C.pitch > R_CAM_MAX_PHI)
|
||||
Camera_CalcAtDefault(camera, &eyeAtNextOffset, uniq1->yOffset, 1);
|
||||
OLib_Vec3fDiffToVecSphGeo(&eyeNextOffset, at, eye);
|
||||
|
||||
if(!oot::config().camera().useClassicCamera())
|
||||
{
|
||||
sp8C.pitch = R_CAM_MAX_PHI;
|
||||
}
|
||||
if(sp8C.pitch < -R_CAM_MAX_PHI)
|
||||
{
|
||||
sp8C.pitch = -R_CAM_MAX_PHI;
|
||||
}
|
||||
eyeNextOffset.r = Camera_LERPCeilF(184.0f, eyeAtNextOffset.r, camera->xzOffsetUpdateRate, 0xA);
|
||||
|
||||
if(anim->timer != 0)
|
||||
{
|
||||
anim->yawTarget += anim->yawTargetAdj;
|
||||
anim->timer--;
|
||||
const oot::hid::Controller& controller = oot::player(0).controller();
|
||||
StepControlTimer(camera);
|
||||
if(camera->startControlTimer > 0 || controller.state().r_stick_x != 0 || controller.state().r_stick_y != 0)
|
||||
{
|
||||
eyeNextOffset.yaw = eyeAtNextOffset.yaw + Camera_CalcControllerYawDiff(camera);
|
||||
eyeNextOffset.pitch = eyeAtNextOffset.pitch + Camera_CalcControllerPitchDiff(camera);
|
||||
}
|
||||
if(eyeNextOffset.pitch > 0x2AF8)
|
||||
{
|
||||
eyeNextOffset.pitch = 0x2AF8;
|
||||
}
|
||||
if(eyeNextOffset.pitch < -0x2AF8)
|
||||
{
|
||||
eyeNextOffset.pitch = -0x2AF8;
|
||||
}
|
||||
}
|
||||
if(oot::config().camera().useClassicCamera() || camera->startControlTimer <= 0)
|
||||
{
|
||||
camera->dist = Camera_LERPClampDist(camera, eyeNextOffset.r, uniq1->distMin, uniq1->distMax);
|
||||
eyeNextOffset.pitch = Camera_LERPCeilS(uniq1->pitchTarget, eyeAtNextOffset.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA);
|
||||
|
||||
sp8C.yaw = Camera_LERPFloorS(anim->yawTarget, eyeNextAtOffset.yaw, 0.5f, 0x2710);
|
||||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp8C);
|
||||
if(eyeNextOffset.pitch > R_CAM_MAX_PHI)
|
||||
{
|
||||
eyeNextOffset.pitch = R_CAM_MAX_PHI;
|
||||
}
|
||||
if(eyeNextOffset.pitch < -R_CAM_MAX_PHI)
|
||||
{
|
||||
eyeNextOffset.pitch = -R_CAM_MAX_PHI;
|
||||
}
|
||||
|
||||
if(anim->timer != 0)
|
||||
{
|
||||
anim->yawTarget += anim->yawTargetAdj;
|
||||
anim->timer--;
|
||||
}
|
||||
eyeNextOffset.yaw = Camera_LERPFloorS(anim->yawTarget, eyeAtNextOffset.yaw, 0.1f, 0xA);
|
||||
}
|
||||
|
||||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeNextOffset);
|
||||
*eye = *eyeNext;
|
||||
Camera_BGCheck(camera, at, eye);
|
||||
camera->fov = Camera_LERPCeilF(uniq1->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f);
|
||||
|
@ -5885,6 +5913,7 @@ s32 Camera_Unique7(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Unique8(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -6589,6 +6618,7 @@ s32 Camera_Demo1(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Demo2(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -6680,7 +6710,9 @@ s32 Camera_Demo3(Camera* camera)
|
|||
eyeOffset.r = D_8011D658[0].r;
|
||||
eyeOffset.pitch = D_8011D658[0].pitch;
|
||||
eyeOffset.yaw = (D_8011D658[0].yaw * anim->yawDir) + camPlayerPosRot->rot.y;
|
||||
anim->unk_0C = 1.0f;
|
||||
anim->stepScale = 1.0f;
|
||||
|
||||
camera->animState = 0xA;
|
||||
break;
|
||||
case 1:
|
||||
temp_f0 = (anim->animFrame - 2) * (1.0f / 146.0f);
|
||||
|
@ -6701,7 +6733,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
eyeOffset.pitch = atOffset.pitch;
|
||||
eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y;
|
||||
|
||||
anim->unk_0C -= (1.0f / 365.0f);
|
||||
anim->stepScale -= (1.0f / 365.0f);
|
||||
break;
|
||||
case 2:
|
||||
temp_f0 = (anim->animFrame - 0x94) * 0.1f;
|
||||
|
@ -6722,7 +6754,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
eyeOffset.r = atOffset.r;
|
||||
eyeOffset.pitch = atOffset.pitch;
|
||||
eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y;
|
||||
anim->unk_0C -= 0.04f;
|
||||
anim->stepScale -= 0.04f;
|
||||
break;
|
||||
case 3:
|
||||
temp_f0 = (anim->animFrame - 0x9F) * (1.0f / 9.0f);
|
||||
|
@ -6743,7 +6775,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
eyeOffset.r = atOffset.r;
|
||||
eyeOffset.pitch = atOffset.pitch;
|
||||
eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y;
|
||||
anim->unk_0C += (4.0f / 45.0f);
|
||||
anim->stepScale += (4.0f / 45.0f);
|
||||
break;
|
||||
case 30:
|
||||
camera->unk_14C |= 0x400;
|
||||
|
@ -6759,7 +6791,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
eyeOffset.r = 80.0f;
|
||||
eyeOffset.pitch = 0;
|
||||
eyeOffset.yaw = eyeAtOffset.yaw;
|
||||
anim->unk_0C = 0.1f;
|
||||
anim->stepScale = 0.1f;
|
||||
sCameraInterfaceFlags = 0x3400;
|
||||
|
||||
if(!((anim->animFrame < 0 || camera->xzSpeed > 0.001f || CHECK_BTN_ALL(globalCtxAlt->input[0].press.button, BTN_A) || CHECK_BTN_ALL(globalCtxAlt->input[0].press.button, BTN_B) ||
|
||||
|
@ -6790,11 +6822,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
|
||||
anim->animFrame++;
|
||||
|
||||
if(anim->animFrame == 1)
|
||||
{
|
||||
camera->animState = 0xA;
|
||||
}
|
||||
else if(anim->animFrame == 2)
|
||||
if(anim->animFrame == 2)
|
||||
{
|
||||
camera->animState = 0x1;
|
||||
}
|
||||
|
@ -6821,9 +6849,9 @@ s32 Camera_Demo3(Camera* camera)
|
|||
|
||||
if(!skipUpdateEye)
|
||||
{
|
||||
eyeOffset.r = Camera_LERPCeilF(eyeOffset.r, eyeAtOffset.r, anim->unk_0C, 2.0f);
|
||||
eyeOffset.pitch = Camera_LERPCeilS(eyeOffset.pitch, eyeAtOffset.pitch, anim->unk_0C, 0xA);
|
||||
eyeOffset.yaw = Camera_LERPCeilS(eyeOffset.yaw, eyeAtOffset.yaw, anim->unk_0C, 0xA);
|
||||
eyeOffset.r = Camera_LERPCeilF(eyeOffset.r, eyeAtOffset.r, anim->stepScale, 2.0f);
|
||||
eyeOffset.pitch = Camera_LERPCeilS(eyeOffset.pitch, eyeAtOffset.pitch, anim->stepScale, 0xA);
|
||||
eyeOffset.yaw = Camera_LERPCeilS(eyeOffset.yaw, eyeAtOffset.yaw, anim->stepScale, 0xA);
|
||||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeOffset);
|
||||
*eye = *eyeNext;
|
||||
}
|
||||
|
@ -6836,6 +6864,7 @@ s32 Camera_Demo3(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Demo4(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -7241,6 +7270,7 @@ s32 Camera_Demo7(Camera* camera)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Demo8(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -7412,6 +7442,7 @@ s32 Camera_Demo9(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Demo0(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -7467,16 +7498,19 @@ s32 Camera_Special0(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Special1(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Special2(Camera* camera)
|
||||
{
|
||||
return Camera_Unique2(camera);
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Special3(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
|
@ -7798,11 +7832,13 @@ s32 Camera_Special6(Camera* camera)
|
|||
return true;
|
||||
}
|
||||
|
||||
//noop
|
||||
s32 Camera_Special8(Camera* camera)
|
||||
{
|
||||
return Camera_Noop(camera);
|
||||
}
|
||||
|
||||
//walking through a door camera
|
||||
s32 Camera_Special9(Camera* camera)
|
||||
{
|
||||
s32 pad;
|
||||
|
@ -7917,9 +7953,9 @@ s32 Camera_Special9(Camera* camera)
|
|||
spAC = playerPosRot->pos;
|
||||
spAC.y += (playerYOffset + params->yOffset);
|
||||
Camera_LERPCeilVec3f(&spAC, at, 0.5f, 0.5f, 0.1f);
|
||||
eyeAdjustment.pitch = Camera_LERPCeilS(0xAAA, atEyeOffsetGeo.pitch, 0.3f, 0xA);
|
||||
eyeAdjustment.yaw = Camera_LERPCeilS(anim->targetYaw, atEyeOffsetGeo.yaw, 0.3f, 0xA);
|
||||
eyeAdjustment.r = Camera_LERPCeilF(60.0f, atEyeOffsetGeo.r, 0.3f, 1.0f);
|
||||
eyeAdjustment.pitch = Camera_LERPCeilS(0xAAA, atEyeOffsetGeo.pitch, 0.3f / FRAMERATE_SCALER_INV, 0xA);
|
||||
eyeAdjustment.yaw = Camera_LERPCeilS(anim->targetYaw, atEyeOffsetGeo.yaw, 0.3f / FRAMERATE_SCALER_INV, 0xA);
|
||||
eyeAdjustment.r = Camera_LERPCeilF(60.0f, atEyeOffsetGeo.r, 0.3f / FRAMERATE_SCALER_INV, 1.0f);
|
||||
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment);
|
||||
*eye = *eyeNext;
|
||||
spec9->doorParams.timer3--;
|
||||
|
|
|
@ -179,9 +179,8 @@ void Effect_Add(GlobalContext* globalCtx, s32* pIndex, s32 type, u8 arg3, u8 arg
|
|||
|
||||
if(!slotFound)
|
||||
{
|
||||
// "EffectAdd(): I cannot secure it. Be careful. Type %d"
|
||||
osSyncPrintf("EffectAdd():確保できません。注意してください。Type%d\n", type);
|
||||
osSyncPrintf("エフェクト追加せずに終了します。\n"); // "Exit without adding the effect."
|
||||
osSyncPrintf("EffectAdd():Cannot be secured. Be careful. Type%d\n", type);
|
||||
osSyncPrintf("Exit without adding effects.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -295,7 +294,7 @@ void Effect_DeleteAll(GlobalContext* globalCtx)
|
|||
{
|
||||
s32 i;
|
||||
|
||||
osSyncPrintf("エフェクト総て解放\n"); // "All effect release"
|
||||
osSyncPrintf("Release all effects Begin\n");
|
||||
|
||||
for(i = 0; i < SPARK_COUNT; i++)
|
||||
{
|
||||
|
@ -315,5 +314,5 @@ void Effect_DeleteAll(GlobalContext* globalCtx)
|
|||
sEffectInfoTable[EFFECT_SHIELD_PARTICLE].destroy(&sEffectContext.shieldParticles[i].effect);
|
||||
}
|
||||
|
||||
osSyncPrintf("エフェクト総て解放 終了\n"); // "All effects release End"
|
||||
osSyncPrintf("Release all effects End\n");
|
||||
}
|
||||
|
|
|
@ -211,21 +211,20 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
|
||||
overlayEntry = &gEffectSsOverlayTable[type];
|
||||
|
||||
ASSERT(type < EFFECT_SS_TYPE_MAX, "type < EFFECT_SS2_TYPE_LAST_LABEL", "../z_effect_soft_sprite.c", 556);
|
||||
|
||||
if(EffectSs_FindSlot(priority, &index) != 0)
|
||||
{
|
||||
// Abort because we couldn't find a suitable slot to add this effect in
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(type < EFFECT_SS_TYPE_MAX, "type < EFFECT_SS2_TYPE_LAST_LABEL", "../z_effect_soft_sprite.c", 556);
|
||||
|
||||
sEffectSsInfo.searchStartIndex = index + 1;
|
||||
overlaySize = POINTER_SUB(overlayEntry->vramEnd, overlayEntry->vramStart);
|
||||
|
||||
if(overlayEntry->vramStart == NULL)
|
||||
{
|
||||
// "Not an overlay"
|
||||
osSyncPrintf("EffectSoftSprite2_makeEffect():オーバーレイではありません。\n");
|
||||
osSyncPrintf("EffectSoftSprite2_makeEffect(): Not an overlay\n");
|
||||
initInfo = overlayEntry->initInfo;
|
||||
}
|
||||
else
|
||||
|
@ -237,13 +236,10 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
if(overlayEntry->loadedRamAddr == NULL)
|
||||
{
|
||||
osSyncPrintf(VT_FGCOL(RED));
|
||||
// "The memory of %d byte cannot be secured. Therefore, the program cannot be loaded.
|
||||
// What a dangerous situation! Naturally, effects will not produced either."
|
||||
osSyncPrintf(
|
||||
"EffectSoftSprite2_makeEffect():zelda_malloc_r()により,%"
|
||||
"dbyteのメモリ確保ができま\nせん。そのため、プログラムのロードも\n出来ません。ただいま危険"
|
||||
"な状態です!\nもちろん,エフェクトも出ません。\n",
|
||||
overlaySize);
|
||||
"EffectSoftSprite2_makeEffect():zelda_malloc_r() The memory of %d byte cannot be secured. Therefore, the program cannot be loaded.\
|
||||
What a dangerous situation! Naturally, effects will not produced either.\n",
|
||||
overlaySize);
|
||||
osSyncPrintf(VT_RST);
|
||||
return;
|
||||
}
|
||||
|
@ -258,12 +254,10 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
|
||||
if(initInfo->init == NULL)
|
||||
{
|
||||
// "Effects have already been loaded, but the constructor is NULL so the addition will not occur.
|
||||
// Please fix this. (Waste of memory) %08x %d"
|
||||
osSyncPrintf(
|
||||
"EffectSoftSprite2_makeEffect():すでにエフェクトはロード済みで\nすが,"
|
||||
"コンストラクターがNULLなので追加をやめます。\n直してください。(メモリーの無駄) %08x %d\n",
|
||||
initInfo, type);
|
||||
"EffectSoftSprite2_makeEffect():Effects have already been loaded, but the constructor is NULL so the addition will not occur.\n"
|
||||
"Please fix this. (Waste of memory) %08x %d",
|
||||
initInfo, type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -276,11 +270,9 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
if(initInfo->init(globalCtx, index, &sEffectSsInfo.table[index], initParams) == 0)
|
||||
{
|
||||
osSyncPrintf(VT_FGCOL(GREEN));
|
||||
// "Construction failed for some reason. The constructor returned an error.
|
||||
// Ceasing effect addition."
|
||||
osSyncPrintf("EffectSoftSprite2_makeEffect():"
|
||||
"何らかの理由でコンストラクト失敗。コンストラクターがエラーを返しました。エフェクトの追加を中"
|
||||
"止します。\n");
|
||||
osSyncPrintf("EffectSoftSprite2_makeEffect():\
|
||||
Construction failed for some reason. The constructor returned an error.\
|
||||
Ceasing effect addition.\n");
|
||||
osSyncPrintf(VT_RST);
|
||||
EffectSs_Reset(&sEffectSsInfo.table[index]);
|
||||
}
|
||||
|
@ -289,7 +281,7 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init
|
|||
void EffectSs_Update(GlobalContext* globalCtx, s32 index)
|
||||
{
|
||||
EffectSs* effectSs = &sEffectSsInfo.table[index];
|
||||
|
||||
|
||||
if(effectSs->update != NULL)
|
||||
{
|
||||
effectSs->velocity.x += effectSs->accel.x;
|
||||
|
@ -322,7 +314,7 @@ void EffectSs_UpdateAll(GlobalContext* globalCtx)
|
|||
|
||||
if(sEffectSsInfo.table[i].life > -1)
|
||||
{
|
||||
EffectSs_Update(globalCtx, i);
|
||||
EffectSs_Update(globalCtx, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +334,7 @@ void EffectSs_Draw(GlobalContext* globalCtx, s32 index)
|
|||
void EffectSs_DrawAll(GlobalContext* globalCtx)
|
||||
{
|
||||
Lights* lights = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->gfxCtx);
|
||||
s32 i;
|
||||
s32 i;
|
||||
|
||||
Lights_BindAll(lights, globalCtx->lightCtx.listHead, NULL);
|
||||
Lights_Draw(lights, globalCtx->gfxCtx);
|
||||
|
@ -355,17 +347,13 @@ void EffectSs_DrawAll(GlobalContext* globalCtx)
|
|||
(sEffectSsInfo.table[i].pos.z < -32000.0f))
|
||||
{
|
||||
osSyncPrintf(VT_FGCOL(RED));
|
||||
// "Since the position is outside the area, delete it.
|
||||
// Effect label No. %d: Please respond by the program.
|
||||
// Here is ==> pos (%f, %f, %f) and the label is in z_effect_soft_sprite_dlftbls.decl."
|
||||
osSyncPrintf(
|
||||
"EffectSoftSprite2_disp():位置が領域外のため "
|
||||
"削除します。エフェクトラベルNo.%d:プログラムの方で対応をお願いします。ここです ==> "
|
||||
"pos(%f, %f, %f)で、ラベルはz_effect_soft_sprite_dlftbls.declにあります。\n",
|
||||
"EffectSoftSprite2_disp():Since the position is outside the area, delete it.\
|
||||
Effect label No. %d: Please respond by the program.\
|
||||
Here is ==> pos (%f, %f, %f) and the label is in z_effect_soft_sprite_dlftbls.decl.\n",
|
||||
sEffectSsInfo.table[i].type, sEffectSsInfo.table[i].pos.x, sEffectSsInfo.table[i].pos.y, sEffectSsInfo.table[i].pos.z);
|
||||
osSyncPrintf(VT_FGCOL(GREEN));
|
||||
// "If you are using pos for something else, consult me."
|
||||
osSyncPrintf("もし、posを別のことに使っている場合相談に応じます。\n");
|
||||
osSyncPrintf("If you are using pos for something else, consult me.\n");
|
||||
osSyncPrintf(VT_RST);
|
||||
|
||||
EffectSs_Delete(&sEffectSsInfo.table[i]);
|
||||
|
|
|
@ -255,7 +255,7 @@ f32 gLensFlareColorIntensity;
|
|||
s16 gLensFlareScreenFillAlpha;
|
||||
LightningBolt sLightningBolts[3];
|
||||
LightningStrike gLightningStrike;
|
||||
s16 sLightningFlashAlpha;
|
||||
TimerS16 sLightningFlashAlpha;
|
||||
s16 gSunScreenPosX;
|
||||
s16 gSunScreenPosY;
|
||||
LightNode* sNGameOverLightNode;
|
||||
|
@ -263,7 +263,7 @@ LightInfo sNGameOverLightInfo;
|
|||
LightNode* sSGameOverLightNode;
|
||||
LightInfo sSGameOverLightInfo;
|
||||
u8 sGameOverLightsIntensity;
|
||||
u16 D_8015FDB0;
|
||||
TimerU16 ScrollingMulitplier;
|
||||
|
||||
s32 func_8006F0A0(s32 a0)
|
||||
{
|
||||
|
@ -328,9 +328,9 @@ void Environment_Init(GlobalContext* globalCtx2, EnvironmentContext* envCtx, s32
|
|||
envCtx->unk_D8 = 1.0f;
|
||||
envCtx->unk_DC = 0;
|
||||
envCtx->gloomySkyMode = 0;
|
||||
envCtx->unk_DE = 0;
|
||||
envCtx->skyState = 0;
|
||||
envCtx->lightningMode = LIGHTNING_MODE_OFF;
|
||||
envCtx->unk_E0 = 0;
|
||||
envCtx->dayState = 0;
|
||||
envCtx->fillScreen = false;
|
||||
envCtx->screenFillColor[0] = 0;
|
||||
envCtx->screenFillColor[1] = 0;
|
||||
|
@ -613,7 +613,7 @@ f32 Environment_LerpWeightAccelDecel(u16 endFrame, u16 startFrame, u16 curFrame,
|
|||
f32 totalFrames;
|
||||
f32 temp;
|
||||
f32 framesElapsed;
|
||||
f32 ret;
|
||||
TimerF32 ret;
|
||||
|
||||
if(curFrame <= startFrame)
|
||||
{
|
||||
|
@ -681,7 +681,7 @@ void func_8006FB94(EnvironmentContext* envCtx, u8 unused)
|
|||
{
|
||||
if(envCtx->gloomySkyMode != 0)
|
||||
{
|
||||
switch(envCtx->unk_DE)
|
||||
switch(envCtx->skyState)
|
||||
{
|
||||
case 0:
|
||||
if((envCtx->gloomySkyMode == 1) && !gSkyboxBlendingEnabled)
|
||||
|
@ -695,7 +695,7 @@ void func_8006FB94(EnvironmentContext* envCtx, u8 unused)
|
|||
envCtx->unk_20 = 2;
|
||||
D_8011FB34 = 2;
|
||||
envCtx->unk_22 = envCtx->unk_24 = 100;
|
||||
envCtx->unk_DE++;
|
||||
envCtx->skyState++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
|
@ -713,7 +713,7 @@ void func_8006FB94(EnvironmentContext* envCtx, u8 unused)
|
|||
envCtx->unk_22 = envCtx->unk_24 = 100;
|
||||
envCtx->unk_EE[0] = 0;
|
||||
envCtx->gloomySkyMode = 0;
|
||||
envCtx->unk_DE = 0;
|
||||
envCtx->skyState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2137,7 +2137,7 @@ void Environment_DrawLightning(GlobalContext* globalCtx, s32 unused)
|
|||
|
||||
void func_800758AC(GlobalContext* globalCtx)
|
||||
{
|
||||
globalCtx->envCtx.unk_E0 = 0xFF;
|
||||
globalCtx->envCtx.dayState = 0xFF;
|
||||
|
||||
// both lost woods exits on the bridge from kokiri to hyrule field
|
||||
if(((void)0, gSaveContext.entranceIndex) == 0x4DE || ((void)0, gSaveContext.entranceIndex) == 0x5E0)
|
||||
|
@ -2179,7 +2179,7 @@ void func_800758AC(GlobalContext* globalCtx)
|
|||
Audio_PlaySequence(globalCtx->sequenceCtx.seqId);
|
||||
}
|
||||
|
||||
globalCtx->envCtx.unk_E0 = 1;
|
||||
globalCtx->envCtx.dayState = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2190,15 +2190,15 @@ void func_800758AC(GlobalContext* globalCtx)
|
|||
|
||||
if(((void)0, gSaveContext.dayTime) > 0xB71C && ((void)0, gSaveContext.dayTime) < 0xCAAC)
|
||||
{
|
||||
globalCtx->envCtx.unk_E0 = 3;
|
||||
globalCtx->envCtx.dayState = 3;
|
||||
}
|
||||
else if(((void)0, gSaveContext.dayTime) > 0xCAAC || ((void)0, gSaveContext.dayTime) < 0x4555)
|
||||
{
|
||||
globalCtx->envCtx.unk_E0 = 5;
|
||||
globalCtx->envCtx.dayState = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
globalCtx->envCtx.unk_E0 = 7;
|
||||
globalCtx->envCtx.dayState = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2206,7 +2206,7 @@ void func_800758AC(GlobalContext* globalCtx)
|
|||
osSyncPrintf("\n Forced BGM=[%d]", ((void)0, gSaveContext.forcedSeqId)); // "Forced BGM"
|
||||
osSyncPrintf("\n BGM=[%d]", globalCtx->sequenceCtx.seqId);
|
||||
osSyncPrintf("\n Ambience=[%d]", globalCtx->sequenceCtx.natureAmbienceId);
|
||||
osSyncPrintf("\n status=[%d]", globalCtx->envCtx.unk_E0);
|
||||
osSyncPrintf("\n status=[%d]", globalCtx->envCtx.dayState);
|
||||
|
||||
Audio_SetEnvReverb(globalCtx->roomCtx.curRoom.echo);
|
||||
}
|
||||
|
@ -2214,7 +2214,7 @@ void func_800758AC(GlobalContext* globalCtx)
|
|||
// updates bgm/sfx and other things as the day progresses
|
||||
void func_80075B44(GlobalContext* globalCtx)
|
||||
{
|
||||
switch(globalCtx->envCtx.unk_E0)
|
||||
switch(globalCtx->envCtx.dayState)
|
||||
{
|
||||
case 0:
|
||||
func_800F6D58(86, 1, 0);
|
||||
|
@ -2223,7 +2223,7 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
osSyncPrintf("\n\n\nNa_StartMorinigBgm\n\n");
|
||||
Audio_PlaySequence2(globalCtx->sequenceCtx.seqId);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
break;
|
||||
case 1:
|
||||
if(gSaveContext.dayTime > 0xB71C)
|
||||
|
@ -2232,14 +2232,14 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
{
|
||||
Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xF000FF);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(gSaveContext.dayTime > 0xC000)
|
||||
{
|
||||
Common_PlaySfx2(NA_SE_EV_DOG_CRY_EVENING);
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
|
@ -2248,12 +2248,12 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
func_800F6FB4(globalCtx->sequenceCtx.natureAmbienceId);
|
||||
func_800F6D58(1, 1, 1);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
break;
|
||||
case 4:
|
||||
if(gSaveContext.dayTime > 0xCAAB)
|
||||
{
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
|
@ -2262,7 +2262,7 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
{
|
||||
func_800F6D58(36, 1, 1);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
break;
|
||||
case 6:
|
||||
if((gSaveContext.dayTime < 0xCAAC) && (gSaveContext.dayTime > 0x4555))
|
||||
|
@ -2275,7 +2275,7 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
{
|
||||
Message_StartTextbox(globalCtx, 0x3066, NULL);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
|
@ -2284,12 +2284,12 @@ void func_80075B44(GlobalContext* globalCtx)
|
|||
{
|
||||
func_800F6D58(86, 1, 1);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
globalCtx->envCtx.dayState++;
|
||||
break;
|
||||
case 8:
|
||||
if(gSaveContext.dayTime > 0x4AAB)
|
||||
{
|
||||
globalCtx->envCtx.unk_E0 = 0;
|
||||
globalCtx->envCtx.dayState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2619,10 +2619,11 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState)
|
|||
envColor.g = ((envColor.g * sp98) + ((6.0f - sp98) * primColor.g)) * (1.0f / 6.0f);
|
||||
envColor.b = ((envColor.b * sp98) + ((6.0f - sp98) * primColor.b)) * (1.0f / 6.0f);
|
||||
|
||||
sp96 = (s32)(D_8015FDB0 * (11.0f / 6.0f));
|
||||
sp94 = (s32)(D_8015FDB0 * (9.0f / 6.0f));
|
||||
sp92 = (s32)(D_8015FDB0 * (6.0f / 6.0f));
|
||||
sp96 = (s32)(ScrollingMulitplier * (11.0f / 6.0f));
|
||||
sp94 = (s32)(ScrollingMulitplier * (9.0f / 6.0f));
|
||||
sp92 = (s32)(ScrollingMulitplier * (6.0f / 6.0f));
|
||||
|
||||
//onscreen sand storm texture
|
||||
OPEN_DISPS(globalCtx->gfxCtx, "../z_kankyo.c", 4044);
|
||||
|
||||
POLY_XLU_DISP = func_80093F34(POLY_XLU_DISP);
|
||||
|
@ -2636,7 +2637,7 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState)
|
|||
|
||||
CLOSE_DISPS(globalCtx->gfxCtx, "../z_kankyo.c", 4068);
|
||||
|
||||
D_8015FDB0 += (s32)sp98;
|
||||
ScrollingMulitplier += (s32)sp98;
|
||||
}
|
||||
|
||||
void Environment_AdjustLights(GlobalContext* globalCtx, f32 arg1, f32 arg2, f32 arg3, f32 arg4)
|
||||
|
|
|
@ -33,6 +33,14 @@ f32 Math_SinS(s16 angle)
|
|||
return sins(angle) * SHT_MINV;
|
||||
}
|
||||
|
||||
f32 Math_AccurateCosS(s16 angle)
|
||||
{
|
||||
return cosf(DEG_TO_RAD((f32)(angle & 0xFFFC) / SHT_MAX) * 180.0f);
|
||||
}
|
||||
f32 Math_AccurateSinS(s16 angle)
|
||||
{
|
||||
return sinf(DEG_TO_RAD((f32)(angle & 0xFFFC) / SHT_MAX) * 180.0f);
|
||||
}
|
||||
/**
|
||||
* Changes pValue by step (scaled by the update rate) towards target, setting it equal when the target is reached.
|
||||
* Returns true when target is reached, false otherwise.
|
||||
|
@ -434,6 +442,13 @@ void Math_Vec3f_Copy(Vec3f* dest, Vec3f* src)
|
|||
dest->z = src->z;
|
||||
}
|
||||
|
||||
void Math_VecPos_Copy(VecPos* dest, Vec3f* src)
|
||||
{
|
||||
dest->x = src->x;
|
||||
dest->y = src->y;
|
||||
dest->z = src->z;
|
||||
}
|
||||
|
||||
void Math_Vec3s_ToVec3f(Vec3f* dest, Vec3s* src)
|
||||
{
|
||||
dest->x = src->x;
|
||||
|
@ -621,7 +636,9 @@ static inline f32 _Math_SmoothStepToF(T* pValue, f32 target, f32 fraction, const
|
|||
float minStep = _minStep.value();
|
||||
if(*pValue != target)
|
||||
{
|
||||
f32 stepSize = (target - *pValue) * (fraction);
|
||||
if(fraction != 1.0f)
|
||||
fraction = fraction * FRAMERATE_SCALER;
|
||||
f32 stepSize = (target - *pValue) * fraction;
|
||||
|
||||
if((stepSize >= minStep) || (stepSize <= -minStep))
|
||||
{
|
||||
|
@ -713,6 +730,11 @@ void Math_ApproachF(CounterF* pValue, f32 target, f32 fraction, const Step& _ste
|
|||
_Math_ApproachF(pValue, target, fraction, _step);
|
||||
}
|
||||
|
||||
void Math_ApproachF(Rotation* pValue, f32 target, f32 fraction, const Step& _step)
|
||||
{
|
||||
_Math_ApproachF(pValue, target, fraction, _step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes pValue by step towards zero. If step is more than fraction of the remaining distance, step by that instead.
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,7 @@ void Map_SetPaletteData(GlobalContext* globalCtx, s16 room)
|
|||
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "PALETE Set"
|
||||
osSyncPrintf("PALETEセット 【 i=%x : room=%x 】Room_Inf[%d][4]=%x ( map_palete_no = %d )\n", paletteIndex, room, mapIndex, gSaveContext.sceneFlags[mapIndex].rooms, interfaceCtx->mapPaletteIndex);
|
||||
osSyncPrintf("Palette【 i=%x : room=%x 】Room_Inf[%d][4]=%x ( map_palete_no = %d )\n", paletteIndex, room, mapIndex, gSaveContext.sceneFlags[mapIndex].rooms, interfaceCtx->mapPaletteIndex);
|
||||
osSyncPrintf(VT_RST);
|
||||
|
||||
interfaceCtx->mapPalette[paletteIndex * 2] = 2;
|
||||
|
@ -199,14 +199,13 @@ void Map_InitData(GlobalContext* globalCtx, s16 room)
|
|||
case SCENE_JYASINBOSS:
|
||||
case SCENE_HAKADAN_BS:
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Deku Tree Dungeon MAP Texture DMA"
|
||||
osSyncPrintf("デクの樹ダンジョンMAP テクスチャDMA(%x) scene_id_offset=%d VREG(30)=%d\n", room, mapIndex, VREG(30));
|
||||
osSyncPrintf("Deku Tree Dungeon MAP Texture DMA(%x) scene_id_offset=%d VREG(30)=%d\n", room, mapIndex, VREG(30));
|
||||
osSyncPrintf(VT_RST);
|
||||
globalCtx->interfaceCtx.mapSegment1 = (u8*)map_i_static_lut[gMapData->dgnMinimapTexIndexOffset[mapIndex] + room];
|
||||
R_COMPASS_OFFSET_X = gMapData->roomCompassOffsetX[mapIndex][room];
|
||||
R_COMPASS_OFFSET_Y = gMapData->roomCompassOffsetY[mapIndex][room];
|
||||
Map_SetFloorPalettesData(globalCtx, VREG(30));
|
||||
osSyncPrintf("MAP 各階ONチェック\n"); // "MAP Individual Floor ON Check"
|
||||
osSyncPrintf("MAP Individual Floor ON Check\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -241,12 +240,12 @@ void Map_InitRoomData(GlobalContext* globalCtx, s16 room)
|
|||
case SCENE_JYASINBOSS:
|
||||
case SCENE_HAKADAN_BS:
|
||||
gSaveContext.sceneFlags[mapIndex].rooms |= gBitFlags[room];
|
||||
osSyncPrintf("ROOM_INF=%d\n", gSaveContext.sceneFlags[mapIndex].rooms);
|
||||
osSyncPrintf("Room_inf=%d\n", gSaveContext.sceneFlags[mapIndex].rooms);
|
||||
interfaceCtx->mapRoomNum = room;
|
||||
interfaceCtx->unk_25A = mapIndex;
|
||||
Map_SetPaletteData(globalCtx, room);
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("部屋部屋=%d\n", room); // "Room Room = %d"
|
||||
osSyncPrintf("Room room=%d\n", room);
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(globalCtx, room);
|
||||
break;
|
||||
|
@ -592,8 +591,7 @@ void Map_Update(GlobalContext* globalCtx)
|
|||
|
||||
if(interfaceCtx->mapRoomNum != sLastRoomNum)
|
||||
{
|
||||
// "Current floor = %d Current room = %x Number of rooms = %d"
|
||||
osSyncPrintf("現在階=%d 現在部屋=%x 部屋数=%d\n", floor, interfaceCtx->mapRoomNum, gMapData->switchEntryCount[mapIndex]);
|
||||
osSyncPrintf("Current floor=%d Current room=%x number of rooms=%d\n", floor, interfaceCtx->mapRoomNum, gMapData->switchEntryCount[mapIndex]);
|
||||
sLastRoomNum = interfaceCtx->mapRoomNum;
|
||||
}
|
||||
|
||||
|
@ -603,8 +601,7 @@ void Map_Update(GlobalContext* globalCtx)
|
|||
{
|
||||
interfaceCtx->mapRoomNum = gMapData->switchToRoom[mapIndex][i];
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Layer switching = %x"
|
||||
osSyncPrintf("階層切替=%x\n", interfaceCtx->mapRoomNum);
|
||||
osSyncPrintf("Layer switching=%x\n", interfaceCtx->mapRoomNum);
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(globalCtx, interfaceCtx->mapRoomNum);
|
||||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||||
|
|
|
@ -88,12 +88,14 @@ Vec3f* OLib_VecSphToVec3f(Vec3f* dest, VecSph* sph)
|
|||
{
|
||||
Vec3f v;
|
||||
f32 sinPitch;
|
||||
f32 cosPitch = Math_CosS(sph->pitch);
|
||||
f32 cosPitch;
|
||||
f32 sinYaw;
|
||||
f32 cosYaw = Math_CosS(sph->yaw);
|
||||
f32 cosYaw;
|
||||
|
||||
sinPitch = Math_SinS(sph->pitch);
|
||||
sinYaw = Math_SinS(sph->yaw);
|
||||
cosPitch = Math_AccurateCosS(sph->pitch);
|
||||
cosYaw = Math_AccurateCosS(sph->yaw);
|
||||
sinPitch = Math_AccurateSinS(sph->pitch);
|
||||
sinYaw = Math_AccurateSinS(sph->yaw);
|
||||
|
||||
v.x = sph->r * sinPitch * sinYaw;
|
||||
v.y = sph->r * cosPitch;
|
||||
|
|
|
@ -489,7 +489,7 @@ void Player_ClearZTarget(Player* pthis)
|
|||
pthis->stateFlags2 &= ~PLAYER_STATE2_ZTARGET_CHANGED;
|
||||
}
|
||||
|
||||
void func_8008EE08(Player* pthis)
|
||||
void SetFlagsForClearZTarget(Player* pthis)
|
||||
{
|
||||
if((pthis->actor.bgCheckFlags & BG_STATE_0) || (pthis->stateFlags1 & (PLAYER_STATE1_21 | PLAYER_STATE_HORSE_MOUNTED | PLAYER_STATE_SWIMMING)) ||
|
||||
(!(pthis->stateFlags1 & (PLAYER_STATE1_18 | PLAYER_STATE1_19)) && ((pthis->actor.world.pos.y - pthis->actor.floorHeight) < 100.0f)))
|
||||
|
@ -504,11 +504,11 @@ void func_8008EE08(Player* pthis)
|
|||
Player_ClearZTarget(pthis);
|
||||
}
|
||||
|
||||
void func_8008EEAC(GlobalContext* globalCtx, Actor* actor)
|
||||
void StartInvolintaryZtarget(GlobalContext* globalCtx, Actor* actor)
|
||||
{
|
||||
Player* pthis = GET_PLAYER(globalCtx);
|
||||
|
||||
func_8008EE08(pthis);
|
||||
SetFlagsForClearZTarget(pthis);
|
||||
pthis->targetedActor = actor;
|
||||
pthis->unk_684 = actor;
|
||||
pthis->stateFlags1 |= PLAYER_STATE1_16;
|
||||
|
@ -898,7 +898,7 @@ void func_8008F87C(GlobalContext* globalCtx, Player* pthis, SkelAnime* skelAnime
|
|||
|
||||
sp7C = D_80126058[(void)0, gSaveContext.linkAge];
|
||||
sp78 = D_80126060[(void)0, gSaveContext.linkAge];
|
||||
sp74 = D_80126068[(void)0, gSaveContext.linkAge] - pthis->unk_6C4;
|
||||
sp74 = D_80126068[(void)0, gSaveContext.linkAge] - pthis->sinkTimer;
|
||||
|
||||
Matrix_Push();
|
||||
Matrix_TranslateRotateZYX(pos, rot);
|
||||
|
@ -988,7 +988,7 @@ s32 func_8008FCC8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p
|
|||
}
|
||||
}
|
||||
|
||||
pos->y -= pthis->unk_6C4;
|
||||
pos->y -= pthis->sinkTimer;
|
||||
|
||||
if(pthis->rotationX != 0)
|
||||
{
|
||||
|
|
|
@ -2051,12 +2051,12 @@ void func_8009FC90(GlobalContext* globalCtx)
|
|||
CLOSE_DISPS(globalCtx->gfxCtx, "../z_scene_table.c", 7653);
|
||||
}
|
||||
|
||||
f32 D_8012A398 = 0.0f;
|
||||
TimerF32 dynamicWallTimer = 0.0f;
|
||||
|
||||
void func_8009FE58(GlobalContext* globalCtx)
|
||||
void sceneDrawHandlerBDAN(GlobalContext* globalCtx)
|
||||
{
|
||||
static s16 D_8012A39C = 538;
|
||||
static s16 D_8012A3A0 = 4272;
|
||||
static TimerS16 zoomingFrameTimer = 538;
|
||||
static TimerS16 stretchingFrameTimer = 4272;
|
||||
u32 gameplayFrames;
|
||||
f32 temp;
|
||||
|
||||
|
@ -2081,17 +2081,17 @@ void func_8009FE58(GlobalContext* globalCtx)
|
|||
|
||||
if(FrameAdvance_IsEnabled(globalCtx) != true)
|
||||
{
|
||||
D_8012A39C += 1820;
|
||||
D_8012A3A0 += 1820;
|
||||
zoomingFrameTimer += 1820;
|
||||
stretchingFrameTimer += 1820;
|
||||
|
||||
temp = 0.020000001f;
|
||||
func_800AA76C(
|
||||
&globalCtx->view, ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_CosS(D_8012A39C), ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A39C),
|
||||
((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(D_8012A3A0));
|
||||
func_800AA78C(&globalCtx->view, 1.f + (0.79999995f * temp * Math_SinS(D_8012A3A0)), 1.f + (0.39999998f * temp * Math_CosS(D_8012A3A0)), 1.f + (1 * temp * Math_CosS(D_8012A39C)));
|
||||
&globalCtx->view, ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_CosS(zoomingFrameTimer), ((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(zoomingFrameTimer),
|
||||
((360.00018f / 65535.0f) * (M_PI / 180.0f)) * temp * Math_SinS(stretchingFrameTimer));
|
||||
func_800AA78C(&globalCtx->view, 1.0f + (0.79999995f * temp * Math_SinS(stretchingFrameTimer)), 1.0f + (0.39999998f * temp * Math_CosS(stretchingFrameTimer)), 1.0f + (1 * temp * Math_CosS(zoomingFrameTimer)));
|
||||
func_800AA7AC(&globalCtx->view, 0.95f);
|
||||
|
||||
switch(globalCtx->roomCtx.unk_74[0])
|
||||
switch(globalCtx->roomCtx.unk_74[0].toS16())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
@ -2118,16 +2118,16 @@ void func_8009FE58(GlobalContext* globalCtx)
|
|||
break;
|
||||
}
|
||||
|
||||
D_8012A398 += 0.15f + (globalCtx->roomCtx.unk_74[1] * 0.001f);
|
||||
dynamicWallTimer += 0.15f + (globalCtx->roomCtx.unk_74[1] * 0.001f);
|
||||
}
|
||||
|
||||
if(globalCtx->roomCtx.curRoom.num == 2)
|
||||
{
|
||||
Matrix_Scale(1.0f, sinf(D_8012A398) * 0.8f, 1.0f, MTXMODE_NEW);
|
||||
Matrix_Scale(1.0f, sinf(dynamicWallTimer / FRAMERATE_SCALER_INV) * 0.8f, 1.0f, MTXMODE_NEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix_Scale(1.005f, sinf(D_8012A398) * 0.8f, 1.005f, MTXMODE_NEW);
|
||||
Matrix_Scale(1.005f, sinf(dynamicWallTimer / FRAMERATE_SCALER_INV) * 0.8f, 1.005f, MTXMODE_NEW);
|
||||
}
|
||||
|
||||
gSPSegment(POLY_OPA_DISP++, 0x0D, Matrix_NewMtx(globalCtx->gfxCtx, "../z_scene_table.c", 7809));
|
||||
|
@ -2190,7 +2190,7 @@ void func_800A059C(GlobalContext* globalCtx)
|
|||
|
||||
void (*sSceneDrawHandlers[])(GlobalContext*) = {
|
||||
func_80099550, func_8009DA30, func_8009DD5C, func_8009DE78, func_8009E0B8, func_8009E54C, func_8009E730, func_8009E8C0, func_8009EAD8, func_8009EE44, func_8009F074, func_8009F1B4, func_8009F270, func_8009F40C,
|
||||
func_8009F5D4, func_8009F7D4, func_8009F9D0, func_8009FB74, func_8009FC90, func_800995DC, func_80099878, func_8009FE58, func_8009D758, func_8009B0FC, func_8009AE30, func_8009D974, func_800A0334, func_8009CC00,
|
||||
func_8009F5D4, func_8009F7D4, func_8009F9D0, func_8009FB74, func_8009FC90, func_800995DC, func_80099878, sceneDrawHandlerBDAN, func_8009D758, func_8009B0FC, func_8009AE30, func_8009D974, func_800A0334, func_8009CC00,
|
||||
func_80099760, func_8009B86C, func_80099BD8, func_8009A45C, func_8009A798, func_8009A9DC, func_8009B9BC, func_8009BAA4, func_8009BC44, func_8009C3EC, func_8009C0AC, func_8009ACA8, func_8009AFE0, func_8009D0E8,
|
||||
func_8009C608, func_8009C8B8, func_8009D31C, func_8009D438, func_8009D5B4, func_8009CAC0, func_8009AB98, func_800A059C, func_8009CF84, func_800A057C, func_800A055C,
|
||||
};
|
||||
|
|
|
@ -93,7 +93,7 @@ s32 BgBdanObjects_GetContactRu1(BgBdanObjects* pthis, s32 arg1)
|
|||
case 3:
|
||||
return pthis->cameraSetting == CAM_SET_DUNGEON1;
|
||||
default:
|
||||
osSyncPrintf("Bg_Bdan_Objects_Get_Contact_Ru1\nそんな受信モードは無い%d!!!!!!!!\n");
|
||||
osSyncPrintf("Bg_Bdan_Objects_Get_Contact_Ru1\nThere is no such reception mode %d!!!!!!!!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ void BgBdanObjects_SetContactRu1(BgBdanObjects* pthis, s32 arg1)
|
|||
gSaveContext.infTable[20] |= 0x40;
|
||||
break;
|
||||
default:
|
||||
osSyncPrintf("Bg_Bdan_Objects_Set_Contact_Ru1\nそんな送信モードは無い%d!!!!!!!!\n");
|
||||
osSyncPrintf("Bg_Bdan_Objects_Set_Contact_Ru1\nThere is no such transmission mode %d!!!!!!!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,13 @@ struct BgBdanSwitch
|
|||
/* 0x0164 */ BgBdanSwitchActionFunc actionFunc;
|
||||
/* 0x0168 */ ColliderJntSph collider;
|
||||
/* 0x0188 */ ColliderJntSphElement colliderItems[1];
|
||||
/* 0x01C8 */ f32 unk_1C8;
|
||||
/* 0x01CC */ s16 unk_1CC;
|
||||
/* 0x01C8 */ TimerF32 unk_1C8;
|
||||
/* 0x01CC */ TimerS16 unk_1CC;
|
||||
/* 0x01CE */ char unk_1CE[0x2];
|
||||
/* 0x01D0 */ f32 unk_1D0;
|
||||
/* 0x01D4 */ f32 unk_1D4;
|
||||
/* 0x01D8 */ s16 unk_1D8;
|
||||
/* 0x01DA */ s16 unk_1DA;
|
||||
/* 0x01D8 */ TimerS16 unk_1D8;
|
||||
/* 0x01DA */ TimerS16 unk_1DA;
|
||||
/* 0x01DC */ u8 unk_1DC;
|
||||
/* 0x01DD */ char unk_1DD[0x3];
|
||||
};
|
||||
|
|
|
@ -242,16 +242,16 @@ void func_8086ED70(BgBombwall* pthis, GlobalContext* globalCtx)
|
|||
void func_8086EDFC(BgBombwall* pthis, GlobalContext* globalCtx)
|
||||
{
|
||||
pthis->dList = gBgBombwallNormalDL;
|
||||
pthis->unk_2A0 = 1;
|
||||
pthis->animTimer = 1;
|
||||
func_8086EB5C(pthis, globalCtx);
|
||||
pthis->actionFunc = func_8086EE40;
|
||||
}
|
||||
|
||||
void func_8086EE40(BgBombwall* pthis, GlobalContext* globalCtx)
|
||||
{
|
||||
if(pthis->unk_2A0 > 0)
|
||||
if(pthis->animTimer > 0)
|
||||
{
|
||||
pthis->unk_2A0--;
|
||||
pthis->animTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -15,7 +15,6 @@ struct BgBombwall
|
|||
/* 0x0184 */ ColliderTrisElement colliderItems[3];
|
||||
/* 0x0298 */ BgBombwallActionFunc actionFunc;
|
||||
/* 0x029C */ Gfx* dList;
|
||||
/* 0x02A0 */ s16 unk_2A0;
|
||||
/* 0x02A0 */ TimerS16 animTimer;
|
||||
/* 0x02A2 */ u8 unk_2A2;
|
||||
/* 0x02A3 */ u8 unk_2A3;
|
||||
};
|
||||
|
|
|
@ -162,7 +162,7 @@ void func_808BF078(BgYdanMaruta* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
if(pthis->collider.base.acFlags & AC_HIT)
|
||||
{
|
||||
pthis->unk_16A = 20;
|
||||
pthis->timer = 20;
|
||||
Flags_SetSwitch(globalCtx, pthis->switchFlag);
|
||||
Common_PlaySfx(NA_SE_SY_CORRECT_CHIME);
|
||||
pthis->actionFunc = func_808BF108;
|
||||
|
@ -178,11 +178,11 @@ void func_808BF108(BgYdanMaruta* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
s16 temp;
|
||||
|
||||
if(pthis->unk_16A != 0)
|
||||
if(pthis->timer != 0)
|
||||
{
|
||||
pthis->unk_16A--;
|
||||
pthis->timer--;
|
||||
}
|
||||
if(pthis->unk_16A == 0)
|
||||
if(pthis->timer == 0)
|
||||
{
|
||||
pthis->actionFunc = func_808BF1EC;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ void func_808BF108(BgYdanMaruta* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
}
|
||||
|
||||
temp = (pthis->unk_16A % 4) - 2;
|
||||
temp = (pthis->timer % 4) - 2;
|
||||
if(temp == -2)
|
||||
{
|
||||
temp = 0;
|
||||
|
|
|
@ -13,7 +13,7 @@ struct BgYdanMaruta
|
|||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgYdanMarutaActionFunc actionFunc;
|
||||
/* 0x0168 */ u8 switchFlag;
|
||||
/* 0x016A */ s16 unk_16A;
|
||||
/* 0x016A */ TimerS16 timer;
|
||||
/* 0x016C */ ColliderTris collider;
|
||||
/* 0x018C */ ColliderTrisElement elements[2];
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,8 +13,8 @@ struct BossDodongoEffect
|
|||
/* 0x00 */ Vec3f unk_00;
|
||||
/* 0x0C */ Vec3f unk_0C;
|
||||
/* 0x18 */ Vec3f unk_18;
|
||||
/* 0x24 */ u8 unk_24;
|
||||
/* 0x25 */ u8 unk_25;
|
||||
/* 0x24 */ bool unk_24;
|
||||
/* 0x25 */ TimerU8 unk_25;
|
||||
/* 0x26 */ Color_RGB8 color;
|
||||
/* 0x2A */ s16 alpha;
|
||||
/* 0x2C */ f32 unk_2C;
|
||||
|
@ -26,68 +26,55 @@ struct BossDodongo
|
|||
/* 0x014C */ SkelAnime skelAnime;
|
||||
/* 0x0190 */ BossDodongoActionFunc actionFunc;
|
||||
/* 0x0194 */ s16 health;
|
||||
/* 0x0196 */ s16 unk_196;
|
||||
/* 0x0198 */ s16 unk_198;
|
||||
/* 0x019A */ s16 unk_19A;
|
||||
/* 0x0196 */ TimerS16 timer1;//sound related?
|
||||
/* 0x0198 */ TimerS16 timer2;//sound related?
|
||||
/* 0x019C */ s16 csState;
|
||||
/* 0x019E */ s16 unk_19E;
|
||||
/* 0x01A0 */ s16 unk_1A0;
|
||||
/* 0x019E */ TimerS16 lavaFloorTimer;//lava floor speed?
|
||||
/* 0x01A0 */ s16 unk_1A0;//corner related index?
|
||||
/* 0x01A2 */ s16 unk_1A2;
|
||||
/* 0x01A4 */ s16 unk_1A4;
|
||||
/* 0x01A6 */ s16 unk_1A6;
|
||||
/* 0x01A8 */ s16 numWallCollisions;
|
||||
/* 0x01AA */ s16 unk_1AA;
|
||||
/* 0x01AC */ s16 unk_1AC;
|
||||
/* 0x01AE */ s16 unk_1AE;
|
||||
/* 0x01B0 */ s16 unk_1B0;
|
||||
/* 0x01B2 */ char unk_1B2[0x2];
|
||||
/* 0x01AA */ bool unk_1AA;//used as boolean
|
||||
/* 0x01AC */ TimerS16 eatExplosiveTimer;//timer for eating the bomb
|
||||
/* 0x01AE */ TimerS16 fireBallFadeTimer;//maintains the trail effect for fire ball
|
||||
/* 0x01B4 */ s16 cutsceneCamera;
|
||||
/* 0x01B6 */ s16 unk_1B6;
|
||||
/* 0x01B6 */ TimerS16 cutsceneCameraBounceTimer;
|
||||
/* 0x01B8 */ s16 playerYawInRange;
|
||||
/* 0x01BA */ s16 playerPosInRange;
|
||||
/* 0x01BC */ s16 unk_1BC;
|
||||
/* 0x01BE */ s16 unk_1BE;
|
||||
/* 0x01C0 */ s16 unk_1C0;
|
||||
/* 0x01C2 */ s16 unk_1C2;
|
||||
/* 0x01C4 */ s16 unk_1C4; // Some kind of angle
|
||||
/* 0x01C6 */ s16 unk_1C6;
|
||||
/* 0x01C8 */ s16 unk_1C8;
|
||||
/* 0x01CA */ char unk_1CA[0x2];
|
||||
/* 0x01BC */ s16 walkingState;
|
||||
/* 0x01BE */ TimerS16 colorFilterTransitionTimer;
|
||||
/* 0x01C0 */ TimerS16 whiteFlashFogTimer;
|
||||
/* 0x01C2 */ s16 unk_1C2;//floor transition index
|
||||
/* 0x01C4 */ Rotation rollingRot;//rolling timer
|
||||
/* 0x01C6 */ bool isFloorRock;//used as a boolean
|
||||
/* 0x01C8 */ TimerS16 unk_1C8;//?unsure?fireball begining transition?
|
||||
/* 0x01CC */ s16 unk_1CC;
|
||||
/* 0x01CE */ char unk_1CE[0xC];
|
||||
/* 0x01DA */ s16 unk_1DA;
|
||||
/* 0x01DC */ s16 unk_1DC;
|
||||
/* 0x01DE */ s16 unk_1DE;
|
||||
/* 0x01E0 */ s16 unk_1E0;
|
||||
/* 0x01E2 */ u8 unk_1E2;
|
||||
/* 0x01E3 */ s8 unk_1E3;
|
||||
/* 0x01E4 */ f32 unk_1E4;
|
||||
/* 0x01DA */ TimerS16 blowFireTimer;
|
||||
/* 0x01E2 */ bool unk_1E2;//health related?
|
||||
/* 0x01E4 */ f32 unk_1E4;//position related
|
||||
/* 0x01E8 */ f32 unk_1E8;
|
||||
/* 0x01EC */ f32 unk_1EC;
|
||||
/* 0x01F0 */ char unk_1F0[0x8];
|
||||
/* 0x01F8 */ f32 unk_1F8;
|
||||
/* 0x01FC */ f32 unk_1FC;
|
||||
/* 0x0200 */ f32 unk_200;
|
||||
/* 0x01F8 */ f32 unk_1F8;//laydown related?
|
||||
/* 0x0204 */ f32 unk_204;
|
||||
/* 0x0208 */ f32 unk_208;
|
||||
/* 0x0208 */ f32 unk_208;//limb rot scal
|
||||
/* 0x020C */ f32 unk_20C;
|
||||
/* 0x0210 */ f32 colorFilterR;
|
||||
/* 0x0214 */ f32 colorFilterG;
|
||||
/* 0x0214 */ f32 colorFilterB;
|
||||
/* 0x021C */ f32 colorFilterMin;
|
||||
/* 0x0220 */ f32 colorFilterMax;
|
||||
/* 0x0224 */ f32 unk_224;
|
||||
/* 0x0224 */ f32 floorTexTransitionMultiplier;
|
||||
/* 0x0228 */ f32 unk_228;
|
||||
/* 0x022C */ f32 unk_22C;
|
||||
/* 0x0230 */ f32 unk_230;
|
||||
/* 0x0234 */ f32 unk_234;
|
||||
/* 0x0238 */ f32 unk_238;
|
||||
/* 0x023C */ f32 unk_23C;
|
||||
/* 0x0230 */ TimerF32 endSceneCameraPanTimer;
|
||||
/* 0x0234 */ f32 rollingRotScale; // rotation inc?
|
||||
/* 0x0238 */ f32 endSceneBodyRotScale;
|
||||
/* 0x023C */ f32 unk_23C;///groundRotation
|
||||
/* 0x0240 */ f32 unk_240;
|
||||
/* 0x0244 */ f32 unk_244;
|
||||
/* 0x0248 */ char unk_248[0x14];
|
||||
/* 0x025C */ f32 unk_25C[50];
|
||||
/* 0x0324 */ f32 unk_324[50];
|
||||
/* 0x0244 */ f32 unk_244;//fireball travel c?
|
||||
/* 0x025C */ TimerF32 limbRot[50];
|
||||
/* 0x0324 */ TimerF32 limbRndRot[50];
|
||||
/* 0x03EC */ Vec3f vec;
|
||||
/* 0x03F8 */ Vec3f firePos;
|
||||
/* 0x0404 */ Vec3f unk_404;
|
||||
|
|
|
@ -76,7 +76,7 @@ struct BossDoorInfo
|
|||
struct DoorShutter
|
||||
{
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ s16 unk_164;
|
||||
/* 0x0164 */ TimerS16 unk_164;
|
||||
/* 0x0166 */ s16 unk_166;
|
||||
/* 0x0168 */ s16 unk_168;
|
||||
/* 0x016A */ u8 doorType;
|
||||
|
@ -84,7 +84,7 @@ struct DoorShutter
|
|||
/* 0x016C */ u8 unk_16C;
|
||||
/* 0x016D */ s32 requiredObjBankIndex;
|
||||
/* 0x016E */ Timer unk_16E;
|
||||
/* 0x016F */ s8 unk_16F;
|
||||
/* 0x016F */ TimerS8 unk_16F;
|
||||
/* 0x0170 */ f32 unk_170;
|
||||
/* 0x0174 */ DoorShutterActionFunc actionFunc;
|
||||
};
|
||||
|
|
|
@ -143,7 +143,7 @@ void EnBa_Destroy(Actor* thisx, GlobalContext* globalCtx)
|
|||
|
||||
void EnBa_SetupIdle(EnBa* pthis)
|
||||
{
|
||||
pthis->unk14C = 2;
|
||||
pthis->state = 2;
|
||||
pthis->unk31C = 1500;
|
||||
pthis->actor.speedXZ = 10.0f;
|
||||
EnBa_SetupAction(pthis, EnBa_Idle);
|
||||
|
@ -211,7 +211,7 @@ void EnBa_Idle(EnBa* pthis, GlobalContext* globalCtx)
|
|||
|
||||
void EnBa_SetupFallAsBlob(EnBa* pthis)
|
||||
{
|
||||
pthis->unk14C = 0;
|
||||
pthis->state = 0;
|
||||
pthis->actor.speedXZ = Rand_CenteredFloat(8.0f);
|
||||
pthis->actor.world.rot.y = Rand_CenteredFloat(65535.0f);
|
||||
pthis->unk318 = 20;
|
||||
|
@ -244,7 +244,7 @@ void EnBa_FallAsBlob(EnBa* pthis, GlobalContext* globalCtx)
|
|||
|
||||
void EnBa_SetupSwingAtPlayer(EnBa* pthis)
|
||||
{
|
||||
pthis->unk14C = 3;
|
||||
pthis->state = 3;
|
||||
pthis->unk318 = 20;
|
||||
pthis->unk31A = 0;
|
||||
pthis->unk31C = 1500;
|
||||
|
@ -367,7 +367,7 @@ void EnBa_SwingAtPlayer(EnBa* pthis, GlobalContext* globalCtx)
|
|||
|
||||
void func_809B7174(EnBa* pthis)
|
||||
{
|
||||
pthis->unk14C = 1;
|
||||
pthis->state = 1;
|
||||
pthis->unk31C = 1500;
|
||||
pthis->unk318 = 20;
|
||||
pthis->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||
|
@ -437,7 +437,7 @@ void func_809B75A0(EnBa* pthis, GlobalContext* globalCtx2)
|
|||
|
||||
pthis->unk31C = 2500;
|
||||
EffectSsDeadSound_SpawnStationary(globalCtx, &pthis->actor.projectedPos, NA_SE_EN_BALINADE_HAND_DEAD, 1, 1, 40);
|
||||
pthis->unk14C = 0;
|
||||
pthis->state = 0;
|
||||
|
||||
for(i = 7; i < 14; i++)
|
||||
{
|
||||
|
@ -527,7 +527,7 @@ void EnBa_Update(Actor* thisx, GlobalContext* globalCtx)
|
|||
{
|
||||
pthis->actor.focus.pos = pthis->unk158[6];
|
||||
}
|
||||
if(pthis->unk14C >= 2)
|
||||
if(pthis->state >= 2)
|
||||
{
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &pthis->collider.base);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,9 @@ enum EnBaType
|
|||
struct EnBa
|
||||
{
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ s32 unk14C;
|
||||
/* 0x014C */ s32 state;
|
||||
/* 0x0150 */ EnBaActionFunc actionFunc;
|
||||
/* 0x0154 */ s16 upperParams;
|
||||
/* 0x0156 */ s16 unk156;
|
||||
/* 0x0158 */ Vec3f unk158[14];
|
||||
/* 0x0200 */ Vec3f unk200[14];
|
||||
/* 0x02A8 */ Vec3s unk2A8[14];
|
||||
|
|
|
@ -57,7 +57,7 @@ void EnBdfire_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
{
|
||||
EnBdfire_SetupAction(pthis, func_809BC2A4);
|
||||
pthis->actor.scale.x = 2.8f;
|
||||
pthis->unk_154 = 90;
|
||||
pthis->timer = 90;
|
||||
Lights_PointNoGlowSetInfo(&pthis->lightInfoNoGlow, pthis->actor.world.pos.x, pthis->actor.world.pos.y, pthis->actor.world.pos.z, 255, 255, 255, 300);
|
||||
pthis->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &pthis->lightInfoNoGlow);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ void EnBdfire_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
EnBdfire_SetupAction(pthis, func_809BC598);
|
||||
ActorShape_Init(&pthis->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f);
|
||||
pthis->actor.speedXZ = 30.0f;
|
||||
pthis->unk_154 = (25 - (s32)(pthis->actor.params * 0.8f));
|
||||
if(pthis->unk_154 < 0)
|
||||
pthis->timer = (25 - (s32)(pthis->actor.params * 0.8f));
|
||||
if(pthis->timer < 0)
|
||||
{
|
||||
pthis->unk_154 = 0;
|
||||
pthis->timer = 0;
|
||||
}
|
||||
pthis->unk_188 = 4.2000003f - (pthis->actor.params * 0.25f * 0.6f);
|
||||
|
||||
|
@ -82,7 +82,7 @@ void EnBdfire_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
{
|
||||
pthis->unk_18C = 20.0f;
|
||||
}
|
||||
pthis->unk_156 = (Rand_ZeroOne() * 8.0f);
|
||||
pthis->animTimer = (Rand_ZeroOne() * 8.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,20 +115,20 @@ void func_809BC2A4(EnBdfire* pthis, GlobalContext* globalCtx)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(pthis->unk_154 < 70)
|
||||
if(pthis->timer < 70)
|
||||
{
|
||||
Math_SmoothStepToF(&pthis->unk_18C, 128.0f, 0.1f, 1.5f, 0.0f);
|
||||
Math_SmoothStepToF(&pthis->unk_190, 255.0f, 1.0f, 3.8249998f, 0.0f);
|
||||
Math_SmoothStepToF(&pthis->unk_194, 100.0f, 1.0f, 1.5f, 0.0f);
|
||||
}
|
||||
if(pthis->unk_154 == 0)
|
||||
if(pthis->timer == 0)
|
||||
{
|
||||
temp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_154--;
|
||||
temp = pthis->unk_154;
|
||||
pthis->timer--;
|
||||
temp = pthis->timer;
|
||||
}
|
||||
if(temp == 0)
|
||||
{
|
||||
|
@ -198,14 +198,14 @@ void func_809BC598(EnBdfire* pthis, GlobalContext* globalCtx)
|
|||
pthis->actor.world.rot.y -= 0x4000;
|
||||
}
|
||||
}
|
||||
if(pthis->unk_154 == 0)
|
||||
if(pthis->timer == 0)
|
||||
{
|
||||
temp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_154--;
|
||||
temp = pthis->unk_154;
|
||||
pthis->timer--;
|
||||
temp = pthis->timer;
|
||||
}
|
||||
if(temp == 0)
|
||||
{
|
||||
|
@ -236,7 +236,7 @@ void EnBdfire_Update(Actor* thisx, GlobalContext* globalCtx)
|
|||
{
|
||||
EnBdfire* pthis = (EnBdfire*)thisx;
|
||||
|
||||
pthis->unk_156++;
|
||||
pthis->animTimer++;
|
||||
pthis->actionFunc(pthis, globalCtx);
|
||||
Actor_MoveForward(&pthis->actor);
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ void EnBdfire_DrawFire(EnBdfire* pthis, GlobalContext* globalCtx)
|
|||
s32 pad;
|
||||
|
||||
OPEN_DISPS(globalCtx->gfxCtx, "../z_en_bdfire.c", 612);
|
||||
temp = pthis->unk_156 & 7;
|
||||
temp = pthis->animTimer & 7;
|
||||
func_800D1FD4(&globalCtx->billboardMtxF);
|
||||
func_80094BC4(globalCtx->gfxCtx);
|
||||
POLY_XLU_DISP = func_80094968(POLY_XLU_DISP);
|
||||
|
|
|
@ -15,15 +15,13 @@ struct EnBdfire
|
|||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ EnBdfireActionFunc actionFunc;
|
||||
/* 0x0150 */ EnBdfireDrawFunc drawFunc;
|
||||
/* 0x0154 */ s16 unk_154;
|
||||
/* 0x0156 */ s16 unk_156;
|
||||
/* 0x0154 */ TimerS16 timer;//how long the fire ball will last
|
||||
/* 0x0156 */ TimerS16 animTimer;//timer for animation speed
|
||||
/* 0x0158 */ s16 unk_158;
|
||||
/* 0x015A */ char unk_15A[0x2E];
|
||||
/* 0x0188 */ f32 unk_188;
|
||||
/* 0x018C */ f32 unk_18C;
|
||||
/* 0x0190 */ f32 unk_190;
|
||||
/* 0x0194 */ f32 unk_194;
|
||||
/* 0x0198 */ char unk_198[0x38];
|
||||
/* 0x01D0 */ LightNode* lightNode;
|
||||
/* 0x01D4 */ LightInfo lightInfoNoGlow;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
* File: z_en_brob.c
|
||||
* Overlay: ovl_En_Brob
|
||||
* Description: Flobbery Muscle Block (Jabu-Jabu's Belly)
|
||||
* Description: Flobbery Muscle Block (The Enimies prodomanently in jabujabu)
|
||||
*/
|
||||
|
||||
#include "z_en_brob.h"
|
||||
|
@ -121,7 +121,7 @@ void func_809CADDC(EnBrob* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
func_8003EC50(globalCtx, &globalCtx->colCtx.dyna, pthis->dyna.bgId);
|
||||
pthis->timer = pthis->actionFunc == func_809CB2B8 ? 200 : 0;
|
||||
pthis->unk_1AE = 0;
|
||||
pthis->transitionTimer = 0;
|
||||
pthis->actionFunc = func_809CB054;
|
||||
}
|
||||
|
||||
|
@ -129,14 +129,14 @@ void func_809CAE44(EnBrob* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
Animation_PlayOnce(&pthis->skelAnime, &object_brob_Anim_001750);
|
||||
func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, pthis->dyna.bgId);
|
||||
pthis->unk_1AE = 1000;
|
||||
pthis->transitionTimer = 1000;
|
||||
pthis->actionFunc = func_809CB114;
|
||||
}
|
||||
|
||||
void func_809CAEA0(EnBrob* pthis)
|
||||
{
|
||||
Animation_MorphToLoop(&pthis->skelAnime, &object_brob_Anim_001958, -5.0f);
|
||||
pthis->unk_1AE = 8000;
|
||||
pthis->transitionTimer = 8000;
|
||||
pthis->timer = 1200;
|
||||
pthis->actionFunc = func_809CB218;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ void func_809CAEA0(EnBrob* pthis)
|
|||
void func_809CAEF4(EnBrob* pthis)
|
||||
{
|
||||
Animation_MorphToPlayOnce(&pthis->skelAnime, &object_brob_Anim_000290, -5.0f);
|
||||
pthis->unk_1AE -= 125.0f;
|
||||
pthis->transitionTimer -= 125.0f;
|
||||
Actor_SetColorFilter(&pthis->dyna.actor, 0, 0xFF, 0, 0x50);
|
||||
Audio_PlayActorSound2(&pthis->dyna.actor, NA_SE_EN_GOMA_JR_FREEZE);
|
||||
pthis->actionFunc = func_809CB2B8;
|
||||
|
@ -153,7 +153,7 @@ void func_809CAEF4(EnBrob* pthis)
|
|||
void func_809CAF88(EnBrob* pthis)
|
||||
{
|
||||
Animation_Change(&pthis->skelAnime, &object_brob_Anim_001750, -1.0f, Animation_GetLastFrame(&object_brob_Anim_001750), 0.0f, ANIMMODE_ONCE, -5.0f);
|
||||
pthis->unk_1AE = 8250;
|
||||
pthis->transitionTimer = 8250;
|
||||
pthis->actionFunc = func_809CB354;
|
||||
}
|
||||
|
||||
|
@ -201,15 +201,15 @@ void func_809CB114(EnBrob* pthis, GlobalContext* globalCtx)
|
|||
curFrame = pthis->skelAnime.curFrame;
|
||||
if(curFrame < 8.0f)
|
||||
{
|
||||
pthis->unk_1AE += 1000.0f;
|
||||
pthis->transitionTimer += 1000.0f;
|
||||
}
|
||||
else if(curFrame < 12.0f)
|
||||
{
|
||||
pthis->unk_1AE += 250.0f;
|
||||
pthis->transitionTimer += 250.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_1AE -= 250.0f;
|
||||
pthis->transitionTimer -= 250.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ void func_809CB2B8(EnBrob* pthis, GlobalContext* globalCtx)
|
|||
}
|
||||
else if(pthis->skelAnime.curFrame < 8.0f)
|
||||
{
|
||||
pthis->unk_1AE -= 1250.0f;
|
||||
pthis->transitionTimer -= 1250.0f;
|
||||
}
|
||||
pthis->dyna.actor.colorFilterTimer = 0x50;
|
||||
}
|
||||
|
@ -257,15 +257,15 @@ void func_809CB354(EnBrob* pthis, GlobalContext* globalCtx)
|
|||
curFrame = pthis->skelAnime.curFrame;
|
||||
if(curFrame < 8.0f)
|
||||
{
|
||||
pthis->unk_1AE -= 1000.0f;
|
||||
pthis->transitionTimer -= 1000.0f;
|
||||
}
|
||||
else if(curFrame < 12.0f)
|
||||
{
|
||||
pthis->unk_1AE -= 250.0f;
|
||||
pthis->transitionTimer -= 250.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_1AE += 250.0f;
|
||||
pthis->transitionTimer += 250.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ void EnBrob_Draw(Actor* thisx, GlobalContext* globalCtx)
|
|||
EnBrob* pthis = (EnBrob*)thisx;
|
||||
|
||||
func_80093D18(globalCtx->gfxCtx);
|
||||
Matrix_Translate(0.0f, pthis->unk_1AE, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Translate(0.0f, pthis->transitionTimer, 0.0f, MTXMODE_APPLY);
|
||||
SkelAnime_DrawFlexOpa(globalCtx, pthis->skelAnime.skeleton, pthis->skelAnime.jointTable, pthis->skelAnime.dListCount, NULL, EnBrob_PostLimbDraw, pthis);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ struct EnBrob
|
|||
/* 0x0164 */ SkelAnime skelAnime;
|
||||
/* 0x01A8 */ EnBrobActionFunc actionFunc;
|
||||
/* 0x01AC */ Timer timer;
|
||||
/* 0x01AE */ s16 unk_1AE;
|
||||
/* 0x01AE */ TimerS16 transitionTimer;
|
||||
/* 0x01B0 */ Vec3s jointTable[10];
|
||||
/* 0x01EC */ Vec3s morphTable[10];
|
||||
/* 0x0228 */ ColliderCylinder colliders[2];
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#define INTERNAL_SRC_OVERLAYS_ACTORS_OVL_EN_BUBBLE_Z_EN_BUBBLE_C
|
||||
#include "actor_common.h"
|
||||
/*
|
||||
* File: z_en_bubble.cpp
|
||||
* Description: Bubble
|
||||
*/
|
||||
|
||||
#include "z_en_bubble.h"
|
||||
#include "def/code_8006BA00.h"
|
||||
#include "def/random.h"
|
||||
|
@ -226,10 +231,10 @@ void EnBubble_Fly(EnBubble* pthis, GlobalContext* globalCtx)
|
|||
CollisionPoly* sp94;
|
||||
Actor* bumpActor;
|
||||
Vec3f sp84;
|
||||
Vec3f sp78;
|
||||
Vec3f sp6C;
|
||||
Vec3f sp60;
|
||||
Vec3f sp54;
|
||||
VecPos pos1;
|
||||
VecPos pos2;
|
||||
Vec3f normal;
|
||||
Vec3f vel;
|
||||
f32 bounceSpeed;
|
||||
s32 bgId;
|
||||
u8 bounceCount;
|
||||
|
@ -246,28 +251,31 @@ void EnBubble_Fly(EnBubble* pthis, GlobalContext* globalCtx)
|
|||
pthis->sinkSpeed -= 0.1f;
|
||||
if(pthis->sinkSpeed < pthis->actor.minVelocityY)
|
||||
{
|
||||
pthis->sinkSpeed = pthis->actor.minVelocityY;
|
||||
pthis->sinkSpeed = pthis->actor.minVelocityY / FRAMERATE_SCALER_INV;
|
||||
}
|
||||
sp54.x = pthis->velocityFromBounce.x + pthis->velocityFromBump.x;
|
||||
sp54.y = pthis->velocityFromBounce.y + pthis->velocityFromBump.y + pthis->sinkSpeed;
|
||||
sp54.z = pthis->velocityFromBounce.z + pthis->velocityFromBump.z;
|
||||
EnBubble_Vec3fNormalize(&sp54);
|
||||
vel.x = pthis->velocityFromBounce.x + pthis->velocityFromBump.x;
|
||||
vel.y = pthis->velocityFromBounce.y + pthis->velocityFromBump.y + pthis->sinkSpeed;
|
||||
vel.z = pthis->velocityFromBounce.z + pthis->velocityFromBump.z;
|
||||
EnBubble_Vec3fNormalize(&vel);
|
||||
|
||||
sp78.x = pthis->actor.world.pos.x;
|
||||
sp78.y = pthis->actor.world.pos.y + pthis->actor.shape.yOffset;
|
||||
sp78.z = pthis->actor.world.pos.z;
|
||||
sp6C = sp78;
|
||||
pos1.x = pthis->actor.world.pos.x;
|
||||
pos1.y = pthis->actor.world.pos.y + pthis->actor.shape.yOffset;
|
||||
pos1.z = pthis->actor.world.pos.z;
|
||||
pos2 = pos1;
|
||||
|
||||
sp6C.x += (sp54.x * 24.0f);
|
||||
sp6C.y += (sp54.y * 24.0f);
|
||||
sp6C.z += (sp54.z * 24.0f);
|
||||
if(BgCheck_EntityLineTest1(&globalCtx->colCtx, &sp78, &sp6C, &sp84, &sp94, true, true, true, false, &bgId))
|
||||
pos2.x += (vel.x * 24.0f) / FRAMERATE_SCALER_INV;
|
||||
pos2.y += (vel.y * 24.0f) / FRAMERATE_SCALER_INV;
|
||||
pos2.z += (vel.z * 24.0f) / FRAMERATE_SCALER_INV;
|
||||
|
||||
Vec3f pos1Chk = pos1;
|
||||
Vec3f pos2Chk = pos2;
|
||||
if(BgCheck_EntityLineTest1(&globalCtx->colCtx, &pos1Chk, &pos2Chk, &sp84, &sp94, true, true, true, false, &bgId))
|
||||
{
|
||||
sp60.x = COLPOLY_GET_NORMAL(sp94->normal.x);
|
||||
sp60.y = COLPOLY_GET_NORMAL(sp94->normal.y);
|
||||
sp60.z = COLPOLY_GET_NORMAL(sp94->normal.z);
|
||||
EnBubble_Vec3fNormalizedRelfect(&sp54, &sp60, &sp54);
|
||||
pthis->bounceDirection = sp54;
|
||||
normal.x = COLPOLY_GET_NORMAL(sp94->normal.x);
|
||||
normal.y = COLPOLY_GET_NORMAL(sp94->normal.y);
|
||||
normal.z = COLPOLY_GET_NORMAL(sp94->normal.z);
|
||||
EnBubble_Vec3fNormalizedRelfect(&vel, &normal, &vel);
|
||||
pthis->bounceDirection = vel;
|
||||
bounceCount = pthis->bounceCount;
|
||||
pthis->bounceCount = ++bounceCount;
|
||||
if(bounceCount > (s16)(Rand_ZeroOne() * 10.0f))
|
||||
|
@ -281,15 +289,15 @@ void EnBubble_Fly(EnBubble* pthis, GlobalContext* globalCtx)
|
|||
pthis->velocityFromBounce.z = (pthis->bounceDirection.z * bounceSpeed);
|
||||
pthis->sinkSpeed = 0.0f;
|
||||
Audio_PlayActorSound2(&pthis->actor, NA_SE_EN_AWA_BOUND);
|
||||
pthis->graphicRotSpeed = 128.0f;
|
||||
pthis->graphicRotSpeed = 128.0f / FRAMERATE_SCALER_INV;
|
||||
pthis->graphicEccentricity = 0.48f;
|
||||
}
|
||||
else if(pthis->actor.bgCheckFlags & BG_STATE_5 && sp54.y < 0.0f)
|
||||
else if(pthis->actor.bgCheckFlags & BG_STATE_5 && vel.y < 0.0f)
|
||||
{
|
||||
sp60.x = sp60.z = 0.0f;
|
||||
sp60.y = 1.0f;
|
||||
EnBubble_Vec3fNormalizedRelfect(&sp54, &sp60, &sp54);
|
||||
pthis->bounceDirection = sp54;
|
||||
normal.x = normal.z = 0.0f;
|
||||
normal.y = 1.0f;
|
||||
EnBubble_Vec3fNormalizedRelfect(&vel, &normal, &vel);
|
||||
pthis->bounceDirection = vel;
|
||||
bounceCount = pthis->bounceCount;
|
||||
pthis->bounceCount = ++bounceCount;
|
||||
if(bounceCount > (s16)(Rand_ZeroOne() * 10.0f))
|
||||
|
@ -303,7 +311,7 @@ void EnBubble_Fly(EnBubble* pthis, GlobalContext* globalCtx)
|
|||
pthis->velocityFromBounce.z = (pthis->bounceDirection.z * bounceSpeed);
|
||||
pthis->sinkSpeed = 0.0f;
|
||||
Audio_PlayActorSound2(&pthis->actor, NA_SE_EN_AWA_BOUND);
|
||||
pthis->graphicRotSpeed = 128.0f;
|
||||
pthis->graphicRotSpeed = 128.0f / FRAMERATE_SCALER_INV;
|
||||
pthis->graphicEccentricity = 0.48f;
|
||||
}
|
||||
pthis->actor.velocity.x = pthis->velocityFromBounce.x + pthis->velocityFromBump.x;
|
||||
|
|
|
@ -29,6 +29,6 @@ struct EnBubble
|
|||
/* 0x022C */ Vec3f bounceDirection;
|
||||
/* 0x0238 */ Vec3f velocityFromBounce;
|
||||
/* 0x0244 */ Vec3f normalizedBumpVelocity;
|
||||
/* 0x0250 */ Vec3f velocityFromBump;
|
||||
/* 0x025C */ f32 sinkSpeed;
|
||||
/* 0x0250 */ VecPos velocityFromBump;
|
||||
/* 0x025C */ TimerF32 sinkSpeed;
|
||||
};
|
||||
|
|
|
@ -138,8 +138,8 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
}
|
||||
}
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &pthis->actor, globalCtx, ACTOR_EN_COW, pthis->actor.world.pos.x, pthis->actor.world.pos.y, pthis->actor.world.pos.z, 0, pthis->actor.shape.rot.y, 0, 1);
|
||||
pthis->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f;
|
||||
pthis->unk_27A = 0;
|
||||
pthis->mooTimer = Rand_ZeroFloat(1000.0f) + 40.0f;
|
||||
pthis->breathingTimer = 0;
|
||||
pthis->actor.targetMode = 6;
|
||||
DREG(53) = 0;
|
||||
break;
|
||||
|
@ -151,7 +151,7 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
pthis->actionFunc = func_809DFA84;
|
||||
func_809DEF94(pthis);
|
||||
pthis->actor.flags &= ~ACTOR_FLAG_VISIBLE;
|
||||
pthis->unk_278 = ((u32)(Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f;
|
||||
pthis->mooTimer = ((u32)(Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f;
|
||||
break;
|
||||
}
|
||||
pthis->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||
|
@ -172,13 +172,13 @@ void EnCow_Destroy(Actor* thisx, GlobalContext* globalCtx)
|
|||
|
||||
void func_809DF494(EnCow* pthis, GlobalContext* globalCtx)
|
||||
{
|
||||
if(pthis->unk_278 > 0)
|
||||
if(pthis->mooTimer > 0)
|
||||
{
|
||||
pthis->unk_278 -= 1;
|
||||
pthis->mooTimer -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_278 = Rand_ZeroFloat(500.0f) + 40.0f;
|
||||
pthis->mooTimer = Rand_ZeroFloat(500.0f) + 40.0f;
|
||||
Animation_Change(&pthis->skelAnime, &gCowBodyChewAnim, 1.0f, pthis->skelAnime.curFrame, Animation_GetLastFrame(&gCowBodyChewAnim), ANIMMODE_ONCE, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -187,29 +187,29 @@ void func_809DF494(EnCow* pthis, GlobalContext* globalCtx)
|
|||
pthis->unk_276 |= 2;
|
||||
if(pthis->skelAnime.animation == &gCowBodyChewAnim)
|
||||
{
|
||||
pthis->unk_278 = 0;
|
||||
pthis->mooTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pthis->unk_27A += 1;
|
||||
if(pthis->unk_27A >= 0x31)
|
||||
pthis->breathingTimer += 1;
|
||||
if(pthis->breathingTimer >= 0x31)
|
||||
{
|
||||
pthis->unk_27A = 0;
|
||||
pthis->breathingTimer = 0;
|
||||
}
|
||||
|
||||
// (1.0f / 100.0f) instead of 0.01f below is necessary so 0.01f doesn't get reused mistakenly
|
||||
if(pthis->unk_27A < 0x20)
|
||||
if(pthis->breathingTimer < 0x20)
|
||||
{
|
||||
pthis->actor.scale.x = ((Math_SinS(pthis->unk_27A << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
|
||||
pthis->actor.scale.x = ((Math_SinS(pthis->breathingTimer << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->actor.scale.x = 0.01f;
|
||||
}
|
||||
|
||||
if(pthis->unk_27A >= 0x11)
|
||||
if(pthis->breathingTimer >= 0x11)
|
||||
{
|
||||
pthis->actor.scale.y = ((Math_SinS((pthis->unk_27A << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
|
||||
pthis->actor.scale.y = ((Math_SinS((pthis->breathingTimer << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -329,13 +329,13 @@ void func_809DF96C(EnCow* pthis, GlobalContext* globalCtx)
|
|||
|
||||
void func_809DFA84(EnCow* pthis, GlobalContext* globalCtx)
|
||||
{
|
||||
if(pthis->unk_278 > 0)
|
||||
if(pthis->mooTimer > 0)
|
||||
{
|
||||
pthis->unk_278--;
|
||||
pthis->mooTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_278 = Rand_ZeroFloat(200.0f) + 40.0f;
|
||||
pthis->mooTimer = Rand_ZeroFloat(200.0f) + 40.0f;
|
||||
Animation_Change(&pthis->skelAnime, &gCowTailIdleAnim, 1.0f, pthis->skelAnime.curFrame, Animation_GetLastFrame(&gCowTailIdleAnim), ANIMMODE_ONCE, 1.0f);
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ void func_809DFA84(EnCow* pthis, GlobalContext* globalCtx)
|
|||
pthis->unk_276 |= 2;
|
||||
if(pthis->skelAnime.animation == &gCowTailIdleAnim)
|
||||
{
|
||||
pthis->unk_278 = 0;
|
||||
pthis->mooTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ struct EnCow
|
|||
/* 0x024C */ Vec3s morphTable[6];
|
||||
/* 0x0270 */ Vec3s someRot;
|
||||
/* 0x0276 */ u16 unk_276;
|
||||
/* 0x0278 */ u16 unk_278;
|
||||
/* 0x027A */ u16 unk_27A;
|
||||
/* 0x0278 */ TimerU16 mooTimer;
|
||||
/* 0x027A */ TimerU16 breathingTimer;
|
||||
/* 0x027C */ EnCowActionFunc actionFunc;
|
||||
};
|
||||
|
|
|
@ -242,7 +242,7 @@ void EnDh_Wait(EnDh* pthis, GlobalContext* globalCtx)
|
|||
SkelAnime_Update(&pthis->skelAnime);
|
||||
if(pthis->actor.params != ENDH_START_ATTACK_BOMB)
|
||||
{
|
||||
func_8008EEAC(globalCtx, &pthis->actor);
|
||||
StartInvolintaryZtarget(globalCtx, &pthis->actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ void EnFish_Dropped_Fall(EnFish* pthis, GlobalContext* globalCtx)
|
|||
{
|
||||
osSyncPrintf(VT_COL(YELLOW, BLACK));
|
||||
// "BG missing? Running Actor_delete"
|
||||
osSyncPrintf("BG 抜け? Actor_delete します(%s %d)\n", "../z_en_sakana.c", 822);
|
||||
osSyncPrintf("Missing BG? Actor_delete Do(%s %d)\n", "../z_en_sakana.c", 822);
|
||||
osSyncPrintf(VT_RST);
|
||||
Actor_Kill(&pthis->actor);
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ void EnHata_Init(Actor* thisx, GlobalContext* globalCtx)
|
|||
pthis->invScale = 6;
|
||||
pthis->maxStep = 1000;
|
||||
pthis->minStep = 1;
|
||||
pthis->unk_278 = Rand_ZeroOne() * 0xFFFF;
|
||||
pthis->animTimer = Rand_ZeroOne() * 0xFFFF;
|
||||
}
|
||||
|
||||
void EnHata_Destroy(Actor* thisx, GlobalContext* globalCtx)
|
||||
|
@ -110,15 +110,15 @@ void EnHata_Update(Actor* thisx, GlobalContext* globalCtx2)
|
|||
|
||||
if(Rand_ZeroOne() > 0.5f)
|
||||
{
|
||||
pthis->unk_278 += 6000;
|
||||
pthis->animTimer += 6000;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthis->unk_278 += 3000;
|
||||
pthis->animTimer += 3000;
|
||||
}
|
||||
|
||||
// Mimic varying wind gusts
|
||||
sin = Math_SinS(pthis->unk_278) * 80.0f;
|
||||
sin = Math_SinS(pthis->animTimer) * 80.0f;
|
||||
pitch = -Math_Vec3f_Pitch(&zeroVec, &windVec);
|
||||
pitch = ((s32)((15000 - pitch) * (1.0f - (globalCtx->envCtx.windSpeed / (255.0f - sin))))) + pitch;
|
||||
Math_SmoothStepToS(&pthis->limbs[FLAGPOLE_LIMB_FLAG_1_HOIST_END_BASE].y, pitch, pthis->invScale, pthis->maxStep, pthis->minStep);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue