diff --git a/mupen64plus-input-raphnetraw/.gitignore b/mupen64plus-input-raphnetraw/.gitignore new file mode 100644 index 0000000..cb2cbd5 --- /dev/null +++ b/mupen64plus-input-raphnetraw/.gitignore @@ -0,0 +1,5 @@ +*.dll +*.so +*.o +*.swp +/projects/unix/_obj*/ diff --git a/mupen64plus-input-raphnetraw/COPYING b/mupen64plus-input-raphnetraw/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/mupen64plus-input-raphnetraw/COPYING @@ -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. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + , 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. diff --git a/mupen64plus-input-raphnetraw/INSTALL b/mupen64plus-input-raphnetraw/INSTALL new file mode 100644 index 0000000..b0d4a7d --- /dev/null +++ b/mupen64plus-input-raphnetraw/INSTALL @@ -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 + with your desired local installation path): + +$ cd projects/unix +$ make all +$ make install LIBDIR= + + diff --git a/mupen64plus-input-raphnetraw/LICENSES b/mupen64plus-input-raphnetraw/LICENSES new file mode 100644 index 0000000..7777bb7 --- /dev/null +++ b/mupen64plus-input-raphnetraw/LICENSES @@ -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. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + + , 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. + diff --git a/mupen64plus-input-raphnetraw/README.md b/mupen64plus-input-raphnetraw/README.md new file mode 100644 index 0000000..1e0c7b8 --- /dev/null +++ b/mupen64plus-input-raphnetraw/README.md @@ -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 +``` diff --git a/mupen64plus-input-raphnetraw/RELEASE b/mupen64plus-input-raphnetraw/RELEASE new file mode 100644 index 0000000..0bce74e --- /dev/null +++ b/mupen64plus-input-raphnetraw/RELEASE @@ -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 + diff --git a/mupen64plus-input-raphnetraw/projects/unix/Makefile b/mupen64plus-input-raphnetraw/projects/unix/Makefile new file mode 100644 index 0000000..9ee7226 --- /dev/null +++ b/mupen64plus-input-raphnetraw/projects/unix/Makefile @@ -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 diff --git a/mupen64plus-input-raphnetraw/projects/unix/buildwin32.sh b/mupen64plus-input-raphnetraw/projects/unix/buildwin32.sh new file mode 100755 index 0000000..c9be024 --- /dev/null +++ b/mupen64plus-input-raphnetraw/projects/unix/buildwin32.sh @@ -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 diff --git a/mupen64plus-input-raphnetraw/projects/unix/buildwin64.sh b/mupen64plus-input-raphnetraw/projects/unix/buildwin64.sh new file mode 100755 index 0000000..3f9393a --- /dev/null +++ b/mupen64plus-input-raphnetraw/projects/unix/buildwin64.sh @@ -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 diff --git a/mupen64plus-input-raphnetraw/release_src.sh b/mupen64plus-input-raphnetraw/release_src.sh new file mode 100755 index 0000000..016d858 --- /dev/null +++ b/mupen64plus-input-raphnetraw/release_src.sh @@ -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 diff --git a/mupen64plus-input-raphnetraw/release_windows.sh b/mupen64plus-input-raphnetraw/release_windows.sh new file mode 100755 index 0000000..2fb193e --- /dev/null +++ b/mupen64plus-input-raphnetraw/release_windows.sh @@ -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 diff --git a/mupen64plus-input-raphnetraw/src/gcn64.c b/mupen64plus-input-raphnetraw/src/gcn64.c new file mode 100644 index 0000000..30a2dd2 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64.c @@ -0,0 +1,371 @@ +/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware + Copyright (C) 2007-2017 Raphael Assenat + + This program is free software: you can 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 . +*/ +#include +#include +#include +#include +#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; +} + diff --git a/mupen64plus-input-raphnetraw/src/gcn64.h b/mupen64plus-input-raphnetraw/src/gcn64.h new file mode 100644 index 0000000..460cb24 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64.h @@ -0,0 +1,59 @@ +#ifndef _gcn64_h__ +#define _gcn64_h__ + +#include + +#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__ + diff --git a/mupen64plus-input-raphnetraw/src/gcn64_priv.h b/mupen64plus-input-raphnetraw/src/gcn64_priv.h new file mode 100644 index 0000000..909e5da --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64_priv.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 diff --git a/mupen64plus-input-raphnetraw/src/gcn64_protocol.h b/mupen64plus-input-raphnetraw/src/gcn64_protocol.h new file mode 100644 index 0000000..0c3ba24 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64_protocol.h @@ -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__ diff --git a/mupen64plus-input-raphnetraw/src/gcn64lib.c b/mupen64plus-input-raphnetraw/src/gcn64lib.c new file mode 100644 index 0000000..445d546 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64lib.c @@ -0,0 +1,444 @@ +/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware + Copyright (C) 2007-2015 Raphael Assenat + + This program is free software: you can 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 . +*/ +#include +#include +#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; icaps.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 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= 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; +} + diff --git a/mupen64plus-input-raphnetraw/src/gcn64lib.h b/mupen64plus-input-raphnetraw/src/gcn64lib.h new file mode 100644 index 0000000..c06639b --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/gcn64lib.h @@ -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__ diff --git a/mupen64plus-input-raphnetraw/src/hexdump.c b/mupen64plus-input-raphnetraw/src/hexdump.c new file mode 100644 index 0000000..4027f9a --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/hexdump.c @@ -0,0 +1,29 @@ +/* gc_n64_usb : Gamecube or N64 controller to USB adapter firmware + Copyright (C) 2007-2015 Raphael Assenat + + This program is free software: you can 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 . +*/ +#include + +void printHexBuf(unsigned char *buf, int n) +{ + int i; + + for (i=0; i +#include +#include + +#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); +} + + diff --git a/mupen64plus-input-raphnetraw/src/osal_dynamiclib_win32.c b/mupen64plus-input-raphnetraw/src/osal_dynamiclib_win32.c new file mode 100644 index 0000000..751e1b0 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/osal_dynamiclib_win32.c @@ -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 +#include +#include + +#include "m64p_types.h" +#include "osal_dynamiclib.h" + +m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) +{ + if (pLibHandle == NULL || pccLibraryPath == NULL) + return M64ERR_INPUT_ASSERT; + + *pLibHandle = LoadLibrary(pccLibraryPath); + + if (*pLibHandle == NULL) + { + char *pchErrMsg; + DWORD dwErr = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); + fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg); + LocalFree(pchErrMsg); + return M64ERR_INPUT_NOT_FOUND; + } + + return M64ERR_SUCCESS; +} + +void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) +{ + if (pccProcedureName == NULL) + return NULL; + + return GetProcAddress(LibHandle, pccProcedureName); +} + +m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) +{ + int rval = FreeLibrary(LibHandle); + + if (rval == 0) + { + char *pchErrMsg; + DWORD dwErr = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); + fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg); + LocalFree(pchErrMsg); + return M64ERR_INTERNAL; + } + + return M64ERR_SUCCESS; +} diff --git a/mupen64plus-input-raphnetraw/src/osal_preproc.h b/mupen64plus-input-raphnetraw/src/osal_preproc.h new file mode 100644 index 0000000..52a451c --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/osal_preproc.h @@ -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 diff --git a/mupen64plus-input-raphnetraw/src/plugin_back.c b/mupen64plus-input-raphnetraw/src/plugin_back.c new file mode 100644 index 0000000..7f81440 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/plugin_back.c @@ -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 +#include +#include "plugin_back.h" +#include "gcn64.h" +#include "gcn64lib.h" +#include "version.h" +#include "hexdump.h" + +#undef ENABLE_TIMING + +#ifdef ENABLE_TIMING +#include + +#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; iinf, 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; iinf.caps.n_raw_channels <= 0) + continue; + + for (j=0; jinf.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 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; ibiops; + + /* Skip adapters that do not have IO operations queued. */ + if (adap->n_ops <= 0) + continue; + +#ifdef TRACE_BLOCK_IO + for (i=0; in_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; in_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; +} diff --git a/mupen64plus-input-raphnetraw/src/plugin_back.h b/mupen64plus-input-raphnetraw/src/plugin_back.h new file mode 100644 index 0000000..d2aa859 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/plugin_back.h @@ -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__ + diff --git a/mupen64plus-input-raphnetraw/src/plugin_front.c b/mupen64plus-input-raphnetraw/src/plugin_front.c new file mode 100644 index 0000000..28bbac7 --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/plugin_front.c @@ -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 +#include +#include +#include +#include + +#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 + +#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 + +#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__ + diff --git a/mupen64plus-input-raphnetraw/src/requests.h b/mupen64plus-input-raphnetraw/src/requests.h new file mode 100644 index 0000000..9eccf0d --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/requests.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 diff --git a/mupen64plus-input-raphnetraw/src/version.h b/mupen64plus-input-raphnetraw/src/version.h new file mode 100644 index 0000000..ed73dec --- /dev/null +++ b/mupen64plus-input-raphnetraw/src/version.h @@ -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 */ +