pax_global_header00006660000000000000000000000064143663571760014534gustar00rootroot0000000000000052 comment=2129e942fdc2ee74d4d5f9c815dd204c45d9f4c1 mupen64plus-input-sdl-2.5.9+55+g2129e94/000077500000000000000000000000001436635717600171775ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/.gitattributes000066400000000000000000000007661436635717600221030ustar00rootroot00000000000000* text=auto # normal text files *.6 text AUTHORS text *.c text *.cfg text *.cht text *.conf text COPYING text *.cpp text *.def text *-license text *.h text *.html text *.ini text INSTALL text LICENSES text Makefile text *.py text README text RELEASE text *.S text *.sh text *.txt text *.ver text # windows specific text files *.sln text eol=crlf *.vcproj text eol=crlf *.vcxproj text eol=crlf *.vcxproj.filters text eol=crlf # binary files *.gz binary *.ttf binary cursor.tex binary font.tex binary mupen64plus-input-sdl-2.5.9+55+g2129e94/.github/000077500000000000000000000000001436635717600205375ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/.github/workflows/000077500000000000000000000000001436635717600225745ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/.github/workflows/build.yml000066400000000000000000000232221436635717600244170ustar00rootroot00000000000000name: SDL Input on: push: paths-ignore: - '**/*.md' - '.{gitattributes,gitignore,travis.yml}' - 'appveyor.yml,README' pull_request: paths-ignore: - '**/*.md' - '.{gitattributes,gitignore,travis.yml}' - 'appveyor.yml,README' workflow_dispatch: jobs: Linux: strategy: fail-fast: false matrix: include: - cc: GCC platform: x64 bits: 64 - cc: GCC platform: x86 bits: 32 - cc: Clang platform: x64 bits: 64 - cc: Clang platform: x86 bits: 32 name: Linux / ${{ matrix.cc }} / ${{ matrix.platform }} runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - name: Get build dependencies and arrange the environment run: | if [[ "${{ matrix.platform }}" == "x86" ]]; then sudo dpkg --add-architecture i386; fi sudo apt-get update sudo apt-get -y install libsdl1.2-dev libsdl2-dev if [[ "${{ matrix.platform }}" == "x86" ]]; then sudo apt-get --reinstall -y install gcc-multilib g++-multilib libc6 libc6-dev-i386 libsdl1.2debian:i386 libsdl2-2.0-0:i386 LINK="sudo ln -s -T" cd /usr/lib/i386-linux-gnu if ! [[ -f libSDL.so ]]; then ${LINK} libSDL-1.2.so.0.11.4 libSDL.so; fi if ! [[ -f libSDL2.so ]]; then ${LINK} libSDL2-2.0.so.0.18.2 libSDL2.so; fi cd /usr/include/SDL2 if ! [[ -f _real_SDL_config.h ]]; then ${LINK} ../x86_64-linux-gnu/SDL2/_real_SDL_config.h _real_SDL_config.h; fi fi sudo ldconfig - name: Build and related stuff run: | if [[ ${{ matrix.bits }} -eq 32 ]]; then export OPTFLAGS="-O2 -flto -mtune=pentium4"; else export OPTFLAGS="-O2 -flto -mtune=core2"; fi G_REV=$(git rev-parse --short HEAD) echo "G_REV=${G_REV}" >> "${GITHUB_ENV}" ORIG="$(pwd)" if [[ "${{ matrix.cc }}" == "GCC" ]]; then CC="gcc" CXX="g++" else CC="clang" CXX="clang++" fi if [[ ${{ matrix.bits }} -eq 32 ]]; then export PIC="1"; fi ${CC} --version echo "" git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core MSG="1.2" mkdir tmp for SDL in sdl sdl2 do echo "" echo ":: ${{ matrix.cc }} ${{ matrix.platform }} / SDL${MSG} ::" echo "" make -C projects/unix clean echo "" make CC="${CC}" CXX="${CXX}" BITS="${{ matrix.bits }}" SDL_CONFIG="${SDL}-config" -C projects/unix all -j4 echo "" make -C projects/unix install DESTDIR="${ORIG}/tmp" echo "" cd tmp/usr/local/lib/mupen64plus ls -gG *.so ldd mupen64plus-input-sdl.so MSG="2" cd "${ORIG}" done mkdir pkg if [[ "${CC}" == "gcc" ]]; then tar cvzf pkg/mupen64plus-input-sdl-${{ matrix.platform }}-g${G_REV}.tar.gz -C tmp/ "usr"; fi - name: Upload artifact uses: actions/upload-artifact@v3 with: name: mupen64plus-input-sdl-${{ matrix.platform }}-g${{ env.G_REV }} path: pkg/* if-no-files-found: ignore MSYS2: strategy: fail-fast: false matrix: include: - cc: GCC platform: x64 cross: x86_64 bits: 64 - cc: GCC platform: x86 cross: i686 bits: 32 name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.platform }} runs-on: windows-2019 defaults: run: shell: msys2 {0} steps: - uses: actions/checkout@v3 - uses: msys2/setup-msys2@v2 with: msystem: MINGW${{ matrix.bits }} update: true install: >- git libtool make mingw-w64-${{ matrix.cross }}-gcc mingw-w64-${{ matrix.cross }}-toolchain mingw-w64-${{ matrix.cross }}-SDL2 - name: Build and related stuff run: | if [[ ${{ matrix.bits }} -eq 32 ]]; then export OPTFLAGS="-O2 -flto -mtune=pentium4"; else export OPTFLAGS="-O2 -flto -mtune=core2"; fi echo "G_REV=$(git rev-parse --short HEAD)" >> "${GITHUB_ENV}" ORIG="$(pwd)" CC="gcc" CXX="g++" ${CC} --version echo "" git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core mkdir tmp echo "" echo ":: ${{ matrix.cc }} ${{ matrix.platform }} / SDL2 ::" echo "" make -C projects/unix clean echo "" make CC="${CC}" CXX="${CXX}" BITS="${{ matrix.bits }}" -C projects/unix all -j4 echo "" make -C projects/unix install PLUGINDIR="" SHAREDIR="" BINDIR="" MANDIR="" LIBDIR="" APPSDIR="" ICONSDIR="icons" INCDIR="api" LDCONFIG="true" DESTDIR="${ORIG}/tmp" echo "" ls -gG tmp/*.dll ldd tmp/mupen64plus-input-sdl.dll - name: Copy binaries, dependencies, etc... run: | mkdir pkg if [[ ${{ matrix.bits }} -eq 32 ]]; then LIBGCC="libgcc_s_dw2-1"; else LIBGCC="libgcc_s_seh-1"; fi for LIB in ${LIBGCC} libwinpthread-1 SDL2 do echo ":: Copying ${LIB}.dll" cp "/mingw${{ matrix.bits }}/bin/${LIB}.dll" pkg/ done if [ -d data ]; then cd data for DAT in * do echo ":: Copying ${DAT}" cp -r "${DAT}" ../pkg/ done fi cd ../tmp for BIN in *.dll do echo ":: Copying ${BIN}" cp "${BIN}" ../pkg/ done - name: Upload artifact uses: actions/upload-artifact@v3 with: name: mupen64plus-input-sdl-msys2-${{ matrix.platform }}-g${{ env.G_REV }} path: pkg/* MSVC: strategy: fail-fast: false matrix: include: - toolset: v143 platform: x64 vs: 2022 - toolset: v141_xp platform: x86 vs: 2019 name: Windows / MSVC ${{ matrix.toolset }} / ${{ matrix.platform }} runs-on: windows-${{ matrix.vs }} defaults: run: shell: cmd steps: - uses: actions/checkout@v3 - uses: microsoft/setup-msbuild@v1 # with: # vs-version: 16.11 - name: Build and related stuff run: | for /f "tokens=1" %%R in ('git rev-parse --short HEAD') do set "G_REV=%%R" echo G_REV=%G_REV%>> "%GITHUB_ENV%" set "ARCH=${{ matrix.platform }}" if [%ARCH%] == [x86] set "ARCH=Win32" echo. msbuild --version echo. git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ..\mupen64plus-core git clone --depth 1 https://github.com/mupen64plus/mupen64plus-win32-deps.git ..\mupen64plus-win32-deps echo. msbuild projects\msvc\mupen64plus-input-sdl.vcxproj /p:Configuration=Release;Platform=%ARCH%;PlatformToolset=${{ matrix.toolset }} echo. md backup copy projects\msvc\%ARCH%\Release\mupen64plus-input-sdl.dll backup\ dir backup\*.dll - name: Copy binaries, dependencies, etc... run: | md pkg cd pkg xcopy "..\backup" . xcopy "..\data" . copy "..\..\mupen64plus-win32-deps\SDL2-2.24.0\lib\${{ matrix.platform }}\*.dll" . - name: Upload artifact uses: actions/upload-artifact@v3 with: name: mupen64plus-input-sdl-msvc-${{ matrix.platform }}-g${{ env.G_REV }} path: pkg/* Nightly-build: runs-on: ubuntu-latest needs: [Linux, MSYS2, MSVC] if: github.ref == 'refs/heads/master' steps: - uses: actions/checkout@v3 - name: Download artifacts uses: actions/download-artifact@v3 with: path: binaries - name: Get some tools run: | sudo apt-get update sudo apt-get -y install hashdeep - name: Creating new artifacts and update nightly-build run: | mkdir pkg cd binaries for BIN in * do cd "${BIN}" if [[ "${BIN:22:4}" == "msys" ]]; then echo ":: Creating ${BIN}.zip" zip -r "../../pkg/${BIN}.zip" * elif [[ "${BIN:22:4}" == "msvc" ]]; then echo ":: Creating ${BIN}.zip" zip -r "../../pkg/${BIN}.zip" * else echo ":: Recovering ${BIN}.tar.gz" mv *.tar.gz ../../pkg/ fi cd .. done cd ../pkg echo "" for BIN in * do ls -gG ${BIN} tigerdeep -l ${BIN} >> ../${BIN:0:21}.tiger.txt sha256sum ${BIN} >> ../${BIN:0:21}.sha256.txt sha512sum ${BIN} >> ../${BIN:0:21}.sha512.txt done mv ../*.tiger.txt . mv ../*.sha*.txt . echo "" echo "TIGER:" cat *.tiger.txt echo "" echo "SHA256:" cat *.sha256.txt echo "" echo "SHA512:" cat *.sha512.txt echo "" git tag -f nightly-build git push -f origin nightly-build - name: Nightly-build uses: ncipollo/release-action@v1 with: prerelease: true allowUpdates: true removeArtifacts: true replacesArtifacts: false tag: nightly-build artifacts: pkg/* mupen64plus-input-sdl-2.5.9+55+g2129e94/.gitignore000066400000000000000000000001061436635717600211640ustar00rootroot00000000000000/projects/unix/_obj*/ /projects/unix/mupen64plus-input-sdl*.so /build/mupen64plus-input-sdl-2.5.9+55+g2129e94/.travis.yml000066400000000000000000000065661436635717600213250ustar00rootroot00000000000000sudo: required dist: xenial language: cpp compiler: - gcc - clang addons: apt: packages: - git - libsdl1.2-dev - libsdl2-dev before_install: - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core env: - PLUGINDBG=0 - PLUGINDBG=1 script: - make -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && LDFLAGS="-Wl,--no-add-needed -Wl,--no-undefined" OPTFLAGS="-O2" make SDL_CONFIG=sdl-config CC="${CC}" CXX="${CXX}" -j$(nproc) -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 all - make -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && LDFLAGS="-Wl,--no-add-needed -Wl,--no-undefined" OPTFLAGS="-O2" make SDL_CONFIG=sdl2-config CC="${CC}" CXX="${CXX}" -j$(nproc) -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 all # extra mxe build entries matrix: include: - env: - MXE_CPU=i686 - PATH="/usr/lib/mxe/usr/bin/:$PATH" before_install: - curl -sSL "https://mirror.mxe.cc/repos/apt/client-conf/mxeapt.gpg" | sudo -E apt-key add - - echo "deb https://mirror.mxe.cc/repos/apt xenial main" | sudo tee -a /etc/apt/sources.list - sudo apt-get update -qq - sudo apt-get -y --allow-unauthenticated install mxe-i686-w64-mingw32.shared-gcc - sudo apt-get -y --allow-unauthenticated install mxe-i686-w64-mingw32.shared-sdl2 - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core script: - make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" SDL_CONFIG="${MXE_CPU}-w64-mingw32.shared-sdl2-config" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" SDL_CONFIG="${MXE_CPU}-w64-mingw32.shared-sdl2-config" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 -j$(nproc) all - env: - MXE_CPU=x86_64 - PATH="/usr/lib/mxe/usr/bin/:$PATH" before_install: - curl -sSL "https://mirror.mxe.cc/repos/apt/client-conf/mxeapt.gpg" | sudo -E apt-key add - - echo "deb https://mirror.mxe.cc/repos/apt xenial main" | sudo tee -a /etc/apt/sources.list - sudo apt-get update -qq - sudo apt-get -y --allow-unauthenticated install mxe-x86-64-w64-mingw32.shared-gcc - sudo apt-get -y --allow-unauthenticated install mxe-x86-64-w64-mingw32.shared-sdl2 - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core script: - make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" SDL_CONFIG="${MXE_CPU}-w64-mingw32.shared-sdl2-config" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" SDL_CONFIG="${MXE_CPU}-w64-mingw32.shared-sdl2-config" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 -j$(nproc) all mupen64plus-input-sdl-2.5.9+55+g2129e94/AUTHORS000066400000000000000000000002451436635717600202500ustar00rootroot00000000000000Original author: Gregor Anich Subsequent authors: many people from the Mupen64Plus team have worked on this code. See the LICENSES file for more details. mupen64plus-input-sdl-2.5.9+55+g2129e94/COPYING000066400000000000000000000431271436635717600202410ustar00rootroot00000000000000 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. mupen64plus-input-sdl-2.5.9+55+g2129e94/INSTALL000066400000000000000000000014671436635717600202400ustar00rootroot00000000000000Mupen64Plus-Input-SDL INSTALL ----------------------------- This text file was written to explain the installation process of the Mupen64Plus-Input-SDL 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-SDL 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= mupen64plus-input-sdl-2.5.9+55+g2129e94/LICENSES000066400000000000000000000457261436635717600203450ustar00rootroot00000000000000Mupen64Plus-input-sdl LICENSE ----------------------------- Mupen64Plus-input-sdl is licensed under the GNU General Public License version 2. The authors of Mupen64Plus-input-sdl are: * 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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU 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. mupen64plus-input-sdl-2.5.9+55+g2129e94/README.md000066400000000000000000000226171436635717600204660ustar00rootroot00000000000000![Logo](https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Mupen64plus.svg/127px-Mupen64plus.svg.png) # https://mupen64plus.org/wiki/index.php/ControllerSetup # Mupen64plus-input-sdl README v2.0 The latest documentation for this plugin can be found in wiki format at: https://mupen64plus.org/wiki/index.php/KeyboardSetup https://mupen64plus.org/wiki/index.php/ControllerSetup The format and usage of this plugin's "mupen64plus.cfg" configuration options can be found at: https://mupen64plus.org/wiki/index.php/Mupen64Plus_Plugin_Parameters#Input-SDL ## Notes about usage of SDL input plugin: - If one of the enabled controllers has the "mouse" general-purpose config parameters set to True, the plugin will hide the mouse cursor and 'grab' the mouse pointer. The user may press the Left Control and Alt keys together to toggle the mouse cursor on and off. - If X/Y analog axes are mapped to keys, a plain keypress will simulate the joystick being pressed all the way to the edge. To decrease the amount of simulated joystick deflection, the user may press Right Control, Right Shift, or Right Ctrl+Right Shift. ## Default Keyboard interface: ``` Analog Pad is "Arrow Keys" C Up/Left/Down/Right are "I", "J", "K", "L" DPad Up/Left/Down/Right are "W", "A", "S", "D" Z trig is "z" key L and R trigs are "x" and "c" Start is "Enter" ("Return") A is "left shift" B is "left control" Select Mempack = "," Select Rumblepack = "." ``` ## Special modifier keys - Right-shift key: reduce amplitude of analog joystick X/Y axes by 25% - Right-control key: reduce amplitude of analog joystick X/Y axes by 50% - Left-Control + Left-Alt keys: grab or un-grab the mouse cursor (only if mouse control is enabled) - Left-Windows key: do not auto-center joystick X/Y axes (only when mouse control is enabled) ## Notes for supported joysticks for auto-configuration: 1) Jess Tech Rumble Pad (Saitek Rumble) The left D-pad is mapped to the D-pad; The joystick is mapped to the left joystick of the gamepad; the C buttons are mapped to the gampad's right joystick. Start button is mapped to start; the A-button is mapped to the lowest button on the gamepad's right front; the B-button to the left button (buttons marked 3 and 1 on my gamepad). The L and R buttons are mapped to the lower left and right rear triggers; the Z button is mapped to the left upper rear trigger. All other buttons are unused. 2) Logitech Dual Action gamepad, Logitech Cordless Rumblepad 2: The digital pad maps to the N64 d-pad. The left analog stick maps to the N64 analog stick. The right analog stick maps to the C-buttons, and the buttons 2 and 1 map to A and B. Button 4 is the Z trigger, and the top shoulder buttons map to the left and right N64 triggers. Button 10 is the start button. The bottom shoulder buttons select the memory pack or rumble pak. 3) Logitech Logitech(R) Precision(TM) Gamepad, Gravis GamePad Pro USB I came up with what I see as one of the few decent configurations (SSB aside) since it allows access to everything but the dpad. A is L1, B is R1, Z is L2, R is R2, L is select. C buttons are the four buttons, and the dpad acts as the joystick. Not the most orthodox, but it works well. 4) Microsoft Xbox 360 controller and clones: ``` N64 -> Xbox 360: analog stick -> left stick digital pad -> directional pad R -> right bumper, right trigger L -> left bumper Z -> left trigger A -> A B -> X start -> start C buttons -> right stick C left -> Y (additionally to right stick) C down -> B (additionally to right stick) mempak -> none for now rumblepak -> none for now ``` As discussed in issue #478 Xbox 360 controllers should follow the above mapping convention. If you want to add a Xbox 360 controller clone please stick to it. As your clone might has different button naming, you can find Xbox 360 controller button names at https://en.wikipedia.org/wiki/File:360_controller.svg Keys that are still unbound are back (aka. select) and left/right stick button clicks. Those might be used for mempack and rumblepak toggles. 5) MP-8866 Dual USB Joypad: This is a USB adapter for PlayStation controllers (2). ``` D-Pad: hat(0) L-Stick: x:0, y:1 R-Stick: x:2, y:3 Triangle: button(0) Circle: button(1) Cross: button(2) Square: button(3) L2: button(4) R2: button(5) L1: button(6) R1: button(7) Start: button(8) Select: button(9) L3: button(10) R3: button(11) Note: This is when analog mode is selected. If analog is off then D-Pad becomes axes 0/1 and both sticks are disabled (including L3/R3). ``` 6) Nintendo Wiimote Classic I am on a Mac and used https://code.google.com/p/wjoy/ successfully to connect my Wiimote + Classic Controller. This is my working Wiimote + Class Controller configuration. You use the Classic Controller for all play, the Wiimote serves only as a host for the Classic Controller. I have swapped the left analog stick set as the C-Buttons and the right analog stick set as the N64 Analog (Y-Axis / X-Axis). This makes playing FPS titles like Perfect Dark a bit more reasonable for me. You can easily switch them by swapping 2 with 4 and 3 with 5 in the axis() sections below. ``` N64 -> Classic Controller Z -> L R -> R L -> ZL A -> A B -> B Start -> Start (+) DPad -> DPad CButtons -> Left Analog Analog -> Right Analog Mempak switch -> Home Rumblepak switch -> Select (-) ``` 7) N64 controller: All controls are mapped to their proper place on the N64 controller with an Adaptoid or custom hardware with Gamecon driver. Rumble and Memory packs can be selected with the 'r' and 'm' keys, respectively. 8) Playstation 3 Controller: ``` Left analog stick - analog stick Right analog stick - C-pad D-Pad - D-Pad Cross - A Square - B L1 / R1 - L / R L2 - Z Start - Start ``` 9) SAITEK P880: The gamepad doesnt have enough keys to real assign all buttons. The second analog stick can be used as button by pushing him insight. General Configuration: Digital Pad was used as N64 digital pad, First analog stick was used as N64 Analog stick. The red button was used as N64 Start button. L and R was used for N64 L and R. Second analog stick axes was used for N64 C buttons and second "analog stick button" was used for C-down. The first column of keys was used for A and B and the second and third row was used for C-Buttons - except for the Button next to the A button which would be C-Down but got the Z button. 10) Xbox Gamepad (userspace driver) I created an Input Config for a Xbox 360 controller running with xboxdrv on a Linux system (http://pingus.seul.org/~grumbel/xboxdrv/). ``` Z = Left shoulder button L = Left shoulder trigger A = A Button B = X Button ``` everything else should be obvious. Unfortunately, you will also have to make some configuration to xboxdrv to make this work properly. xboxdrv has to be started with the following config file. The "-as-button" options make sure that the D- Pad and Trigger are emulated as buttons and the deadzone options make the C buttons work much better. The guide=KEY_ESC allows you to quit the emulator by pressing the guide key on the controller. This is obviously just nice-to-have and not actually neccessary for the config to work. ``` [xboxdrv] silent=true trigger-as-button=true dpad-as-button=true [ui-buttonmap] guide=KEY_ESC [axismap] x2^deadzone:27000 y2^deadzone:27000 ``` 11) Saitek Cyborg V.3 Rumble Pad (aka Saitek PS2700) Honestly, it's one of the best pads that I've used in a long time, so thought I'd contribute this quick config. Basically, Dpad and Analog sticks are unchanged, C-buttons are mapped to the right analog stick, L-R triggers are L1 and R1, Z is mapped to R2, A + B are mapped to X and Square, respectively, start is mapped to the Home button, and Triangle, Square, L2, Start, Select, and the Analog triggers are unused, since it's not intuitive to use them for what's left. 12) Arsenal Gaming PS3 controller (aka. "Gasia Co.,Ltd PS(R) Gamepad") ``` N64 Start = PS3 Start N64 D-pad = PS3 D-pad N64 joystick = PS3 left joystick N64 C buttons = PS3 right joystick N64 A = PS3 X N64 B = PS3 Square N64 R = PS3 R1 N64 L = PS3 L1 N64 Z = PS3 L2 Rumble pack swap = PS3 Triangle Memory pack swap = PS3 Circle ``` 13) Google Stadia controller The Google Stadia controller can be used as a HID joystick by plugging it into a computer via USB-C or USB-C to USB-A. ``` N64 Start = Stadia Logo/Start N64 D-pad = Stadia D-pad N64 joystick = Stadia Left Analog Joystick N64 C buttons = Stadia Right Analog Joystick N64 A = Stadia A N64 B = Stadia B N64 R = Stadia Right Bumper N64 L = Stadia Left Bumper N64 Z = Stadia Left Trigger Rumble pack swap = Stadia Y Memory pack swap = Stadia X ``` 14) PS4 Controller for Linux The non-Linux configuration for the Sony Interactive Entertainment Wireless Controller had incompatible bindings. Z was right analog stick up. I made a list of the ps4 buttons: ``` button 0 = cross button 1 = circle button 2 = triangle button 3 = square button 4 = l1 button 5 = r1 button 6 = l2 button 7 = r2 button 8 = share button 9 = options button 10 = ps button 11 = l3 button 12 = r3 axis 0- = lstick left axis 0+ = lstick right axis 1- = lstick up axis 1+ = lstick down axis 2+ = l2 axis 2- = l2 axis 3- = rstick left axis 3+ = rstick right axis 4- = rstick up axis 4+ = rstick down axis 5+ = r2 axis 5- = r2 hat 0 Right = Right hat 0 Left = Left hat 0 Down = Down hat 0 Up = Up ``` mupen64plus-input-sdl-2.5.9+55+g2129e94/RELEASE000066400000000000000000000167661436635717600202220ustar00rootroot00000000000000SDL Input plugin for Mupen64Plus -------------------------------- Mupen64Plus-input-sdl v2.5.9 - February 10, 2019 ------------------------------------------------ - *** BETA RELEASE *** For Testing Only *** Mupen64Plus-input-sdl v2.5 - April 26, 2015 ------------------------------------------- - use SDL1.2 keysyms in the mupen64plus.cfg file Input section even when built against SDL2, with keysym converter - SDL2: support for mapping mouse to controller analog x/y - SDL2: improve/simplify rumble effect code - use prioritization to decide among multiple matching auto-config sections (for SDL2 / XInput) - New auto-config sections for: Wiimote Classic, Wii U Gamecube / Pro, MS SideWinder GamePad Pro, 17 others - When Mouse=True but pointer is un-grabbed, fall back to joystick settings for analog x/y - Prevent mouse/trackpad auto-centering behavior by pressing left-Windows key Mupen64Plus-input-sdl v2.0 - July 4, 2013 ----------------------------------------- - re-write auto-configuration logic to be more user friendly. Add new 'mode' parameter. - support for 6 new joysticks - work-around for buggy xboxdrv which results in no rumble - bugfix: crash when rumble used with controller #4 - support to build against SDL2 - Project files for Visual Studio 2012 - Makefile changes - add support for PowerPC and MinGW32 builds - add cross-compiling support to build Win32 executables (MXE) under Linux Mupen64Plus-input-sdl v1.99.5 - March 10, 2012 ------------------------------------------------- - Improved input setup behavior (auto-config) to make some use cases more friendly - Updated input plugin for new Mupen64plus 2.0 API versioning scheme - Added version number to SDL Input plugin parameters - Add new parameter for mouse sensitivity, handle mouse movement differently so mouse is easier to use as controller - New auto-configuration for controllers: - raphnet technologies GC/N64 usb converter - Logitech Chillstream Controller - Jess Tech Colour Rumble - Xbox 360 linux userspace driver - Generic X-Box pad - Saitek P2900 Wireless Pad - Jess Tech USB 4-Axis 12-Button Gamepad - bugfix: #392 - when switching between rumble pak and memory pak, simulate removing the pack, waiting 1 second, then inserting the new one - bugfix: #424 - problem with USB devices supporting multiple controllers per device - bugfix: #409 - PS3 controller not auto-detected in Gentoo when connected via bluetooth - bugfix: correctly handle USB devices with multiple game pads, from Peter Helbing - makefile fixes and improvements Mupen64Plus-input-sdl v1.99.4 - November 22, 2010 ------------------------------------------------- - Bugfix: Do configuration during PluginStart(), so GUI will see defaults (auto-configured) the first time it is run - Move axis value reducers to right shift and right ctrl, to avoid conflict with A/B buttons - New feature: extra deadzone parameter in axis() config parameter clause when mapping an analog joystick axis to an N64 button - many new joystick auto-configurations - makefile fixes and improvements Mupen64Plus-input-sdl v1.99.3 - February 13, 2010 ------------------------------------------------- - New feature: auto-configuration uses an .ini file instead of hard-coding the controllers in the source code - New controller auto-configurations: - Original X-Box (and compatible clones) - HuiJia USB GamePad - USB Human(2p) Interface Device - sync with core<-->plugin API change for RomOpen() - Bugfix: controller pak was fixed at startup, switching b/w mempak and rumblepak did not work - Bugfix: Xbox 360 and PS3 controllers need slightly different names under OSX - Makefile improvements: - plugin must be linked with CC instead of LD because 'sdl-config --libs' can give "-Wl,-rpath" - added OS type GNU/kFreeBSD Mupen64Plus-input-sdl v1.99.2 - January 6, 2010 ------------------------------------------------- - new feature: added MSVC8 project file, minor code refactoring for VC compatibility - added auto-configuration for: - Xbox 360 Wireless Receiver - PS3 controller - Jess Tech Dual Analog Pad - Makefile improvements: - throw error if OS/CPU not supported - use DESTDIR in install/uninstall paths - Allow user-specified CC/CXX/LD paths Mupen64Plus-input-sdl v1.99.1 - December 14, 2009 ------------------------------------------------- - New feature: Joystick/Keyboard auto-configuration - New feature: deadzone and peak analog joystick values are now configurable - Converted to new Mupen64Plus 2.0 API - Refactored build system to separate source and object files - Major code cleanup: mouse movement and analog axis code was terrible, removed non-standard data types - Improved debug messages - bugfix: mapping the X/Y analog sticks to keypresses didnt work - bugfix: LeftCtrl-LeftAlt key command when mouse is enabled to now toggles between grabbing and releasing the mouse pointer Mupen64Plus Pre-2.0 ------------------- - numerous fixes and enhancements were made to this code during the mupen64plus project before v2.0 Original Blight Changelog ------------------------- 0.0.10: - when the keyboard is used to control an axis left shift and left control can be pressed to change the axis movement. shift reduces the movement by 25%, control reduces it by 50%, control and shift together reduce the movement by 75% - when the mouse is used left ctrl + left alt can be used to release the mouse, clicking into the window will grab the mouse again. 0.0.9: - import new version of SDL_tff (2.0.7) - when the keyboard is used to control an axis left shift can be pressed to change the axis movement to 25% of the original value 0.0.8-b: - fixed bug which didn't put analog axis back into default position when a key which was assigned to it was pressed and released again 0.0.8: - fixed a stupid bug which disabled analog axis 0.0.7-b: - sdl config dialog: input event queue is flushed before a button/whatever is assigned 0.0.7: mouse support! - mouse support (x and y axis automatically mapped to analog stick, mouse buttons mapable onto n64 buttons) 0.0.6: - keyboard and gamepad can be used at the same time (the keyboard will work always, even if you choose another device. if you want to use only the keyboard select keyboard as device 0.0.5: - sdl about dialog - fixed config routine (incorrectly read X- axis) - fixed small sdl config dialog drawing bug - corrected config dialog c button labels 0.0.4: joystick hat support - fixed a segfault when the rom was closed - less axis sensibility when assigning a new mapping (changed from 10 to 50 percent) - less sensibility for axis mapped to buttons (changed from 10 to 20 percent) - it's possible to clear assignments and cancel an assignment - joystick hat support (mapable to axis and buttons) - fixed some bugs in the input reading function - fixed all compiler warnings 0.0.3: - no more need for the SDL_image library - no longer link against gtk library 0.0.2-2: - fixed a bug which didn't allow to assign anything to a pad button 0.0.2-1: *BROKEN* - help for the SDL gui 0.0.2: new SDL config dialog! *BROKEN* - fixed a bug where it wouldn't open the joystick device if you change the controller - sdl config dialog - some other lil' fixes 0.0.1: made some small fixes - now it's possible to map an axis (i.e. X Axis +) to a button (i.e. DPAD_UP) - configuration is saved and displayed for all devices - changed the config dialog a bit (bigger text entries, bigger device combo) - new config file format 0.0.1b: initial version - should work :-) mupen64plus-input-sdl-2.5.9+55+g2129e94/appveyor.yml000066400000000000000000000020121436635717600215620ustar00rootroot00000000000000version: 1.0.{build} image: Visual Studio 2022 skip_commits: files: - '**/*.md' - .github/ - data/* - .gitattributes - .gitignore - .travis.yml - README branches: except: - nightly-build configuration: - Release platform: - Win32 - x64 before_build: - git tag --delete nightly-build - git clone --depth 1 https://github.com/mupen64plus/mupen64plus-win32-deps.git ..\mupen64plus-win32-deps - git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ..\mupen64plus-core build_script: - msbuild projects\msvc\mupen64plus-input-sdl.vcxproj /p:Configuration=%configuration%;Platform=%platform% after_build: - ps: $env:rev1 = git describe --tags - set rev2=%platform% - if "%rev2%"=="Win32" set rev2=x86 - set filepkg=mupen64plus-input-sdl_v%rev1%_%rev2% - cd projects\msvc\%platform%\%configuration% - copy *.dll ..\..\..\..\data - cd ..\..\..\..\data - 7z a -t7z ..\build\%filepkg%.7z * artifacts: - path: build\$(filepkg).7z name: $(filepkg) mupen64plus-input-sdl-2.5.9+55+g2129e94/data/000077500000000000000000000000001436635717600201105ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/data/InputAutoCfg.ini000066400000000000000000001422461436635717600231720ustar00rootroot00000000000000; InputAutoCfg.ini for Mupen64Plus SDL Input plugin [Keyboard] plugged = True mouse = False DPad R = key(100) DPad L = key(97) DPad D = key(115) DPad U = key(119) Start = key(13) Z Trig = key(122) B Button = key(306) A Button = key(304) C Button R = key(108) C Button L = key(106) C Button D = key(107) C Button U = key(105) R Trig = key(99) L Trig = key(120) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = key(276,275) Y Axis = key(273,274) ;Dragonbox Pyra [pyraInput Gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) DPad L = axis(4-) DPad D = axis(5+) DPad U = axis(5-) Start = button(11) Z Trig = button(6) B Button = button(1) A Button = button(3) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(9) L Trig = button(8) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Austgame PS to USB convert cable] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(8) Z Trig = button(4) B Button = button(3) A Button = button(2) C Button R = button(1) C Button L = button(0) C Button D = button(5) C Button U = axis(3-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [BDA Pro Ex] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) DPad L = axis(4-) DPad D = axis(5+) DPad U = axis(5-) Start = button(9) Z Trig = button(7) B Button = button(2) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Boom Smart Joy Converter [HID 6666:0667] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(15) DPad D = button(14) DPad U = button(12) Start = button(11) Z Trig = button(10) B Button = button(4) A Button = button(5) C Button R = button(1) C Button L = button(3) C Button D = button(2) C Button U = button(0) R Trig = button(7) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; EasySMX ESM-9100 Wired Game Controller [Controller (GAME FOR WINDOWS >)] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(1) A Button = button(0) C Button R = axis(4+) C Button L = axis(4-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Cyborg V.3 Rumble Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) DPad L = axis(4-) DPad D = axis(5+) DPad U = axis(5-) Start = button(12) Z Trig = button(7) B Button = button(0) A Button = button(1) C Button R = button(8) axis(2+) C Button L = button(3) axis(2-) C Button D = button(2) axis(3+) C Button U = button(9) axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [DragonRise Inc. Generic USB Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = key(275) axis(0+) DPad L = key(276) axis(0-) DPad D = key(274) axis(1+) DPad U = key(273) axis(1-) Start = button(9) Z Trig = button(4) B Button = button(3) A Button = button(2) C Button R = button(7) axis(3+) C Button L = button(6) axis(3-) C Button D = button(1) axis(4+) C Button U = button(0) axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; FuSa is a homebrew program which allows a PSP to be used as a gamepad [FuSa FuSa GamePad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = DPad L = DPad D = DPad U = Start = button(7) Z Trig = button(4) B Button = button(2) A Button = button(0) C Button R = hat(0 Right) C Button L = hat(0 Left) C Button D = hat(0 Down) C Button U = hat(0 Up) R Trig = button(5) L Trig = button(3) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; "Super Joy Box 13" USB adaptor for a Gamecube controller [GameCube to USB box 1] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = button(6) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3-) C Button U = axis(3+) R Trig = axis(5+) L Trig = axis(4+) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Gasia Co.,Ltd PS(R) Gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = key(275) axis(0+) hat(0 Right) DPad L = key(276) axis(0-) hat(0 Left) DPad D = key(274) axis(1+) hat(0 Down) DPad U = key(273) axis(1-) hat(0 Up) Start = button(9) Z Trig = button(6) B Button = button(3) A Button = button(2) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = button(1) Rumblepak switch = button(0) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; raphnet technologies USB converter (http://www.raphnet-tech.com/) [GC/N64_USB] [GC/N64 to USB, v2.9] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(12) DPad D = button(11) DPad U = button(10) Start = button(3) Z Trig = button(2) B Button = button(1) A Button = button(0) C Button R = button(7) C Button L = button(6) C Button D = button(5) C Button U = button(4) R Trig = button(9) L Trig = button(8) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; raphnet technologies USB converter, v3 series (http://www.raphnet-tech.com/) [raphnet technologies GC/N64 to USB] [raphnet technologies N64 to USB] [raphnet technologies Dual N64 to USB] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(12) DPad D = button(11) DPad U = button(10) Start = button(3) Z Trig = button(2) B Button = button(1) A Button = button(0) C Button R = button(9) C Button L = button(8) C Button D = button(7) C Button U = button(6) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Retrolink N64 USB clone [Generic USB Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(5+) DPad L = axis(5-) DPad D = axis(6+) DPad U = axis(6-) Start = button(9) Z Trig = button(7) B Button = button(8) A Button = button(6) C Button R = button(1) C Button L = button(3) C Button D = button(2) C Button U = button(0) R Trig = button(5) L Trig = button(4) Mempak switch = key(109) Rumblepak switch = key(114) Y Axis = axis(1-,1+) X Axis = axis(0-,0+) ; gioteck VX2PS3-21 RF Wireless Controller [Goodbetterbest Ltd PC USB Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 Mempak switch = button(7) Rumblepak switch = C Button D = button(1) axis(3+) C Button L = axis(2-) Z Trig = button(6) Start = button(9) Y Axis = axis(1-,1+) DPad U = hat(0 Up) C Button U = button(0) axis(3-) A Button = button(2) DPad D = hat(0 Down) X Axis = axis(0-,0+) R Trig = button(5) DPad R = hat(0 Right) B Button = button(3) DPad L = hat(0 Left) C Button R = axis(2+) L Trig = button(4) [GreenAsia Inc. USB Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(1) B Button = button(3) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [GS gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(2) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Guillemot Corporation DA Leader] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(12) Z Trig = button(11) B Button = button(1) A Button = button(3) C Button R = button(6) C Button L = button(4) C Button D = button(7) C Button U = button(5) R Trig = button(2) L Trig = button(0) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [ipega media gamepad controller] plugged = True mouse = False DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(11) Z Trig = button(6) B Button = button(3) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = axis(4+) L Trig = axis(5+) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [ipega gamepad controller] plugged = True mouse = False DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(2) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Jess Tech Dual Analog Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Win32: Colour Rumble Pad] [Jess Tech Colour Rumble Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(4) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(7) L Trig = button(5) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Jess Tech USB 4-Axis 12-Button Gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(4) Z Trig = button(5) B Button = button(8) A Button = button(9) C Button R = button(1) C Button L = button(3) C Button D = button(2) C Button U = button(0) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Jess Technology Co., Ltd. USB Game Controllers] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(0+) DPad L = axis(0-) DPad D = axis(1+) DPad U = axis(1-) Start = button(9) Z Trig = button(3) B Button = button(0) A Button = button(2) C Button R = axis(5+) C Button L = axis(5-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = button(7) Rumblepak switch = button(5) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; X-box controllers and compatible clones [Logitech Chillstream Controller] [Logic3 Controller] [HORIPAD ONE] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = button(6) Rumblepak switch = button(8) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Logitech Cordless Rumblepad 2] [Logitech Cordless RumblePad 2] [Logitech RumblePad 2 USB] [Logitech Dual Action] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) hat(0 Right) DPad L = axis(4-) hat(0 Left) DPad D = axis(5+) hat(0 Down) DPad U = axis(5-) hat(0 Up) Start = button(9) Z Trig = button(6) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = button(8) Rumblepak switch = button(7) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Logitech Gamepad F310] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(5+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = button(1) Rumblepak switch = button(3) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Logitech Gamepad F710] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = button(6) Rumblepak switch = axis(5+) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Logitech Logitech(R) Precision(TM) Gamepad] [Gravis GamePad Pro USB] plugged = True mouse = False AnalogDeadzone = 100,100 AnalogPeak = 32768,32768 DPad R = axis(0+) DPad L = axis(0-) DPad D = axis(1+) Dpad U = axis(1-) Start = button(9) Z Trig = button(6) B Button = button(5) A Button = button(4) C Button R = button(2) C Button L = button(0) C Button D = button(1) C Button U = button(3) R Trig = button(7) L Trig = button(8) Mempack switch = Rumblepak Switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Logitech WingMan Action Pad] [Logitech Inc WingMan RumblePad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(15) DPad D = button(14) DPad U = button(12) Start = button(8) Z Trig = button(6) B Button = button(3) A Button = button(0) C Button R = button(2) C Button L = button(4) C Button D = button(1) C Button U = button(5) R Trig = button(7) L Trig = Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Mayflash GC Controller Adapter 4-Port] ; Mayflash Gamecube 4-Port Controller Adapter (for PC & Wii U USB) - With one Gamecube gamepad(s) connected ; this is a 4-port USB device. The ports from left to right are p1, p2, p3, p4. ; This is configured for Toki no Ocarina, therefore the L trig represents the Z trig and vice versa plugged = True mouse = False AnalogDeadzone = 128,128 AnalogPeak = 28000,28000 DPad R = hat(4 Right) DPad L = hat(4 Left) DPad D = hat(4 Down) DPad U = hat(4 Up) Start = button(36) ; L Trig is mapped to Z Z Trig = axis(12+) B Button = button(8) A Button = button(4) C Button R = axis(20+) C Button L = axis(20-) C Button D = axis(8+) C Button U = axis(8-) R Trig = axis(16+) L Trig = button(28) Mempak switch = Rumblepak switch = Y Axis = axis(0-,0+) X Axis = axis(4-,4+) [Mega World Thrustmaster dual analog 3.2] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(8) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(6) L Trig = button(4) Mempak switch = button(5) Rumblepak switch = button(7) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Mega World USB Game Controllers] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [MP-8866 Dual USB Joypad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(8) Z Trig = button(6) B Button = button(3) A Button = button(2) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(7) L Trig = button(4) Mempak switch = button(10) Rumblepak switch = button(11) Y Axis = axis(1-,1+) X Axis = axis(0-,0+) ; Nes30 Pro Controller ; NB - this maps Z trigger to button Y ; Select, L2 and R2 are unmapped [Bluetooth Wireless Controller ] [8Bitdo NES30 Pro] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(6+) DPad L = axis(6-) DPad D = axis(7+) DPad U = axis(7-) Start = button(11) Z Trig = button(4) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Linux: Microsoft X-Box 360 pad] [Linux: Xbox 360 Wireless Receiver (XBOX)] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+,24000) C Button L = axis(3-,24000) button(3) C Button D = axis(4+,24000) button(1) C Button U = axis(4-,24000) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Multilaser PS2 Generic Controller JS030 [Linux: Microntek USB Joystick] [Win32: USB Network Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(6) B Button = button(3) A Button = button(2) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Microsoft X-Box 360 pad] [Microsoft X-Box One pad] [Win32: Controller (XBOX 360 For Windows)] [Win32: XBOX 360 For Windows (Controller)] [Win32: XBOX 360 For Windows] [Xbox 360 Wireless Receiver] [Linux: Xbox Gamepad (userspace driver)] [Afterglow Gamepad for Xbox 360] [Controller (Xbox One For Windows)] [Controller (XEOX Gamepad)] [Xbox 360 Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(4+,24000) C Button L = axis(4-,24000) C Button D = axis(3+,24000) C Button U = axis(3-,24000) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) # mappings for use with the TattieBogle driver under OSX, given in googlecode.com issue #630 [OSX: Wireless 360 Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(3) DPad L = button(2) DPad D = button(0) DPad U = button(1) Start = button(4) Z Trig = axis(5+) B Button = button(13) A Button = button(11) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(9) L Trig = button(8) Mempak switch = "" Rumblepak switch = "" X Axis = axis(0-,0+) Y Axis = axis(1-,1+) # For Xbox One controllers in Bluetooth mode [Xbox Wireless Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(11) Z Trig = button(7) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = axis(4+) L Trig = axis(5+) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) # from the Google Group, with the tattiebogle driver 0.15 beta 3 under El Capitan 10.11.1 [OSX: Xbox 360 Wired Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(14) DPad L = button(13) DPad D = button(12) DPad U = button(11) Start = button(8) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = "" Rumblepak switch = "" X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; ACRUX Gamepad (USB ID: 1a34:0802), a Xbox 360 controller clone aviable under ; various brands (e.g. techsolo TG-30) [USB GAMEPAD 8116] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = axis(4-) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) button(3) C Button D = axis(2+) button(1) C Button U = axis(2-) R Trig = button(5) axis(4+) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [XInput: Microsoft X-Box 360 pad] [XInput: Controller (XBOX 360 For Windows)] [XInput: XBOX 360 For Windows (Controller)] [XInput: XBOX 360 For Windows] [XInput: Xbox 360 Wireless Receiver] [XInput: XInput Controller #] [Xbox One S Controller] [Xbox One Elite Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) button(3) C Button D = axis(4+) button(1) C Button U = axis(4-) R Trig = button(5) axis(5+) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ;Snakebyte PS3-style USB controller [MY-POWER CO.,LTD. 2In1 USB Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(2) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [N64 controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(0) B Button = button(2) A Button = button(1) C Button R = button(4) C Button L = button(5) C Button D = button(3) C Button U = button(6) R Trig = button(8) L Trig = button(7) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Nintendo Wiimote Classic] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(23) DPad L = button(22) DPad D = button(21) DPad U = button(20) Start = button(17) Z Trig = button(24) B Button = button(14) A Button = button(13) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(25) L Trig = button(26) Mempak switch = button(16) Rumblepak switch = button(15) X Axis = axis(4-,4+) Y Axis = axis(5-,5+) [Nintendo Wii Remote Pro Controller] plugged = True mouse = False AnalogDeadzone = 3500,3500 AnalogPeak = 22000,22000 DPad R = button(16) DPad L = button(15) DPad D = button(14) DPad U = button(13) Start = button(9) Z Trig = button(6) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = button(2) Rumblepak switch = button(3) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [OUYA Game Controller] plugged = True mouse = False Mempak switch = Rumblepak switch = DPad U = button(8) DPad D = button(9) DPad L = button(10) DPad R = button(11) Start = button(7) Z Trig = button(12) A Button = button(0) B Button = button(1) C Button U = axis(4-) C Button D = axis(4+) C Button L = axis(3-) C Button R = axis(3+) L Trig = button(4) R Trig = button(5) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [PC Game Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(8) B Button = button(4) A Button = button(5) C Button R = button(1) C Button L = button(3) C Button D = button(2) C Button U = button(0) R Trig = button(7) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Nintendo Switch Pro Controller [Pro Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) DPad L = axis(4-) DPad D = axis(5+) DPad U = axis(5-) Start = button(9) Z Trig = button(6) B Button = button(0) A Button = button(1) C Button R = axis(2-) C Button L = axis(2+) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(7) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Playfect PS3 controller (cheap clone of the Sony DualShock 3 controller) [PS3/PC WirelessGamePad] plugged = True mouse = False DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(4) B Button = button(3) A Button = button(2) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; this is also the MayFlash / HuiJia adapter [PS/SS/N64 Joypad to USB BOX] plugged=True mouse=False AnalogDeadzone=1024,1024 AnalogPeak=11000,11000 DPad R=hat(0 right) DPad L=hat(0 left) DPad U=hat(0 up) DPad D=hat(0 down) Start=button(8) Z Trig=button(9) B Button=button(2) A Button=button(1) C Button R=axis(2-) C Button L=axis(2+) C Button U=axis(3-) C Button D=axis(3+) R Trig=button(7) L Trig=button(5) X Axis=axis(0-,0+) Y Axis=axis(1-,1+) [Rock Candy Gamepad for PS3] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) # Shan Wan adapter is a gamecube adapter with the name "pdobq" on the front. # It allows for gamecube controllers to be used on wiis, wii u's, nintendo # switch, and Dolphin emulator. includes 4 ports, 2 usb plug ins, only 1 is # needed however(the black one). and has a switch between "Wii U/Switch" mode # and "PC" mode. [ShanWan Controller Adapter] plugged = True plugin = 2 mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(15) DPad D = button(14) DPad U = button(12) Start = button(9) Z Trig = button(7) B Button = button(2) A Button = button(1) C Button R = axis(5+) C Button L = axis(5-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Sony USB-Controller from PS1 Classic [Sony Interactive Entertainment Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = axis(3-) B Button = button(7) A Button = button(2) C Button R = button(1) C Button L = button(3) C Button D = button(6) C Button U = button(0) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [PLAYSTATION(R)3 Controller] [Sony PLAYSTATION(R)3 Controller] [SHENGHIC 2009/0708ZXW-V1Inc. PLAYSTATION(R)3Conteroller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(5) DPad L = button(7) DPad D = button(6) DPad U = button(4) Start = button(3) Z Trig = button(10) B Button = button(15) A Button = button(14) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(11) L Trig = button(8) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Sony Computer Entertainment Wireless Controller] [Sony Interactive Entertainment Wireless Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = axis(3+) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(5+) C Button U = axis(5-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Linux: Sony Interactive Entertainment Wireless Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(6) B Button = button(3) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Sony DS4 connected via Bluetooth advertises itself as "Wireless Controller" [Wireless Controller] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) ; L2, change to 7 for R2 Z Trig = button(6) B Button = button(0) A Button = button(1) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [PS5 Controller] plugged = True plugin = 2 mouse = False AnalogDeadzone = "4096,4096" AnalogPeak = "32768,32768" DPad R = button(14) DPad L = button(13) DPad D = button(12) DPad U = button(11) Start = button(6) Z Trig = button(9) B Button = button(2) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(10) axis(5+) L Trig = axis(4+) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; fake Sony Playstation controller [SHANWAN PS3 GamePad] plugged = True plugin = 2 mouse = False AnalogDeadzone = "800,800" AnalogPeak = "32768,32768" DPad R = "button(16)" DPad L = "button(15)" DPad D = "button(14)" DPad U = "button(13)" Start = "button(9)" Z Trig = "button(8)" B Button = "button(3)" A Button = "button(0)" C Button R = "axis(3+)" C Button L = "axis(3-)" C Button D = "axis(4+)" C Button U = "axis(4-)" R Trig = "button(5)" L Trig = "button(4)" Mempak switch = "" Rumblepak switch = "" X Axis = "axis(0-,0+)" Y Axis = "axis(1-,1+)" ; SAFFUN N64 Wired USB PC Game pad Joystick [SWITCH CO.,LTD. Controller (Dinput)] plugged = True plugin = 2 mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(12) Z Trig = button(6) B Button = button(2) A Button = button(1) C Button R = button(8) C Button L = button(3) C Button D = button(0) C Button U = button(9) R Trig = button(5) L Trig = button(4) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [SAITEK P880] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(10) Z Trig = button(3) B Button = button(0) A Button = button(2) C Button R = button(5) axis(3+) C Button L = button(1) axis(3-) C Button D = button(9) axis(2+) C Button U = button(4) axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Saitek P990 Dual Analog Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(5) Z Trig = button(4) B Button = button(0) A Button = button(1) C Button R = button(8) axis(3+) C Button L = button(3) axis(3-) C Button D = button(2) axis(2+) C Button U = button(9) axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = button(11) Rumblepak switch = button(10) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Saitek PLC Saitek P2600 Rumble Force Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(11) Z Trig = button(7) B Button = button(0) A Button = button(1) C Button R = button(8) axis(3+) C Button L = button(3) axis(3-) C Button D = button(2) axis(2+) C Button U = button(9) axis(2-) R Trig = button(5) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Saitek P2900 Wireless Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(4+) DPad L = axis(4-) DPad D = axis(5+) DPad U = axis(5-) Start = button(6) Z Trig = button(7) B Button = button(0) A Button = button(1) C Button R = button(8) axis(3+) C Button L = button(3) axis(3-) C Button D = button(2) axis(2+) C Button U = button(9) axis(2-) R Trig = button(5) L Trig = button(4) Mempak switch = button(11) Rumblepak switch = axis(10+) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Saitek PLC Cyborg Force Rumble Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(8) B Button = button(0) A Button = button(2) C Button R = button(5) axis(3+) C Button L = button(1) axis(3-) C Button D = button(3) axis(2+) C Button U = button(4) axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = button(11) Rumblepak switch = axis(10+) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [ShanWan USB WirelessGamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(0+) DPad L = axis(0-) DPad D = axis(1+) DPad U = axis(1-) Start = button(9) Z Trig = button(8) B Button = button(3) A Button = button(2) C Button R = button(7) C Button L = button(6) C Button D = button(1) C Button U = button(0) R Trig = button(5) L Trig = button(4) Mempak switch = key(109) Rumblepak switch = key(114) Y Axis = axis(1-,1+) X Axis = axis(0-,0+) [SZMY-POWER CO.,LTD. GAMEPAD 3 TURBO] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(6) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [SZMY-POWER CO.,LTD. TIMgames gamepad A3069] plugged = True plugin = 2 mouse = False AnalogDeadzone = 0,0 AnalogPeak = 32767,32767 DPad R = hat(6 Right) DPad L = hat(6 Left) DPad D = hat(7 Down) DPad U = hat(7 Up) Start = button(11) Z Trig = button(9) B Button = button(3) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(7) L Trig = button(6) Mempak switch = button(10) Rumblepak switch = button(12) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Thrustmaster Dual Trigger 3-in-1] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(3) B Button = button(0) A Button = button(1) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(5+) C Button U = axis(5-) R Trig = button(5) L Trig = button(4) Mempak switch = button(6) Rumblepak switch = button(7) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [THRUSTMASTER Firestorm Dual Power 2] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(5) Z Trig = button(8) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(6) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Thrustmaster T Mini Wireless] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat (0 Right) DPad L = hat (0 Left) DPad D = hat (0 Down) DPad U = hat (0 Up) Start = button(9) Z Trig = button(5) B Button = button(0) A Button = button(1) C Button R = Axis = axis(2+) C Button L = Axis = axis(2-) C Button D = Axis = axis(3+) C Button U = Axis = axis(3-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Twin USB Joystick] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(4) B Button = button(6) A Button = button(7) C Button R = button(1) C Button L = button(3) C Button D = button(2) C Button U = button(0) R Trig = button(5) L Trig = button(11) Mempak switch = Rumblepak switch = Y Axis = axis(1-,1+) X Axis = axis(0-,0+) [Twin USB Vibration Gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ;Twin USB PS-controller lookalike, branded "POWER PAD". ;The controller closest to the USB-plug is Player 1. [Twin USB Gamepad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(4) B Button = button(3) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = Y Axis = axis(1-,1+) X Axis = axis(0-,0+) [Wii U GameCube Adapter Port 1] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(11) DPad L = button(10) DPad D = button(9) DPad U = button(8) Start = button(7) Z Trig = button(4) B Button = button(3) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(5) L Trig = button(4) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [TigerGame XBOX+PS2+GC Game Controller Adapter] [WiseGroup.,Ltd TigerGame XBOX+PS2+GC Game Controller Adapter] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(9) DPad L = button(8) DPad D = button(10) DPad U = button(11) Start = button(7) Z Trig = button(6) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = axis(4+) L Trig = axis(5+) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Wish Technologies Adaptoid] [Adaptoid] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = button(13) DPad L = button(12) DPad D = button(11) DPad U = button(10) Start = button(8) Z Trig = button(9) B Button = button(3) A Button = button(0) C Button R = button(2) C Button L = button(4) C Button D = button(1) C Button U = button(5) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; X-box controllers and compatible clones [Microsoft X-Box pad v1 (US)] [Microsoft X-Box pad v2 (US)] [Microsoft X-Box pad (Japan)] [Microsoft Xbox Controller S] [Thrustmaster, Inc. Controller] [Logitech Xbox Cordless Controller] [Logitech Compact Controller for Xbox] [Mad Catz Controller (unverified)] [InterAct 'PowerPad Pro' X-Box pad (Germany)] [Mad Catz Control Pad] [Mad Catz LumiCON] [Mad Catz Control Pad Pro] [Mad Catz MicroCON] [Mad Catz Lynx Wireless Controller] [Zeroplus Xbox Controller] [Pelican Eclipse PL-2023] [Zeroplus Xbox Controller] [Radica Gamester Controller] [Radica Games Jtech Controller] [Logic3 Freebird wireless Controller] [Eclipse wireless Controller] [Edge wireless Controller] [SmartJoy Frag Xpad/PS2 adaptor] [Joytech Advanced Controller] [BigBen XBMiniPad Controller] [Joytech Wireless Advanced Controller] [Chinese-made Xbox Controller] [Generic X-Box pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(7) Z Trig = axis(2+) B Button = button(2) A Button = button(0) C Button R = axis(3+) C Button L = axis(3-) button(3) C Button D = axis(4+) button(1) C Button U = axis(4-) R Trig = button(5) axis(5+) L Trig = button(4) Mempak switch = button(9) Rumblepak switch = button(10) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [OSX: USB GamePad] ; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 ; this is the "MayFlash" adapter, aka HuiJia. The OSX driver seems to have a ; different button mapping plugged = True mouse = False AnalogDeadzone = 2500,2500 AnalogPeak = 20000,20000 DPad R = button(13) DPad L = button(15) DPad D = button(14) DPad U = button(12) Start = button(9) Z Trig = button(8) B Button = button(2) A Button = button(1) C Button R = axis(1-) C Button L = axis(1+) C Button D = axis(0+) C Button U = axis(0-) R Trig = button(7) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(2-,2+) Y Axis = axis(3-,3+) __NextController: plugged = True mouse = False AnalogDeadzone = 2500,2500 AnalogPeak = 20000,20000 DPad R = button(29) DPad L = button(31) DPad D = button(30) DPad U = button(28) Start = button(25) Z Trig = button(24) B Button = button(18) A Button = button(17) C Button R = axis(5-) C Button L = axis(5+) C Button D = axis(4+) C Button U = axis(4-) R Trig = button(23) L Trig = button(22) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(6-,6+) Y Axis = axis(7-,7+) [Linux: HuiJia USB GamePad] plugged = True mouse = False AnalogDeadzone = 100,100 AnalogPeak = 20000,20000 DPad R = button(13) DPad L = button(15) DPad D = button(14) DPad U = button(12) Start = button(8) Z Trig = button(9) B Button = button(2) A Button = button(1) C Button R = axis(3-) C Button L = axis(3+) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; Mayflash N64 Controller Adapter (for PC USB) - With two N64 gamepads connected ; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 [Win32: USB GamePad] plugged = True mouse = False AnalogDeadzone = 1024,1024 AnalogPeak = 12288,12288 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(8) Z Trig = button(9) B Button = button(2) A Button = button(1) C Button R = axis(3-) C Button L = axis(3+) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(7) L Trig = button(6) Mempak switch = key(109) Rumblepak switch = key(114) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) ; MayFlash PC048 adapter [PS/SS/N64 Joypad to USB BOX] plugged = True mouse = False AnalogDeadzone = 1024,1024 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(8) Z Trig = button(9) B Button = button(2) A Button = button(1) C Button R = axis(2-) C Button L = axis(2+) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(7) L Trig = button(5) Mempak switch = Rumblepak switch = Y Axis = axis(1-,1+) X Axis = axis(0-,0+) ; Asikgame - Super Dual Box (with two PS2 gamepads connected) ; this is a 2-port USB device. The Right port is controller #1, the Left port is #2 [USB Human(2p) Interface Device] plugged = True mouse = False DPad R= axis(2+) DPad L= axis(2-) DPad D= axis(5+) DPad U= axis(5-) Start= button(0) Z Trig= button(1) B Button= button(3) A Button= button(2) C Button R= hat(0 Right) C Button L= hat(0 Left) C Button D= hat(0 Down) C Button U= hat(0 Up) R Trig= button(5) L Trig= button(4) Mempak switch= button(9) Rumblepak switch= button(8) Y Axis= axis(1-,1+) X Axis= axis(0-,0+) __NextController: plugged = True mouse = False DPad R= axis(6+) DPad L= axis(6-) DPad D= axis(7+) DPad U= axis(7-) Start= button(12) Z Trig= button(13) B Button= button(15) A Button= button(14) C Button R= hat(1 Right) C Button L= hat(1 Left) C Button D= hat(1 Down) C Button U= hat(1 Up) R Trig= button(17) L Trig= button(16) Mempak switch= button(21) Rumblepak switch= button(20) Y Axis= axis(4-,4+) X Axis= axis(3-,3+) [Microsoft SideWinder Game Pad Pro USB version 1.0] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = key(275) DPad L = key(276) DPad D = key(274) DPad U = key(273) Start = button(8) Z Trig = button(6) B Button = button(0) A Button = button(3) C Button R = button(2) C Button L = button(4) C Button D = button(1) C Button U = button(5) R Trig = button(7) L Trig = button(6) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [USB,2-axis 8-button gamepad] [USB Gamepad ] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = axis(0+) DPad L = axis(0-) DPad D = axis(1+) DPad U = axis(1-) Start = button(7) Z Trig = button(6) B Button = button(1) A Button = button(0) C Button R = button(2) C Button L = button(3) C Button D = button(99) C Button U = button(99) R Trig = button(4) L Trig = button(5) Mempak switch = key(109) Rumblepak switch = key(114) Y Axis = axis(1-,1+) X Axis = axis(0-,0+) ; RetroUSB "USB N64 RetroPort" [N64 ] plugged = True mouse = False AnalogDeadzone = 2048,2048 AnalogPeak = 18432,18432 DPad R = button(0) DPad L = button(1) DPad D = button(2) DPad U = button(3) Start = button(4) Z Trig = button(5) B Button = button(6) A Button = button(7) C Button R = button(8) C Button L = button(9) C Button D = button(10) C Button U = button(11) R Trig = button(12) L Trig = button(13) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Jess Tech GGE909 PC Recoil Pad] plugged = True mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(9) Z Trig = button(7) B Button = button(0) A Button = button(2) C Button R = axis(3+) C Button L = axis(3-) C Button D = axis(2+) C Button U = axis(2-) R Trig = button(6) L Trig = button(4) Mempak switch = button(10) Rumblepak switch = button(11) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [8BITDO NES30] plugged = True mouse = False DPad R = key(3) DPad L = key(2) DPad D = key(5) DPad U = key(0) Start = key(22) Z Trig = key(21) B Button = key(12) A Button = key(11) C Button R = key(3) C Button L = key(2) C Button D = key(5) C Button U = key(0) R Trig = key(99) L Trig = key(120) Mempak switch = key(44) Rumblepak switch = key(46) X Axis = key(276,275) Y Axis = key(273,274) ; Xiaomi Bluetooth Controller [小米蓝牙手柄] plugged = True mouse = False AnalogDeadzone = 0,0 AnalogPeak = 32768,32768 DPad R = axis(8+) DPad L = axis(8-) DPad D = axis(9+) DPad U = axis(9-) Start = button(11) Z Trig = button(6) B Button = button(3) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(5+) C Button U = axis(5-) R Trig = button(7) L Trig = button(8) Mempak switch = Rumblepak switch = X Axis = axis(0-,0+) Y Axis = axis(1-,1+) [Google LLC Stadia Controller] plugged = True plugin = 2 mouse = False AnalogDeadzone = 4096,4096 AnalogPeak = 32768,32768 DPad R = hat(0 Right) DPad L = hat(0 Left) DPad D = hat(0 Down) DPad U = hat(0 Up) Start = button(8) Z Trig = axis(5+) B Button = button(1) A Button = button(0) C Button R = axis(2+) C Button L = axis(2-) C Button D = axis(3+) C Button U = axis(3-) R Trig = button(5) L Trig = button(4) Mempak switch = button(2) Rumblepak switch = button(3) X Axis = axis(0-,0+) Y Axis = axis(1-,1+) mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/000077500000000000000000000000001436635717600210305ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/cmake/000077500000000000000000000000001436635717600221105ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/cmake/CMake/000077500000000000000000000000001436635717600230705ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/cmake/CMake/Find/000077500000000000000000000000001436635717600237505ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/cmake/CMake/Find/FindSDL2.cmake000066400000000000000000000140611436635717600262610ustar00rootroot00000000000000 # This module defines # SDL2_LIBRARY, the name of the library to link against # SDL2_FOUND, if false, do not try to link to SDL2 # SDL2_INCLUDE_DIR, where to find SDL.h # # This module responds to the the flag: # SDL2_BUILDING_LIBRARY # If this is defined, then no SDL2main will be linked in because # only applications need main(). # Otherwise, it is assumed you are building an application and this # module will attempt to locate and set the the proper link flags # as part of the returned SDL2_LIBRARY variable. # # Don't forget to include SDLmain.h and SDLmain.m your project for the # OS X framework based version. (Other versions link to -lSDL2main which # this module will try to find on your behalf.) Also for OS X, this # module will automatically add the -framework Cocoa on your behalf. # # # Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration # and no SDL2_LIBRARY, it means CMake did not find your SDL2 library # (SDL2.dll, libsdl2.so, SDL2.framework, etc). # Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value # as appropriate. These values are used to generate the final SDL2_LIBRARY # variable, but when these values are unset, SDL2_LIBRARY does not get created. # # # $SDL2DIR is an environment variable that would # correspond to the ./configure --prefix=$SDL2DIR # used in building SDL2. # l.e.galup 9-20-02 # # Modified by Eric Wing. # Added code to assist with automated building by using environmental variables # and providing a more controlled/consistent search behavior. # Added new modifications to recognize OS X frameworks and # additional Unix paths (FreeBSD, etc). # Also corrected the header search path to follow "proper" SDL guidelines. # Added a search for SDL2main which is needed by some platforms. # Added a search for threads which is needed by some platforms. # Added needed compile switches for MinGW. # # On OSX, this will prefer the Framework version (if found) over others. # People will have to manually change the cache values of # SDL2_LIBRARY to override this selection or set the CMake environment # CMAKE_INCLUDE_PATH to modify the search paths. # # Note that the header path has changed from SDL2/SDL.h to just SDL.h # This needed to change because "proper" SDL convention # is #include "SDL.h", not . This is done for portability # reasons because not all systems place things in SDL2/ (see FreeBSD). #============================================================================= # Copyright 2003-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) message("") SET(SDL2_SEARCH_PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /sw # Fink /opt/local # DarwinPorts /opt/csw # Blastwave /opt ${SDL2_PATH} ) FIND_PATH(SDL2_INCLUDE_DIR SDL.h HINTS $ENV{SDL2DIR} PATH_SUFFIXES include/SDL2 include PATHS ${SDL2_SEARCH_PATHS} ) FIND_LIBRARY(SDL2_LIBRARY_TEMP NAMES SDL2 HINTS $ENV{SDL2DIR} PATH_SUFFIXES lib64 lib PATHS ${SDL2_SEARCH_PATHS} ) IF(NOT SDL2_BUILDING_LIBRARY) IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") # Non-OS X framework versions expect you to also dynamically link to # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms # seem to provide SDL2main for compatibility even though they don't # necessarily need it. FIND_LIBRARY(SDL2MAIN_LIBRARY NAMES SDL2main HINTS $ENV{SDL2DIR} PATH_SUFFIXES lib64 lib PATHS ${SDL2_SEARCH_PATHS} ) ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") ENDIF(NOT SDL2_BUILDING_LIBRARY) # SDL2 may require threads on your system. # The Apple build may not need an explicit flag because one of the # frameworks may already provide it. # But for non-OSX systems, I will use the CMake Threads package. IF(NOT APPLE) FIND_PACKAGE(Threads) ENDIF(NOT APPLE) # MinGW needs an additional library, mwindows # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows # (Actually on second look, I think it only needs one of the m* libraries.) IF(MINGW) SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") ENDIF(MINGW) IF(SDL2_LIBRARY_TEMP) # For SDL2main IF(NOT SDL2_BUILDING_LIBRARY) IF(SDL2MAIN_LIBRARY) SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) ENDIF(SDL2MAIN_LIBRARY) ENDIF(NOT SDL2_BUILDING_LIBRARY) # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. # CMake doesn't display the -framework Cocoa string in the UI even # though it actually is there if I modify a pre-used variable. # I think it has something to do with the CACHE STRING. # So I use a temporary variable until the end so I can set the # "real" variable in one-shot. IF(APPLE) SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") ENDIF(APPLE) # For threads, as mentioned Apple doesn't need this. # In fact, there seems to be a problem if I used the Threads package # and try using this line, so I'm just skipping it entirely for OS X. IF(NOT APPLE) SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) ENDIF(NOT APPLE) # For MinGW library IF(MINGW) SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) ENDIF(MINGW) # Set the final string here so the GUI reflects the final state. SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") # Set the temp variable to INTERNAL so it is not seen in the CMake GUI SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") ENDIF(SDL2_LIBRARY_TEMP) message("") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/cmake/CMakeLists.txt000066400000000000000000000051161436635717600246530ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.11) project(mupen64plus-input-sdl) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(M64_APIDIR "${CMAKE_SOURCE_DIR}/../../../mupen64plus-core/src/api") message("${CMAKE_SOURCE_DIR}/../../src/") # State directories for modules and binaries set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Find) set(CMAKE_CC_FLAGS "-ffast-math -fno-strict-aliasing -fvisibility=hidden -D_GNU_SOURCE=1") set(CMAKE_CXX_FLAGS "-pthread -fvisibility-inlines-hidden") set(SRCS ${CMAKE_SOURCE_DIR}/../../src/autoconfig.c ${CMAKE_SOURCE_DIR}/../../src/config.c ${CMAKE_SOURCE_DIR}/../../src/plugin.c ${CMAKE_SOURCE_DIR}/../../src/sdl_key_converter.c ) if(WIN32) set(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/../../src/osal_dynamiclib_win32.c ) else() set(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/../../src/osal_dynamiclib_unix.c ) endif() # Find dependencies find_package(PNG REQUIRED) if(NOT ZLIB_FOUND) include(ZLIB) message(FATAL_ERROR "Package zlib is required, but not found!") endif(NOT ZLIB_FOUND) find_package(PNG REQUIRED) if(NOT PNG_FOUND) include(PNG) message(FATAL_ERROR "Package libpng is required, but not found!") endif(NOT PNG_FOUND) find_package(SDL2 REQUIRED) if(NOT SDL2_FOUND) include(SDL2) message(FATAL_ERROR "Package SDL2 is required, but not found!") endif(NOT SDL2_FOUND) find_package(OpenGL REQUIRED) if(NOT OpenGL_FOUND) message(FATAL_ERROR "Package OpenGL is required, but not found!") endif(NOT OpenGL_FOUND) find_package(Freetype REQUIRED) if(NOT FREETYPE_FOUND) message(FATAL_ERROR "Package FreeType is required, but not found!") endif(NOT FREETYPE_FOUND) # Specify include directories include_directories( ${PNG_INCLUDE_DIR} ${OpenGL_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2} ${M64_APIDIR} ${CMAKE_SOURCE_DIR}/../../src/ ) # Create the binary add_library(${CMAKE_PROJECT_NAME} SHARED ${SRCS}) # Link the libraries # add_dependencies(${CMAKE_PROJECT_NAME} ${SDL2_LIBRARIES}) if(WIN32) target_link_libraries(${CMAKE_PROJECT_NAME} ${PNG_LIBRARY} ${OPENGL_LIBRARIES} ${SDL2_LIBRARY} ${ZLIB_LIBRARY} ) elseif(APPLE) target_link_libraries(${CMAKE_PROJECT_NAME} ${PNG_LIBRARY} ${OPENGL_LIBRARIES} ${SDL2_LIBRARY} ${ZLIB_LIBRARY} ) else() target_link_libraries(${CMAKE_PROJECT_NAME} ${PNG_LIBRARY} ${OPENGL_LIBRARIES} ${SDL2_LIBRARY} ${ZLIB_LIBRARY} ${FREETYPE_LIBRARIES} dl ) endif() mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/msvc/000077500000000000000000000000001436635717600220005ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/msvc/mupen64plus-input-sdl.vcxproj000066400000000000000000000225251436635717600275420ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {7F3178D0-0E2E-471B-9160-69F0354F9DE9} mupen64plusinputsdl $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) $(LatestTargetPlatformVersion) $(WindowsTargetPlatformVersion) $(DefaultPlatformToolset) DynamicLibrary MultiByte true $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ DynamicLibrary MultiByte true $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ DynamicLibrary MultiByte $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ DynamicLibrary MultiByte $(SolutionDir)$(Platform)\$(Configuration)\ $(Platform)\$(Configuration)\ Disabled ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL Level3 ..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\lib\x86\SDL2.lib;%(AdditionalDependencies) true Windows Disabled ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL Level3 ..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\lib\x64\SDL2.lib;%(AdditionalDependencies) true Windows ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) MultiThreadedDLL Level3 MaxSpeed true true ..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\lib\x86\SDL2.lib;%(AdditionalDependencies) true Windows true true ..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) MultiThreadedDLL Level3 MaxSpeed true true ..\..\..\mupen64plus-win32-deps\SDL2-2.24.0\lib\x64\SDL2.lib;%(AdditionalDependencies) true Windows true true mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/unix/000077500000000000000000000000001436635717600220135ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/projects/unix/Makefile000077500000000000000000000224131436635717600234600ustar00rootroot00000000000000#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # * Mupen64plus-input-sdl - Makefile * # * Mupen64Plus homepage: https://mupen64plus.org/ * # * Copyright (C) 2007-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. * # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ # Makefile for SDL 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 'https://github.com/mupen64plus/mupen64plus-core/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 SRCDIR = ../../src OBJDIR = _obj$(POSTFIX) # base CFLAGS, LDLIBS, and LDFLAGS OPTFLAGS ?= -O3 -flto WARNFLAGS ?= -Wall CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I$(SRCDIR) -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) ifeq ($(OS), FREEBSD) $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386) endif ifneq ($(OS), OSX) ifeq ($(OS), MINGW) LDFLAGS += -Wl,-m,i386pe else CFLAGS += -m32 LDFLAGS += -Wl,-m,elf_i386 endif endif endif ifeq ($(ARCH_DETECTED), 64BITS) ifeq ($(OS), MINGW) LDFLAGS += -Wl,-m,i386pep endif endif # set special flags per-system ifeq ($(OS), LINUX) LDLIBS += -ldl endif ifeq ($(OS), OSX) OSX_SDK_PATH = $(shell xcrun --sdk macosx --show-sdk-path) ifeq ($(CPU), X86) ifeq ($(ARCH_DETECTED), 64BITS) CFLAGS += -arch x86_64 -mmacosx-version-min=10.6 -isysroot $(OSX_SDK_PATH) LDLIBS += -ldl else CFLAGS += -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=10.6 -isysroot $(OSX_SDK_PATH) LDLIBS += -ldl -read_only_relocs suppress endif endif endif # test for presence of SDL ifeq ($(origin SDL_CFLAGS) $(origin SDL_LDLIBS), undefined undefined) SDL_CONFIG = $(CROSS_COMPILE)sdl2-config ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),) SDL_CONFIG = $(CROSS_COMPILE)sdl-config ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),) $(error No SDL development libraries found!) else $(warning Using SDL 1.2 libraries) endif endif SDL_CFLAGS += $(shell $(SDL_CONFIG) --cflags) SDL_LDLIBS += $(shell $(SDL_CONFIG) --libs) endif CFLAGS += $(SDL_CFLAGS) LDLIBS += $(SDL_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 CFLAGS += -DNDEBUG ifneq ($(OS),OSX) INSTALL_STRIP_FLAG ?= -s endif endif ifeq ($(PLUGINDBG), 1) CFLAGS += -D_DEBUG 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 # list of source files to compile SOURCE = \ $(SRCDIR)/plugin.c \ $(SRCDIR)/autoconfig.c \ $(SRCDIR)/sdl_key_converter.c \ $(SRCDIR)/config.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-sdl$(POSTFIX).$(SO_EXTENSION) targets: @echo "Mupen64Plus-input-sdl makefile. " @echo " Targets:" @echo " all == Build Mupen64Plus SDL input plugin" @echo " clean == remove object files" @echo " rebuild == clean and re-build all" @echo " install == Install Mupen64Plus SDL input plugin" @echo " uninstall == Uninstall Mupen64Plus SDL 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" all: $(TARGET) install: $(TARGET) $(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)" $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)" $(INSTALL) -d "$(DESTDIR)$(SHAREDIR)" $(INSTALL) -m 0644 "$(SRCDIR)/../data/InputAutoCfg.ini" "$(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 mupen64plus-input-sdl-2.5.9+55+g2129e94/src/000077500000000000000000000000001436635717600177665ustar00rootroot00000000000000mupen64plus-input-sdl-2.5.9+55+g2129e94/src/autoconfig.c000066400000000000000000000331451436635717600222760ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - autoconfig.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2009-2013 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 "autoconfig.h" #include "m64p_config.h" #include "m64p_types.h" #include "osal_preproc.h" #include "plugin.h" /* local definitions */ #define INI_FILE_NAME "InputAutoCfg.ini" typedef struct { m64p_handle pSrc; m64p_handle pDst; } SCopySection; /* local functions */ static char *StripSpace(char *pIn) { char *pEnd = pIn + strlen(pIn) - 1; while (*pIn == ' ' || *pIn == '\t' || *pIn == '\r' || *pIn == '\n') pIn++; while (pIn <= pEnd && (*pEnd == ' ' || *pEnd == '\t' || *pEnd == '\r' || *pEnd == '\n')) *pEnd-- = 0; return pIn; } static void CopyParamCallback(void * context, const char *ParamName, m64p_type ParamType) { SCopySection *pCpyContext = (SCopySection *) context; int paramInt; float paramFloat; char paramString[1024]; // handle the parameter copy depending upon type switch (ParamType) { case M64TYPE_INT: case M64TYPE_BOOL: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, ¶mInt, sizeof(int)) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, ¶mInt); break; case M64TYPE_FLOAT: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, ¶mFloat, sizeof(float)) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, ¶mFloat); break; case M64TYPE_STRING: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, paramString, 1024) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, paramString); break; default: // this should never happen DebugMessage(M64MSG_ERROR, "Unknown source parameter type %i in copy callback", (int) ParamType); return; } } /* global functions */ int auto_copy_inputconfig(const char *pccSourceSectionName, const char *pccDestSectionName, const char *sdlJoyName) { SCopySection cpyContext; if (ConfigOpenSection(pccSourceSectionName, &cpyContext.pSrc) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_copy_inputconfig: Couldn't open source config section '%s' for copying", pccSourceSectionName); return 0; } if (ConfigOpenSection(pccDestSectionName, &cpyContext.pDst) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_copy_inputconfig: Couldn't open destination config section '%s' for copying", pccDestSectionName); return 0; } // set the 'name' parameter if (sdlJoyName != NULL) { if (ConfigSetParameter(cpyContext.pDst, "name", M64TYPE_STRING, sdlJoyName) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_copy_inputconfig: Couldn't set 'name' parameter to '%s' in section '%s'", sdlJoyName, pccDestSectionName); return 0; } } // the copy gets done by the callback function if (ConfigListParameters(cpyContext.pSrc, (void *) &cpyContext, CopyParamCallback) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_copy_inputconfig: parameter list copy failed"); return 0; } return 1; } static int auto_compare_name(const char *joySDLName, char *line) { char *wordPtr; int joyFound = 1, joyFoundScore = 0; char Word[64]; wordPtr = line; /* first, if there is a preceding system name in this .ini device name, and the system matches, then strip out */ #if defined(__unix__) if (strncmp(wordPtr, "Unix:", 5) == 0) { wordPtr = StripSpace(wordPtr + 5); joyFoundScore = 1; } #endif #if defined(__linux__) if (strncmp(wordPtr, "Linux:", 6) == 0) { wordPtr = StripSpace(wordPtr + 6); joyFoundScore = 1; } #endif #if defined(__APPLE__) if (strncmp(wordPtr, "OSX:", 4) == 0) { wordPtr = StripSpace(wordPtr + 4); joyFoundScore = 1; } #endif #if defined(WIN32) if (strncmp(wordPtr, "Win32:", 6) == 0) { wordPtr = StripSpace(wordPtr + 6); joyFoundScore = 1; } #if SDL_VERSION_ATLEAST(2,0,0) else if (strncmp(wordPtr, "XInput:", 7) == 0) { wordPtr = StripSpace(wordPtr + 7); joyFoundScore = 2; } #endif #endif /* extra points if the section name is a perfect match */ if (strcmp(wordPtr, joySDLName) == 0) joyFoundScore += 4; /* search in the .ini device name for all the words in the joystick name. If any are missing, then this is not the right joystick model */ while (wordPtr != NULL && strlen(wordPtr) > 0) { /* skip over any preceding spaces */ while (*wordPtr == ' ') wordPtr++; if (*wordPtr == 0) break; /* search for the next space after the current word */ char *nextSpace = strchr(wordPtr, ' '); if (nextSpace == NULL) { strncpy(Word, wordPtr, 63); Word[63] = 0; wordPtr = NULL; } else { int length = (int) (nextSpace - wordPtr); if (length > 63) length = 63; strncpy(Word, wordPtr, length); Word[length] = 0; wordPtr = nextSpace + 1; } if (strcasestr(joySDLName, Word) == NULL) joyFound = 0; else joyFoundScore += 4; } if (joyFound) return joyFoundScore; else return -1; } int auto_set_defaults(int iDeviceIdx, const char *joySDLName) { FILE *pfIn; m64p_handle pConfig = NULL; const char *CfgFilePath = ConfigGetSharedDataFilepath(INI_FILE_NAME); enum { E_NAME_SEARCH, E_NAME_FOUND, E_PARAM_READ } eParseState; char *pchIni, *pchNextLine, *pchCurLine; long iniLength; int ControllersFound = 0; int joyFoundScore = -1; /* if we couldn't get a name (no joystick plugged in to given port), then return with a failure */ if (joySDLName == NULL) return 0; /* if we couldn't find the shared data file, dump an error and return */ if (CfgFilePath == NULL || strlen(CfgFilePath) < 1) { DebugMessage(M64MSG_ERROR, "Couldn't find config file '%s'", INI_FILE_NAME); return 0; } /* read the input auto-config .ini file */ pfIn = fopen(CfgFilePath, "rb"); if (pfIn == NULL) { DebugMessage(M64MSG_ERROR, "Couldn't open config file '%s'", CfgFilePath); return 0; } fseek(pfIn, 0L, SEEK_END); iniLength = ftell(pfIn); fseek(pfIn, 0L, SEEK_SET); if (iniLength < 0) { DebugMessage(M64MSG_ERROR, "Couldn't get size of config file '%s'", CfgFilePath); fclose(pfIn); return 0; } pchIni = (char *) malloc(iniLength + 1); if (pchIni == NULL) { DebugMessage(M64MSG_ERROR, "Couldn't allocate %li bytes for config file '%s'", iniLength, CfgFilePath); fclose(pfIn); return 0; } if (fread(pchIni, 1, iniLength, pfIn) != iniLength) { DebugMessage(M64MSG_ERROR, "File read failed for %li bytes of config file '%s'", iniLength, CfgFilePath); free(pchIni); fclose(pfIn); return 0; } fclose(pfIn); pchIni[iniLength] = 0; /* parse the INI file, line by line */ DebugMessage(M64MSG_INFO, "Using auto-config file at: '%s'", CfgFilePath); pchNextLine = pchIni; eParseState = E_NAME_SEARCH; while (pchNextLine != NULL && *pchNextLine != 0) { char *pivot = NULL; int joyFound = 0; /* set up character pointers */ pchCurLine = pchNextLine; pchNextLine = strchr(pchNextLine, '\n'); if (pchNextLine != NULL) *pchNextLine++ = 0; pchCurLine = StripSpace(pchCurLine); /* handle blank/comment lines */ if (strlen(pchCurLine) < 1 || *pchCurLine == ';' || *pchCurLine == '#') continue; /* handle section (joystick name in ini file) */ if (*pchCurLine == '[' && pchCurLine[strlen(pchCurLine)-1] == ']') { /* only switch to name search when some section body was identified since last header */ if (eParseState == E_PARAM_READ) eParseState = E_NAME_SEARCH; /* we need to look through the device name word by word to see if it matches the joySDLName that we're looking for */ pchCurLine[strlen(pchCurLine)-1] = 0; joyFound = auto_compare_name(joySDLName, StripSpace(pchCurLine + 1)); /* if we found the right joystick, then open up the core config section to store parameters and set the 'device' param */ if (joyFound > joyFoundScore) { char SectionName[32]; ControllersFound = 0; sprintf(SectionName, "AutoConfig%i", ControllersFound); if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName); free(pchIni); return 0; } eParseState = E_NAME_FOUND; ControllersFound++; ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx); joyFoundScore = joyFound; } continue; } /* handle parameters */ pivot = strchr(pchCurLine, '='); if (pivot != NULL) { /* if we haven't found the correct section yet, just skip this */ if (eParseState == E_NAME_SEARCH) continue; eParseState = E_PARAM_READ; /* otherwise, store this parameter in the current active joystick config */ *pivot++ = 0; pchCurLine = StripSpace(pchCurLine); pivot = StripSpace(pivot); if (strcasecmp(pchCurLine, "device") == 0) { int iVal = atoi(pivot); ConfigSetParameter(pConfig, pchCurLine, M64TYPE_INT, &iVal); } else if (strcasecmp(pchCurLine, "plugged") == 0 || strcasecmp(pchCurLine, "mouse") == 0) { int bVal = (strcasecmp(pivot, "true") == 0); ConfigSetParameter(pConfig, pchCurLine, M64TYPE_BOOL, &bVal); } else { ConfigSetParameter(pConfig, pchCurLine, M64TYPE_STRING, pivot); } continue; } /* handle keywords */ if (pchCurLine[strlen(pchCurLine)-1] == ':') { /* if we haven't found the correct section yet, just skip this */ if (eParseState == E_NAME_SEARCH) continue; eParseState = E_PARAM_READ; /* otherwise parse the keyword */ if (strcmp(pchCurLine, "__NextController:") == 0) { char SectionName[32]; /* if there are no more N64 controller spaces left, then exit */ if (ControllersFound == 4) { free(pchIni); return ControllersFound; } /* otherwise go to the next N64 controller */ sprintf(SectionName, "AutoConfig%i", ControllersFound); if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName); free(pchIni); return ControllersFound; } ControllersFound++; ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx); } else { DebugMessage(M64MSG_ERROR, "Unknown keyword '%s' in %s", pchCurLine, INI_FILE_NAME); } continue; } /* unhandled line in .ini file */ DebugMessage(M64MSG_ERROR, "Invalid line in %s: '%s'", INI_FILE_NAME, pchCurLine); } if (joyFoundScore != -1) { /* we've finished parsing all parameters for the discovered input device, which is the last in the .ini file */ free(pchIni); return ControllersFound; } free(pchIni); return 0; } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/autoconfig.h000066400000000000000000000034331436635717600223000ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - autoconfig.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __AUTOCONFIG_H__ #define __AUTOCONFIG_H__ extern int auto_copy_inputconfig(const char *pccSourceSectionName, const char *pccDestSectionName, const char *sdlJoyName); extern int auto_set_defaults(int iDeviceIdx, const char *joySDLName); #endif /* __AUTOCONFIG_H__ */ mupen64plus-input-sdl-2.5.9+55+g2129e94/src/config.c000066400000000000000000001114121436635717600213770ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - config.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2009-2013 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 #define M64P_PLUGIN_PROTOTYPES 1 #include "autoconfig.h" #include "config.h" #include "m64p_config.h" #include "m64p_plugin.h" #include "m64p_types.h" #include "osal_preproc.h" #include "plugin.h" #include "sdl_key_converter.h" #define HAT_POS_NAME( hat ) \ ((hat == SDL_HAT_UP) ? "Up" : \ ((hat == SDL_HAT_DOWN) ? "Down" : \ ((hat == SDL_HAT_LEFT) ? "Left" : \ ((hat == SDL_HAT_RIGHT) ? "Right" : \ "None")))) typedef enum { E_MODE_MANUAL = 0, E_MODE_NAMED_AUTO, E_MODE_FULL_AUTO } eModeType; static const char *button_names[] = { "DPad R", // R_DPAD "DPad L", // L_DPAD "DPad D", // D_DPAD "DPad U", // U_DPAD "Start", // START_BUTTON "Z Trig", // Z_TRIG "B Button", // B_BUTTON "A Button", // A_BUTTON "C Button R", // R_CBUTTON "C Button L", // L_CBUTTON "C Button D", // D_CBUTTON "C Button U", // U_CBUTTON "R Trig", // R_TRIG "L Trig", // L_TRIG "Mempak switch", "Rumblepak switch", "X Axis", // X_AXIS "Y Axis" // Y_AXIS }; /* static functions */ static int get_hat_pos_by_name( const char *name ) { if( !strcasecmp( name, "up" ) ) return SDL_HAT_UP; if( !strcasecmp( name, "down" ) ) return SDL_HAT_DOWN; if( !strcasecmp( name, "left" ) ) return SDL_HAT_LEFT; if( !strcasecmp( name, "right" ) ) return SDL_HAT_RIGHT; DebugMessage(M64MSG_WARNING, "get_hat_pos_by_name(): direction '%s' unknown", name); return -1; } static void clear_controller(int iCtrlIdx) { int b; controller[iCtrlIdx].device = DEVICE_NO_JOYSTICK; controller[iCtrlIdx].control->Present = 0; controller[iCtrlIdx].control->RawData = 0; controller[iCtrlIdx].control->Plugin = PLUGIN_MEMPAK; for( b = 0; b < 16; b++ ) { controller[iCtrlIdx].button[b].button = -1; controller[iCtrlIdx].button[b].key = SDL_SCANCODE_UNKNOWN; controller[iCtrlIdx].button[b].axis = -1; controller[iCtrlIdx].button[b].axis_deadzone = -1; controller[iCtrlIdx].button[b].hat = -1; controller[iCtrlIdx].button[b].hat_pos = -1; controller[iCtrlIdx].button[b].mouse = -1; } for( b = 0; b < 2; b++ ) { controller[iCtrlIdx].mouse_sens[b] = 2.0; controller[iCtrlIdx].axis_deadzone[b] = 4096; controller[iCtrlIdx].axis_peak[b] = 32768; controller[iCtrlIdx].axis[b].button_a = controller[iCtrlIdx].axis[b].button_b = -1; controller[iCtrlIdx].axis[b].key_a = controller[iCtrlIdx].axis[b].key_b = SDL_SCANCODE_UNKNOWN; controller[iCtrlIdx].axis[b].axis_a = -1; controller[iCtrlIdx].axis[b].axis_dir_a = 1; controller[iCtrlIdx].axis[b].axis_b = -1; controller[iCtrlIdx].axis[b].axis_dir_b = 1; controller[iCtrlIdx].axis[b].hat = -1; controller[iCtrlIdx].axis[b].hat_pos_a = -1; controller[iCtrlIdx].axis[b].hat_pos_b = -1; } } static const char * get_sdl_joystick_name(int iCtrlIdx) { static char JoyName[256]; const char *joySDLName; /* get the name of the corresponding joystick */ joySDLName = SDL_JoystickName(iCtrlIdx); /* copy the name to our local string */ if (joySDLName != NULL) { strncpy(JoyName, joySDLName, 255); JoyName[255] = 0; } /* if the SDL function had an error, then return NULL, otherwise return local copy of joystick name */ if (joySDLName == NULL) return NULL; else return JoyName; } ///////////////////////////////////// // load_controller_config() // return value: 1 = OK // 0 = fail: couldn't open config section static int load_controller_config(const char *SectionName, int i, int sdlDeviceIdx) { m64p_handle pConfig; char input_str[256], value1_str[16], value2_str[16]; const char *config_ptr; int j; /* Open the configuration section for this controller */ if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName); return 0; } /* set SDL device number */ controller[i].device = sdlDeviceIdx; /* throw warnings if 'plugged' is missing */ if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing 'plugged' parameter from config section %s. Setting to 1 (true).", SectionName); controller[i].control->Present = 1; } /* load optional parameters */ ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int)); if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1); } /* load configuration for all the digital buttons */ for (j = 0; j < X_AXIS; j++) { if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) { if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1) { DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1); } else { controller[i].button[j].key = sdl_keysym2native(controller[i].button[j].key); } } if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir; if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 && sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1); controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1); value1_str[15] = 0; /* chop off the last character of value1_str if it is the closing parenthesis */ lastchar = &value1_str[strlen(value1_str) - 1]; if (lastchar > value1_str && *lastchar == ')') *lastchar = 0; controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str); } if ((config_ptr = strstr(input_str, "mouse")) != NULL) if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1) DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1); } /* load configuration for the 2 analog joystick axes */ for (j = X_AXIS; j <= Y_AXIS; j++) { int axis_idx = j - X_AXIS; if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) { if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2) { DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1); } else { controller[i].axis[axis_idx].key_a = sdl_keysym2native(controller[i].axis[axis_idx].key_a); controller[i].axis[axis_idx].key_b = sdl_keysym2native(controller[i].axis[axis_idx].key_b); } } if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir1, chAxisDir2; if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1, &controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1); controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0)); controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1); value1_str[15] = value2_str[15] = 0; /* chop off the last character of value2_str if it is the closing parenthesis */ lastchar = &value2_str[strlen(value2_str) - 1]; if (lastchar > value2_str && *lastchar == ')') *lastchar = 0; controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str); controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str); } } return 1; } static void init_controller_config(int iCtrlIdx, const char *pccDeviceName, eModeType mode) { m64p_handle pConfig; char SectionName[32], Param[32], ParamString[128]; int j; /* Delete the configuration section for this controller, so we can use SetDefaults and save the help comments also */ sprintf(SectionName, "Input-SDL-Control%i", iCtrlIdx + 1); ConfigDeleteSection(SectionName); /* Open the configuration section for this controller (create a new one) */ if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName); return; } /* save the general controller parameters */ ConfigSetDefaultFloat(pConfig, "version", CONFIG_VERSION, "Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number."); ConfigSetDefaultInt(pConfig, "mode", (int) mode, "Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic"); ConfigSetDefaultInt(pConfig, "device", controller[iCtrlIdx].device, "Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number"); ConfigSetDefaultString(pConfig, "name", pccDeviceName, "SDL joystick name (or Keyboard)"); ConfigSetDefaultBool(pConfig, "plugged", controller[iCtrlIdx].control->Present, "Specifies whether this controller is 'plugged in' to the simulated N64"); ConfigSetDefaultInt(pConfig, "plugin", controller[iCtrlIdx].control->Plugin, "Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak"); ConfigSetDefaultBool(pConfig, "mouse", controller[iCtrlIdx].mouse, "If True, then mouse buttons may be used with this controller"); sprintf(Param, "%.2f,%.2f", controller[iCtrlIdx].mouse_sens[0], controller[iCtrlIdx].mouse_sens[1]); ConfigSetDefaultString(pConfig, "MouseSensitivity", Param, "Scaling factor for mouse movements. For X, Y axes."); sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_deadzone[0], controller[iCtrlIdx].axis_deadzone[1]); ConfigSetDefaultString(pConfig, "AnalogDeadzone", Param, "The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes."); sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_peak[0], controller[iCtrlIdx].axis_peak[1]); ConfigSetDefaultString(pConfig, "AnalogPeak", Param, "An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value"); /* save configuration for all the digital buttons */ for (j = 0; j < X_AXIS; j++ ) { const char *Help; int len = 0; ParamString[0] = 0; if (controller[iCtrlIdx].button[j].key > 0) { sprintf(Param, "key(%i) ", sdl_native2keysym(controller[iCtrlIdx].button[j].key)); strcat(ParamString, Param); } if (controller[iCtrlIdx].button[j].button >= 0) { sprintf(Param, "button(%i) ", controller[iCtrlIdx].button[j].button); strcat(ParamString, Param); } if (controller[iCtrlIdx].button[j].axis >= 0) { if (controller[iCtrlIdx].button[j].axis_deadzone >= 0) sprintf(Param, "axis(%i%c,%i) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+', controller[iCtrlIdx].button[j].axis_deadzone); else sprintf(Param, "axis(%i%c) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+'); strcat(ParamString, Param); } if (controller[iCtrlIdx].button[j].hat >= 0) { sprintf(Param, "hat(%i %s) ", controller[iCtrlIdx].button[j].hat, HAT_POS_NAME(controller[iCtrlIdx].button[j].hat_pos)); strcat(ParamString, Param); } if (controller[iCtrlIdx].button[j].mouse >= 0) { sprintf(Param, "mouse(%i) ", controller[iCtrlIdx].button[j].mouse); strcat(ParamString, Param); } if (j == 0) Help = "Digital button configuration mappings"; else Help = NULL; /* if last character is a space, chop it off */ len = strlen(ParamString); if (len > 0 && ParamString[len-1] == ' ') ParamString[len-1] = 0; ConfigSetDefaultString(pConfig, button_names[j], ParamString, Help); } /* save configuration for the 2 analog axes */ for (j = 0; j < 2; j++ ) { const char *Help; int len = 0; ParamString[0] = 0; if (controller[iCtrlIdx].axis[j].key_a > 0 && controller[iCtrlIdx].axis[j].key_b > 0) { sprintf(Param, "key(%i,%i) ", sdl_native2keysym(controller[iCtrlIdx].axis[j].key_a), sdl_native2keysym(controller[iCtrlIdx].axis[j].key_b)); strcat(ParamString, Param); } if (controller[iCtrlIdx].axis[j].button_a >= 0 && controller[iCtrlIdx].axis[j].button_b >= 0) { sprintf(Param, "button(%i,%i) ", controller[iCtrlIdx].axis[j].button_a, controller[iCtrlIdx].axis[j].button_b); strcat(ParamString, Param); } if (controller[iCtrlIdx].axis[j].axis_a >= 0 && controller[iCtrlIdx].axis[j].axis_b >= 0) { sprintf(Param, "axis(%i%c,%i%c) ", controller[iCtrlIdx].axis[j].axis_a, (controller[iCtrlIdx].axis[j].axis_dir_a <= 0) ? '-' : '+', controller[iCtrlIdx].axis[j].axis_b, (controller[iCtrlIdx].axis[j].axis_dir_b <= 0) ? '-' : '+' ); strcat(ParamString, Param); } if (controller[iCtrlIdx].axis[j].hat >= 0) { sprintf(Param, "hat(%i %s %s) ", controller[iCtrlIdx].axis[j].hat, HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_a), HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_b)); strcat(ParamString, Param); } if (j == 0) Help = "Analog axis configuration mappings"; else Help = NULL; /* if last character is a space, chop it off */ len = strlen(ParamString); if (len > 0 && ParamString[len-1] == ' ') ParamString[len-1] = 0; ConfigSetDefaultString(pConfig, button_names[X_AXIS + j], ParamString, Help); } } static int setup_auto_controllers(int bPreConfig, int n64CtrlStart, int sdlCtrlIdx, const char *sdlJoyName, eModeType ControlMode[], eModeType OrigControlMode[], char DeviceName[][256]) { char SectionName[32]; int ActiveControllers = 0; int j; /* create auto-config section(s) for this joystick (if this joystick is in the InputAutoConfig.ini) */ int ControllersFound = auto_set_defaults(sdlCtrlIdx, sdlJoyName); if (ControllersFound == 0) return 0; /* copy the auto-config settings to the controller config section, and load our plugin joystick config from this */ sprintf(SectionName, "Input-SDL-Control%i", n64CtrlStart + 1); if (OrigControlMode[n64CtrlStart] == E_MODE_FULL_AUTO) auto_copy_inputconfig("AutoConfig0", SectionName, sdlJoyName); else auto_copy_inputconfig("AutoConfig0", SectionName, NULL); // don't overwrite 'name' parameter if original mode was "named auto" if (load_controller_config("AutoConfig0", n64CtrlStart, sdlCtrlIdx) > 0) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config with SDL joystick %i ('%s')", n64CtrlStart+1, sdlCtrlIdx, sdlJoyName); ActiveControllers++; } else { if (!bPreConfig) DebugMessage(M64MSG_ERROR, "Autoconfig data invalid for SDL joystick '%s'", sdlJoyName); } ConfigDeleteSection("AutoConfig0"); /* we have to handle the unfortunate case of a USB device mapping more than > 1 controller */ if (ControllersFound > 1) { for (j = 1; j < ControllersFound; j++) { char AutoSectionName[32]; sprintf(AutoSectionName, "AutoConfig%i", j); /* if this would be > 4th controller, then just delete the auto-config */ if (n64CtrlStart + j >= 4) { ConfigDeleteSection(AutoSectionName); continue; } /* look for another N64 controller that is in AUTO mode */ if (ControlMode[n64CtrlStart+j] == E_MODE_FULL_AUTO || (ControlMode[n64CtrlStart+j] == E_MODE_NAMED_AUTO && strncmp(DeviceName[n64CtrlStart+j], sdlJoyName, 255) == 0)) { sprintf(SectionName, "Input-SDL-Control%i", n64CtrlStart + j + 1); /* load our plugin joystick settings from the autoconfig */ if (load_controller_config(AutoSectionName, n64CtrlStart+j, sdlCtrlIdx) > 0) { /* copy the auto-config settings to the controller config section */ if (OrigControlMode[n64CtrlStart+j] == E_MODE_FULL_AUTO) auto_copy_inputconfig(AutoSectionName, SectionName, sdlJoyName); else auto_copy_inputconfig(AutoSectionName, SectionName, NULL); // don't overwrite 'name' parameter if original mode was "named auto" if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config with SDL joystick %i ('%s')", n64CtrlStart+j+1, sdlCtrlIdx, sdlJoyName); ActiveControllers++; /* set the local controller mode to Manual so that we won't re-configure this controller in the next loop */ ControlMode[n64CtrlStart+j] = E_MODE_MANUAL; } else { if (!bPreConfig) DebugMessage(M64MSG_ERROR, "Autoconfig data invalid for SDL device '%s'", sdlJoyName); } /* delete the autoconfig section */ ConfigDeleteSection(AutoSectionName); } } } return ActiveControllers; } /* global functions */ /* There are 4 special section parameters: version, mode, device, and name. There are also 24 regular * parameters: plugged, plugin, mouse, MouseSensitivity, DPad R/L/D/U, Start, Z/L/R Trigger, A/B button, * C Button R/L/D/U, Mempak/Rumblepak switch, X/Y Axis, AnalogDeadzone, AnalogPeak. * * The N64 controller configuration behavior is regulated by the 'mode' parameter. If this parameter is * 0 (Fully Manual), then all configuration data is loaded and parsed without changes or autoconfig from * the configuration section. Any errors or warnings are printed. If the mode parameter is 1 (Auto with * named SDL Device), then the code below searches through the available SDL joysticks for one which * matches with the 'name' parameter in the config section. If a match is found, then the corresponding * autoconfig is loaded and the regular parameters from the config section are updated with the * autoconfig'ed settings. If the mode parameter is 2 (Fully Auto), then the code below searches through * all available detected SDL joysticks to try and find an autoconfig for each. If an autoconfig match is * found, then it is loaded and all config parameters (including device, name, and the regular parameters) * are updated. * * This function is called with bPreConfig=true from the PluginStartup() function. The purpose of this * call is to load the 4 configuration sections with autoconfig data if necessary for a GUI front-end. * When we are called with bPreConfig=true, we should only print warning/error messages and not info/status. * This function is also called right before running the ROM game from InitiateControllers() with * bPreConfig=false. We should only print informational messages here, because we do not want to duplicate * console output with the console-ui front-end (since the PluginStart() and InitiateControllers() * functions are called in quick sequence from the console-ui). */ void load_configuration(int bPreConfig) { char SectionName[32]; int joy_plugged = 0; int n64CtrlIdx, sdlCtrlIdx, j; int sdlNumDevUsed = 0; int sdlDevicesUsed[4]; eModeType OrigControlMode[4], ControlMode[4]; int ControlDevice[4]; char DeviceName[4][256]; int ActiveControllers = 0; int sdlNumJoysticks = SDL_NumJoysticks(); float fVersion = 0.0f; const char *sdl_name; int ControllersFound = 0; /* tell user how many SDL joysticks are available */ if (!bPreConfig) DebugMessage(M64MSG_INFO, "%i SDL joysticks were found.", sdlNumJoysticks); /* loop through 4 N64 controllers, initializing and validating special section parameters */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { m64p_handle pConfig; /* reset the controller configuration */ clear_controller(n64CtrlIdx); /* Open the configuration section for this controller */ sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { // this should never happen DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'. Aborting...", SectionName); return; } /* Check version number, and if it doesn't match: delete the config section */ fVersion = 0.0f; if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS || ((int) fVersion) != ((int) CONFIG_VERSION)) { DebugMessage(M64MSG_WARNING, "Missing or incompatible config section '%s'. Clearing.", SectionName); ConfigDeleteSection(SectionName); // set local controller default parameters OrigControlMode[n64CtrlIdx] = ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK; DeviceName[n64CtrlIdx][0] = 0; // write blank config for GUI front-ends init_controller_config(n64CtrlIdx, "", E_MODE_FULL_AUTO); } else { if (ConfigGetParameter(pConfig, "mode", M64TYPE_INT, &OrigControlMode[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS || (int) OrigControlMode[n64CtrlIdx] < 0 || (int) OrigControlMode[n64CtrlIdx] > 2) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "Missing or invalid 'mode' parameter in config section '%s'. Setting to 2 (Fully Auto)", SectionName); OrigControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; } ControlMode[n64CtrlIdx] = OrigControlMode[n64CtrlIdx]; if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &ControlDevice[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "Missing 'device' parameter in config section '%s'. Setting to -1 (No joystick)", SectionName); ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK; } if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, DeviceName[n64CtrlIdx], 256) != M64ERR_SUCCESS) { DeviceName[n64CtrlIdx][0] = 0; } if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[n64CtrlIdx].control->Plugin, sizeof(int)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing 'plugin' parameter from config section %s. Setting to 2 (mempak).", SectionName); controller[n64CtrlIdx].control->Plugin = PLUGIN_MEMPAK; } } } /* loop through 4 N64 controllers and set up those in Fully Manual mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_MANUAL) continue; /* load the stored configuration (disregard any errors) */ sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); load_controller_config(SectionName, n64CtrlIdx, ControlDevice[n64CtrlIdx]); /* if this config uses an SDL joystick, mark it as used */ if (ControlDevice[n64CtrlIdx] == DEVICE_NO_JOYSTICK) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config with no SDL joystick (keyboard/mouse only)", n64CtrlIdx+1); } else { sdlDevicesUsed[sdlNumDevUsed++] = ControlDevice[n64CtrlIdx]; if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config for SDL joystick %i", n64CtrlIdx+1, ControlDevice[n64CtrlIdx]); } ActiveControllers++; } /* now loop through again, setting up those in Named Auto mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_NAMED_AUTO) continue; /* if name is empty, then use full auto mode instead */ if (DeviceName[n64CtrlIdx][0] == 0) { ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; continue; } sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); /* if user is looking for a keyboard, set that up */ if (strcasecmp(DeviceName[n64CtrlIdx], "Keyboard") == 0) { auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard"); if (load_controller_config("AutoConfig0", n64CtrlIdx, DEVICE_NO_JOYSTICK) > 0) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config for keyboard", n64CtrlIdx+1); /* copy the auto-config settings to the controller config section */ auto_copy_inputconfig("AutoConfig0", SectionName, "Keyboard"); ActiveControllers++; } else { DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid"); } ConfigDeleteSection("AutoConfig0"); continue; } /* search for an unused SDL device with the matching name */ for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++) { /* check if this one is in use */ int deviceAlreadyUsed = 0; for (j = 0; j < sdlNumDevUsed; j++) { if (sdlDevicesUsed[j] == sdlCtrlIdx) deviceAlreadyUsed = 1; } if (deviceAlreadyUsed) continue; /* check if the name matches */ sdl_name = get_sdl_joystick_name(sdlCtrlIdx); if (sdl_name != NULL && strncmp(DeviceName[n64CtrlIdx], sdl_name, 255) == 0) { /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */ int ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName); if (ControllersFound == 0) { // error: no auto-config found for this SDL device DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name); // mark this device as being used just so we don't complain about it again sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; // quit looking for SDL joysticks which match the name, because there's no valid autoconfig for that name. // this controller will be unused; skip to the next one break; } /* mark this sdl device as used */ sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; ActiveControllers += ControllersFound; break; } } /* if we didn't find a match for this joystick name, then set the controller to fully auto */ if (sdlCtrlIdx == sdlNumJoysticks) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "N64 Controller #%i: No SDL joystick found matching name '%s'. Using full auto mode.", n64CtrlIdx+1, DeviceName[n64CtrlIdx]); ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; } } /* Final loop through N64 controllers, setting up those in Full Auto mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_FULL_AUTO) continue; sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); /* search for an unused SDL device */ for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++) { /* check if this one is in use */ int deviceAlreadyUsed = 0; for (j = 0; j < sdlNumDevUsed; j++) { if (sdlDevicesUsed[j] == sdlCtrlIdx) deviceAlreadyUsed = 1; } if (deviceAlreadyUsed) continue; /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */ sdl_name = get_sdl_joystick_name(sdlCtrlIdx); ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName); if (!bPreConfig && ControllersFound == 0) { // error: no auto-config found for this SDL device DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name); // mark this device as being used just so we don't complain about it again sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; // keep trying more SDL devices to see if we can auto-config one for this N64 controller continue; } /* mark this sdl device as used */ sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; ActiveControllers += ControllersFound; break; } /* if this N64 controller was not activated, set device to -1 */ if (sdlCtrlIdx == sdlNumJoysticks) { m64p_handle section; if (ConfigOpenSection(SectionName, §ion) == M64ERR_SUCCESS) { const int iNoDevice = -1; ConfigSetParameter(section, "device", M64TYPE_INT, &iNoDevice); if (OrigControlMode[n64CtrlIdx] == E_MODE_FULL_AUTO) ConfigSetParameter(section, "name", M64TYPE_STRING, ""); } } } /* fallback to keyboard if no controllers were configured */ if (ActiveControllers == 0) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #1: Forcing default keyboard configuration"); auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard"); if (load_controller_config("AutoConfig0", 0, DEVICE_NO_JOYSTICK) > 0) { /* copy the auto-config settings to the controller config section */ if (OrigControlMode[0] == E_MODE_FULL_AUTO) auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", "Keyboard"); else auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", NULL); // don't overwrite 'name' parameter ActiveControllers++; } else { DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid"); } ConfigDeleteSection("AutoConfig0"); } /* see how many joysticks are plugged in */ joy_plugged = 0; for (j = 0; j < 4; j++) { if (controller[j].control->Present) joy_plugged++; } /* print out summary info message */ if (!bPreConfig) { if (joy_plugged > 0) { DebugMessage(M64MSG_INFO, "%i controller(s) found, %i plugged in and usable in the emulator", ActiveControllers, joy_plugged); } else { if (ActiveControllers == 0) DebugMessage(M64MSG_WARNING, "No joysticks/controllers found"); else DebugMessage(M64MSG_WARNING, "%i controllers found, but none were 'plugged in'", ActiveControllers); } } } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/config.h000066400000000000000000000032321436635717600214040ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - config.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __CONFIG_H__ #define __CONFIG_H__ #define CONFIG_VERSION 2.00 extern void load_configuration(int bPreConfig); #endif /* __CONFIG_H__ */ mupen64plus-input-sdl-2.5.9+55+g2129e94/src/osal_dynamiclib.h000066400000000000000000000033371436635717600232760ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - osal/dynamiclib.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2009 Richard Goedeken * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #if !defined(OSAL_DYNAMICLIB_H) #define OSAL_DYNAMICLIB_H #include "m64p_types.h" void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName); #endif /* #define OSAL_DYNAMICLIB_H */ mupen64plus-input-sdl-2.5.9+55+g2129e94/src/osal_dynamiclib_unix.c000066400000000000000000000034731436635717600243350ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-core - osal/dynamiclib_unix.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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" void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) { if (pccProcedureName == NULL) return NULL; return dlsym(LibHandle, pccProcedureName); } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/osal_dynamiclib_win32.c000066400000000000000000000060551436635717600243130ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-ui-console - osal_dynamiclib_win32.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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; } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/osal_preproc.h000066400000000000000000000037641436635717600226410ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - osal_preproc.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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 mupen64plus-input-sdl-2.5.9+55+g2129e94/src/plugin.c000066400000000000000000001161541436635717600214400ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - plugin.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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 #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.h" #include "version.h" #ifdef __linux__ #include #include #include #include #include #endif /* __linux__ */ #include /* defines for the force feedback rumble support */ #ifdef __linux__ #define BITS_PER_LONG (sizeof(long) * 8) #define OFF(x) ((x)%BITS_PER_LONG) #define BIT(x) (1UL<> OFF(bit)) & 1) #endif //__linux__ /* definitions of pointers to Core config functions */ ptr_ConfigOpenSection ConfigOpenSection = NULL; ptr_ConfigDeleteSection ConfigDeleteSection = NULL; ptr_ConfigListParameters ConfigListParameters = 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; /* global data definitions */ SController controller[4]; // 4 controllers /* static data definitions */ static void (*l_DebugCallback)(void *, int, const char *) = NULL; static void *l_DebugCallContext = NULL; static int l_PluginInit = 0; static int l_joyWasInit = 0; static int l_hapticWasInit = 0; static unsigned short button_bits[] = { 0x0001, // R_DPAD 0x0002, // L_DPAD 0x0004, // D_DPAD 0x0008, // U_DPAD 0x0010, // START_BUTTON 0x0020, // Z_TRIG 0x0040, // B_BUTTON 0x0080, // A_BUTTON 0x0100, // R_CBUTTON 0x0200, // L_CBUTTON 0x0400, // D_CBUTTON 0x0800, // U_CBUTTON 0x1000, // R_TRIG 0x2000, // L_TRIG 0x4000, // Mempak switch 0x8000 // Rumblepak switch }; static int romopen = 0; // is a rom opened static unsigned char myKeyState[SDL_NUM_SCANCODES]; #if __linux__ && !SDL_VERSION_ATLEAST(2,0,0) static struct ff_effect ffeffect[4]; static struct ff_effect ffstrong[4]; static struct ff_effect ffweak[4]; #endif //__linux__ /* Global functions */ void DebugMessage(int level, const char *message, ...) { char msgbuf[1024]; va_list args; if (l_DebugCallback == NULL) return; va_start(args, message); vsprintf(msgbuf, message, args); (*l_DebugCallback)(l_DebugCallContext, level, msgbuf); va_end(args); } static CONTROL temp_core_controlinfo[4]; /* Mupen64Plus plugin functions */ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, void (*DebugCallback)(void *, int, const char *)) { ptr_CoreGetAPIVersions CoreAPIVersionFunc; int i, ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; if (l_PluginInit) return M64ERR_ALREADY_INIT; /* first thing is to set the callback function for debug info */ 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; } /* 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"); 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 || !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; } /* reset controllers */ memset(controller, 0, sizeof(SController) * 4); for (i = 0; i < SDL_NUM_SCANCODES; i++) { myKeyState[i] = 0; } /* set CONTROL struct pointers to the temporary static array */ /* this small struct is used to tell the core whether each controller is plugged in, and what type of pak is connected */ /* we only need it so that we can call load_configuration below, to auto-config for a GUI front-end */ for (i = 0; i < 4; i++) controller[i].control = temp_core_controlinfo + i; /* initialize the joystick subsystem if necessary */ l_joyWasInit = SDL_WasInit(SDL_INIT_JOYSTICK); if (!l_joyWasInit) if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) { DebugMessage(M64MSG_ERROR, "Couldn't init SDL joystick subsystem: %s", SDL_GetError() ); return M64ERR_SYSTEM_FAIL; } /* read plugin config from core config database, auto-config if necessary and update core database */ load_configuration(1); 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; /* quit the joystick subsystem if necessary */ if (!l_joyWasInit) SDL_QuitSubSystem(SDL_INIT_JOYSTICK); 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; } /* Helper function to handle the SDL keys */ static void doSdlKeys(const unsigned char* keystate) { int c, b, axis_val, axis_max_val; static int grabmouse = 1, grabtoggled = 0; axis_max_val = 80; if (keystate[SDL_SCANCODE_RCTRL]) axis_max_val -= 40; if (keystate[SDL_SCANCODE_RSHIFT]) axis_max_val -= 25; for( c = 0; c < 4; c++ ) { for( b = 0; b < 16; b++ ) { if( controller[c].button[b].key == SDL_SCANCODE_UNKNOWN || ((int) controller[c].button[b].key) < 0) continue; if( keystate[controller[c].button[b].key] ) controller[c].buttons.Value |= button_bits[b]; } for( b = 0; b < 2; b++ ) { // from the N64 func ref: The 3D Stick data is of type signed char and in // the range between 80 and -80. (32768 / 409 = ~80.1) if( b == 0 ) axis_val = controller[c].buttons.X_AXIS; else axis_val = -controller[c].buttons.Y_AXIS; if( controller[c].axis[b].key_a != SDL_SCANCODE_UNKNOWN && ((int) controller[c].axis[b].key_a) > 0) if( keystate[controller[c].axis[b].key_a] ) axis_val = -axis_max_val; if( controller[c].axis[b].key_b != SDL_SCANCODE_UNKNOWN && ((int) controller[c].axis[b].key_b) > 0) if( keystate[controller[c].axis[b].key_b] ) axis_val = axis_max_val; if( b == 0 ) controller[c].buttons.X_AXIS = axis_val; else controller[c].buttons.Y_AXIS = -axis_val; } // sqrt-2 fix for too-fast diagonal movement if (abs(controller[c].buttons.X_AXIS) == axis_max_val && abs(controller[c].buttons.Y_AXIS) == axis_max_val) { controller[c].buttons.X_AXIS = (int) (controller[c].buttons.X_AXIS / 1.41421356f); controller[c].buttons.Y_AXIS = (int) (controller[c].buttons.Y_AXIS / 1.41421356f); } if (controller[c].mouse) { if (keystate[SDL_SCANCODE_LCTRL] && keystate[SDL_SCANCODE_LALT]) { if (!grabtoggled) { grabtoggled = 1; grabmouse = !grabmouse; // grab/ungrab mouse #if SDL_VERSION_ATLEAST(2,0,0) SDL_SetRelativeMouseMode(grabmouse ? SDL_TRUE : SDL_FALSE); #else SDL_WM_GrabInput( grabmouse ? SDL_GRAB_ON : SDL_GRAB_OFF ); #endif SDL_ShowCursor( grabmouse ? 0 : 1 ); } } else grabtoggled = 0; } } } static unsigned char DataCRC( unsigned char *Data, int iLenght ) { unsigned char Remainder = Data[0]; int iByte = 1; unsigned char bBit = 0; while( iByte <= iLenght ) { int HighBit = ((Remainder & 0x80) != 0); Remainder = Remainder << 1; Remainder += ( iByte < iLenght && Data[iByte] & (0x80 >> bBit )) ? 1 : 0; Remainder ^= (HighBit) ? 0x85 : 0; bBit++; iByte += bBit/8; bBit %= 8; } return Remainder; } /****************************************************************** Function: ControllerCommand Purpose: To process the raw data that has just been sent to a specific controller. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data, or the plugin is set to raw the data that is being processed looks like this: initilize controller: 01 03 00 FF FF FF read controller: 01 04 01 FF FF FF FF *******************************************************************/ EXPORT void CALL ControllerCommand(int Control, unsigned char *Command) { unsigned char *Data = &Command[5]; if (Control == -1) return; switch (Command[2]) { case RD_GETSTATUS: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Get status"); #endif break; case RD_READKEYS: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Read keys"); #endif break; case RD_READPAK: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Read pak"); #endif if (controller[Control].control->Plugin == PLUGIN_RAW) { unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0); if(( dwAddress >= 0x8000 ) && ( dwAddress < 0x9000 ) ) memset( Data, 0x80, 32 ); else memset( Data, 0x00, 32 ); Data[32] = DataCRC( Data, 32 ); } break; case RD_WRITEPAK: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Write pak"); #endif if (controller[Control].control->Plugin == PLUGIN_RAW) { unsigned int dwAddress = (Command[3] << 8) + (Command[4] & 0xE0); if (dwAddress == PAK_IO_RUMBLE && *Data) DebugMessage(M64MSG_VERBOSE, "Triggering rumble pack."); #if SDL_VERSION_ATLEAST(2,0,0) if(dwAddress == PAK_IO_RUMBLE && controller[Control].event_joystick) { if (*Data) { SDL_HapticRumblePlay(controller[Control].event_joystick, 1, SDL_HAPTIC_INFINITY); } else { SDL_HapticRumbleStop(controller[Control].event_joystick); } } #elif __linux__ struct input_event play; if( dwAddress == PAK_IO_RUMBLE && controller[Control].event_joystick != 0) { if( *Data ) { play.type = EV_FF; play.code = ffeffect[Control].id; play.value = 1; if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1) perror("Error starting rumble effect"); } else { play.type = EV_FF; play.code = ffeffect[Control].id; play.value = 0; if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1) perror("Error stopping rumble effect"); } } #endif //__linux__ Data[32] = DataCRC( Data, 32 ); } break; case RD_RESETCONTROLLER: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Reset controller"); #endif break; case RD_READEEPROM: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Read eeprom"); #endif break; case RD_WRITEEPROM: #ifdef _DEBUG DebugMessage(M64MSG_INFO, "Write eeprom"); #endif break; } } /****************************************************************** Function: GetKeys Purpose: To get the current state of the controllers buttons. input: - Controller Number (0 to 3) - A pointer to a BUTTONS structure to be filled with the controller state. output: none *******************************************************************/ EXPORT void CALL GetKeys( int Control, BUTTONS *Keys ) { static int mousex_residual = 0; static int mousey_residual = 0; int b, axis_val; SDL_Event event; unsigned char mstate; SDL_PumpEvents(); // Handle keyboard input first doSdlKeys(SDL_GetKeyboardState(NULL)); doSdlKeys(myKeyState); for ( b = 0; b < 4; ++b ) { if (controller[b].device >= 0) { #if SDL_VERSION_ATLEAST(2,0,0) if (!SDL_JoystickGetAttached(controller[b].joystick)) #else if (!SDL_JoystickOpened(controller[b].device)) #endif controller[b].joystick = SDL_JoystickOpen(controller[b].device); } } // read joystick state SDL_JoystickUpdate(); if( controller[Control].device >= 0 ) { for( b = 0; b < 16; b++ ) { if( controller[Control].button[b].button >= 0 ) if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].button[b].button ) ) controller[Control].buttons.Value |= button_bits[b]; if( controller[Control].button[b].axis >= 0 ) { int deadzone = controller[Control].button[b].axis_deadzone; axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].button[b].axis ); if (deadzone < 0) deadzone = 16384; /* default */ if( (controller[Control].button[b].axis_dir < 0) && (axis_val <= -deadzone) ) controller[Control].buttons.Value |= button_bits[b]; else if( (controller[Control].button[b].axis_dir > 0) && (axis_val >= deadzone) ) controller[Control].buttons.Value |= button_bits[b]; } if( controller[Control].button[b].hat >= 0 ) { if( controller[Control].button[b].hat_pos > 0 ) if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].button[b].hat ) & controller[Control].button[b].hat_pos ) controller[Control].buttons.Value |= button_bits[b]; } } int iX = controller[Control].buttons.X_AXIS; int iY = controller[Control].buttons.Y_AXIS; for( b = 0; b < 2; b++ ) { /* from the N64 func ref: The 3D Stick data is of type signed char and in the range between -80 and +80 */ int deadzone = controller[Control].axis_deadzone[b]; int range = controller[Control].axis_peak[b] - controller[Control].axis_deadzone[b]; /* skip this axis if the deadzone/peak values are invalid */ if (deadzone < 0 || range < 1) continue; if( b == 0 ) axis_val = iX; else axis_val = -iY; if( controller[Control].axis[b].axis_a >= 0 ) /* up and left for N64 */ { int joy_val = SDL_JoystickGetAxis(controller[Control].joystick, controller[Control].axis[b].axis_a); int axis_dir = controller[Control].axis[b].axis_dir_a; if (joy_val * axis_dir > deadzone) axis_val = -((abs(joy_val) - deadzone) * 80 / range); } if( controller[Control].axis[b].axis_b >= 0 ) /* down and right for N64 */ { int joy_val = SDL_JoystickGetAxis(controller[Control].joystick, controller[Control].axis[b].axis_b); int axis_dir = controller[Control].axis[b].axis_dir_b; if (joy_val * axis_dir > deadzone) axis_val = ((abs(joy_val) - deadzone) * 80 / range); } if( controller[Control].axis[b].hat >= 0 ) { if( controller[Control].axis[b].hat_pos_a >= 0 ) if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_a ) axis_val = -80; if( controller[Control].axis[b].hat_pos_b >= 0 ) if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_b ) axis_val = 80; } if( controller[Control].axis[b].button_a >= 0 ) if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_a ) ) axis_val = -80; if( controller[Control].axis[b].button_b >= 0 ) if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_b ) ) axis_val = 80; if( b == 0 ) iX = axis_val; else iY = -axis_val; } /* store the result */ if (iX < -80) iX = -80; if (iX > 80) iX = 80; if (iY < -80) iY = -80; if (iY > 80) iY = 80; controller[Control].buttons.X_AXIS = iX; controller[Control].buttons.Y_AXIS = iY; } // process mouse events mstate = SDL_GetMouseState( NULL, NULL ); for( b = 0; b < 16; b++ ) { if( controller[Control].button[b].mouse < 1 ) continue; if( mstate & SDL_BUTTON(controller[Control].button[b].mouse) ) controller[Control].buttons.Value |= button_bits[b]; } if (controller[Control].mouse) { #if SDL_VERSION_ATLEAST(2,0,0) if (SDL_GetRelativeMouseMode()) #else if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON) #endif { #if SDL_VERSION_ATLEAST(1,3,0) while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) == 1) #else while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION)) == 1) #endif { #if SDL_VERSION_ATLEAST(2,0,0) int w, h; SDL_Window *focus; #endif if (event.motion.xrel) { mousex_residual += (int) (event.motion.xrel * controller[Control].mouse_sens[0]); } if (event.motion.yrel) { mousey_residual += (int) (event.motion.yrel * controller[Control].mouse_sens[1]); } #if SDL_VERSION_ATLEAST(2,0,0) focus = SDL_GetKeyboardFocus(); if (focus) { SDL_GetWindowSize(focus, &w, &h); SDL_WarpMouseInWindow(focus, w / 2, h / 2); } else { mousex_residual = 0; mousey_residual = 0; } #endif } /* store the result */ int iX = mousex_residual; int iY = -mousey_residual; if (iX < -80) iX = -80; if (iX > 80) iX = 80; if (iY < -80) iY = -80; if (iY > 80) iY = 80; controller[Control].buttons.X_AXIS = iX; controller[Control].buttons.Y_AXIS = iY; /* the mouse x/y values decay exponentially (returns to center), unless the left "Windows" key is held down */ if (!myKeyState[SDL_SCANCODE_LGUI]) { mousex_residual = (mousex_residual * 224) / 256; mousey_residual = (mousey_residual * 224) / 256; } } else { mousex_residual = 0; mousey_residual = 0; } } #ifdef _DEBUG DebugMessage(M64MSG_VERBOSE, "Controller #%d value: 0x%8.8X", Control, *(int *)&controller[Control].buttons ); #endif *Keys = controller[Control].buttons; /* handle mempack / rumblepak switching (only if rumble is active on joystick) */ #if SDL_VERSION_ATLEAST(2,0,0) if (controller[Control].event_joystick) { static unsigned int SwitchPackTime[4] = {0, 0, 0, 0}, SwitchPackType[4] = {0, 0, 0, 0}; if (controller[Control].buttons.Value & button_bits[14]) { SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given SwitchPackType[Control] = PLUGIN_MEMPAK; // type of new pack to insert controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack SDL_HapticRumblePlay(controller[Control].event_joystick, 0.5, 500); } if (controller[Control].buttons.Value & button_bits[15]) { SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given SwitchPackType[Control] = PLUGIN_RAW; // type of new pack to insert controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack SDL_HapticRumblePlay(controller[Control].event_joystick, 1, 500); } // handle inserting new pack if the time has arrived if (SwitchPackTime[Control] != 0 && (SDL_GetTicks() - SwitchPackTime[Control]) >= 1000) { SDL_HapticRumbleStop(controller[Control].event_joystick); controller[Control].control->Plugin = SwitchPackType[Control]; SwitchPackTime[Control] = 0; } } #elif __linux__ if (controller[Control].event_joystick != 0) { struct input_event play; static unsigned int SwitchPackTime[4] = {0, 0, 0, 0}, SwitchPackType[4] = {0, 0, 0, 0}; // when the user switches packs, we should mimick the act of removing 1 pack, and then inserting another 1 second later if (controller[Control].buttons.Value & button_bits[14]) { SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given SwitchPackType[Control] = PLUGIN_MEMPAK; // type of new pack to insert controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack play.type = EV_FF; play.code = ffweak[Control].id; play.value = 1; if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1) perror("Error starting rumble effect"); } if (controller[Control].buttons.Value & button_bits[15]) { SwitchPackTime[Control] = SDL_GetTicks(); // time at which the 'switch pack' command was given SwitchPackType[Control] = PLUGIN_RAW; // type of new pack to insert controller[Control].control->Plugin = PLUGIN_NONE;// remove old pack play.type = EV_FF; play.code = ffstrong[Control].id; play.value = 1; if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1) perror("Error starting rumble effect"); } // handle inserting new pack if the time has arrived if (SwitchPackTime[Control] != 0 && (SDL_GetTicks() - SwitchPackTime[Control]) >= 1000) { controller[Control].control->Plugin = SwitchPackType[Control]; SwitchPackTime[Control] = 0; } } #endif /* __linux__ */ controller[Control].buttons.Value = 0; } static void InitiateJoysticks(int cntrl) { if (controller[cntrl].device >= 0) { controller[cntrl].joystick = SDL_JoystickOpen(controller[cntrl].device); if (!controller[cntrl].joystick) DebugMessage(M64MSG_WARNING, "Couldn't open joystick for controller #%d: %s", cntrl + 1, SDL_GetError()); } else { controller[cntrl].joystick = NULL; } } static void DeinitJoystick(int cntrl) { #if SDL_VERSION_ATLEAST(2,0,0) if (controller[cntrl].joystick) { SDL_JoystickClose(controller[cntrl].joystick); controller[cntrl].joystick = NULL; } #endif } static void InitiateRumble(int cntrl) { #if SDL_VERSION_ATLEAST(2,0,0) l_hapticWasInit = SDL_WasInit(SDL_INIT_HAPTIC); if (!l_hapticWasInit) { if (SDL_InitSubSystem(SDL_INIT_HAPTIC) == -1) { DebugMessage(M64MSG_ERROR, "Couldn't init SDL haptic subsystem: %s", SDL_GetError() ); return; } } controller[cntrl].event_joystick = SDL_HapticOpenFromJoystick(controller[cntrl].joystick); if (!controller[cntrl].event_joystick) { DebugMessage(M64MSG_WARNING, "Couldn't open rumble support for joystick #%i", cntrl + 1); return; } if (SDL_HapticRumbleSupported(controller[cntrl].event_joystick) == SDL_FALSE) { SDL_HapticClose(controller[cntrl].event_joystick); controller[cntrl].event_joystick = NULL; DebugMessage(M64MSG_WARNING, "Joystick #%i doesn't support rumble effect", cntrl + 1); return; } if (SDL_HapticRumbleInit(controller[cntrl].event_joystick) != 0) { SDL_HapticClose(controller[cntrl].event_joystick); controller[cntrl].event_joystick = NULL; DebugMessage(M64MSG_WARNING, "Rumble initialization failed for Joystick #%i", cntrl + 1); return; } DebugMessage(M64MSG_INFO, "Rumble activated on N64 joystick #%i", cntrl + 1); #elif __linux__ DIR* dp; struct dirent* ep; unsigned long features[4]; char temp[128]; char temp2[128]; int iFound = 0; controller[cntrl].event_joystick = 0; sprintf(temp,"/sys/class/input/js%d/device", controller[cntrl].device); dp = opendir(temp); if(dp==NULL) return; while ((ep=readdir(dp))) { if (strncmp(ep->d_name, "event",5)==0) { sprintf(temp, "/dev/input/%s", ep->d_name); iFound = 1; break; } else if(strncmp(ep->d_name,"input:event", 11)==0) { sscanf(ep->d_name, "input:%s", temp2); sprintf(temp, "/dev/input/%s", temp2); iFound = 1; break; } else if(strncmp(ep->d_name,"input:input", 11)==0) { strcat(temp, "/"); strcat(temp, ep->d_name); closedir (dp); dp = opendir(temp); if(dp==NULL) return; } } closedir(dp); if (!iFound) { DebugMessage(M64MSG_WARNING, "Couldn't find input event for rumble support."); return; } controller[cntrl].event_joystick = open(temp, O_RDWR); if(controller[cntrl].event_joystick==-1) { DebugMessage(M64MSG_WARNING, "Couldn't open device file '%s' for rumble support.", temp); controller[cntrl].event_joystick = 0; return; } if(ioctl(controller[cntrl].event_joystick, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features)==-1) { DebugMessage(M64MSG_WARNING, "Linux kernel communication failed for force feedback (rumble).\n"); controller[cntrl].event_joystick = 0; return; } if(!test_bit(FF_RUMBLE, features)) { DebugMessage(M64MSG_WARNING, "No rumble supported on N64 joystick #%i", cntrl + 1); controller[cntrl].event_joystick = 0; return; } ffeffect[cntrl].type = FF_RUMBLE; ffeffect[cntrl].id = -1; ffeffect[cntrl].u.rumble.strong_magnitude = 0xFFFF; ffeffect[cntrl].u.rumble.weak_magnitude = 0xFFFF; ffeffect[cntrl].replay.length = 0x7fff; // hack: xboxdrv is buggy and doesn't support infinite replay. // when xboxdrv is fixed (https://github.com/Grumbel/xboxdrv/issues/47), // please remove this ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffeffect[cntrl]); ffstrong[cntrl].type = FF_RUMBLE; ffstrong[cntrl].id = -1; ffstrong[cntrl].u.rumble.strong_magnitude = 0xFFFF; ffstrong[cntrl].u.rumble.weak_magnitude = 0x0000; ffstrong[cntrl].replay.length = 500; ffstrong[cntrl].replay.delay = 0; ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffstrong[cntrl]); ffweak[cntrl].type = FF_RUMBLE; ffweak[cntrl].id = -1; ffweak[cntrl].u.rumble.strong_magnitude = 0x0000; ffweak[cntrl].u.rumble.weak_magnitude = 0xFFFF; ffweak[cntrl].replay.length = 500; ffweak[cntrl].replay.delay = 0; ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffweak[cntrl]); DebugMessage(M64MSG_INFO, "Rumble activated on N64 joystick #%i", cntrl + 1); #endif /* __linux__ */ } static void DeinitRumble(int cntrl) { #if SDL_VERSION_ATLEAST(2,0,0) /* quit the haptic subsystem if necessary */ if (!l_hapticWasInit) SDL_QuitSubSystem(SDL_INIT_HAPTIC); if (controller[cntrl].event_joystick) { SDL_HapticClose(controller[cntrl].event_joystick); controller[cntrl].event_joystick = NULL; } #endif } /****************************************************************** 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; // reset controllers memset( controller, 0, sizeof( SController ) * 4 ); for ( i = 0; i < SDL_NUM_SCANCODES; i++) { myKeyState[i] = 0; } // set our CONTROL struct pointers to the array that was passed in to this function from the core // this small struct tells the core whether each controller is plugged in, and what type of pak is connected for (i = 0; i < 4; i++) controller[i].control = ControlInfo.Controls + i; // read configuration load_configuration(0); for( i = 0; i < 4; i++ ) { // test for rumble support for this joystick InitiateJoysticks(i); InitiateRumble(i); // if rumble not supported, switch to mempack if (controller[i].control->Plugin == PLUGIN_RAW && controller[i].event_joystick == 0) controller[i].control->Plugin = PLUGIN_MEMPAK; DeinitRumble(i); DeinitJoystick(i); } DebugMessage(M64MSG_INFO, "%s version %i.%i.%i initialized.", PLUGIN_NAME, VERSION_PRINTF_SPLIT(PLUGIN_VERSION)); } /****************************************************************** Function: ReadController Purpose: To process the raw data in the pif ram that is about to be read. input: - Controller Number (0 to 3) and -1 signalling end of processing the pif ram. - Pointer of data to be processed. output: none note: This function is only needed if the DLL is allowing raw data. *******************************************************************/ EXPORT void CALL ReadController(int Control, unsigned char *Command) { #ifdef _DEBUG if (Command != NULL) DebugMessage(M64MSG_INFO, "Raw Read (cont=%d): %02X %02X %02X %02X %02X %02X", Control, Command[0], Command[1], Command[2], Command[3], Command[4], Command[5]); #endif } /****************************************************************** Function: RomClosed Purpose: This function is called when a rom is closed. input: none output: none *******************************************************************/ EXPORT void CALL RomClosed(void) { int i; // close joysticks for( i = 0; i < 4; i++ ) { DeinitRumble(i); DeinitJoystick(i); } // release/ungrab mouse #if SDL_VERSION_ATLEAST(2,0,0) SDL_SetRelativeMouseMode(SDL_FALSE); #else SDL_WM_GrabInput( SDL_GRAB_OFF ); #endif SDL_ShowCursor( 1 ); romopen = 0; } /****************************************************************** Function: RomOpen Purpose: This function is called when a rom is open. (from the emulation thread) input: none output: none *******************************************************************/ EXPORT int CALL RomOpen(void) { int i; // open joysticks for (i = 0; i < 4; i++) { InitiateJoysticks(i); InitiateRumble(i); } // grab mouse if (controller[0].mouse || controller[1].mouse || controller[2].mouse || controller[3].mouse) { SDL_ShowCursor( 0 ); #if SDL_VERSION_ATLEAST(2,0,0) if (SDL_SetRelativeMouseMode(SDL_TRUE) < 0) { DebugMessage(M64MSG_WARNING, "Couldn't grab input! Mouse support won't work!"); } #else if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON) { DebugMessage(M64MSG_WARNING, "Couldn't grab input! Mouse support won't work!"); } #endif } romopen = 1; return 1; } /****************************************************************** Function: SDL_KeyDown Purpose: To pass the SDL_KeyDown message from the emulator to the plugin. input: keymod and keysym of the SDL_KEYDOWN message. output: none *******************************************************************/ EXPORT void CALL SDL_KeyDown(int keymod, int keysym) { myKeyState[keysym] = 1; } /****************************************************************** Function: SDL_KeyUp Purpose: To pass the SDL_KeyUp message from the emulator to the plugin. input: keymod and keysym of the SDL_KEYUP message. output: none *******************************************************************/ EXPORT void CALL SDL_KeyUp(int keymod, int keysym) { myKeyState[keysym] = 0; } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/plugin.h000066400000000000000000000155541436635717600214470ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - plugin.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2008-2009 Richard Goedeken * * Copyright (C) 2008 Tillin9 * * Copyright (C) 2002 Blight * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef __PLUGIN_H__ #define __PLUGIN_H__ #if defined(__GNUC__) #define ATTR_FMT(fmtpos, attrpos) __attribute__ ((format (printf, fmtpos, attrpos))) #else #define ATTR_FMT(fmtpos, attrpos) #endif #include #include #if ! SDL_VERSION_ATLEAST(1,3,0) #define SDL_GetKeyboardState SDL_GetKeyState #define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN #define SDL_NUM_SCANCODES SDLK_LAST #define SDL_SCANCODE_RCTRL SDLK_RCTRL #define SDL_SCANCODE_RSHIFT SDLK_RSHIFT #define SDL_SCANCODE_LCTRL SDLK_LCTRL #define SDL_SCANCODE_LALT SDLK_LALT #define SDL_SCANCODE_LGUI SDLK_LSUPER #define SDL_Scancode SDLKey #endif #if SDL_VERSION_ATLEAST(2,0,0) static inline const char* _SDL_JoystickName(int device_index) { SDL_Joystick *joystick; const char *name; static char JoyName[256]; joystick = SDL_JoystickOpen(device_index); if (!joystick) return NULL; name = SDL_JoystickName(joystick); if (name) { strncpy(JoyName, name, 255); JoyName[255] = 0; } SDL_JoystickClose(joystick); return JoyName; } #define SDL_JoystickName(device_index) _SDL_JoystickName(device_index) #endif #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 enum EButton { R_DPAD = 0, L_DPAD, D_DPAD, U_DPAD, START_BUTTON, Z_TRIG, B_BUTTON, A_BUTTON, R_CBUTTON, L_CBUTTON, D_CBUTTON, U_CBUTTON, R_TRIG, L_TRIG, MEMPAK, RUMBLEPAK, X_AXIS, Y_AXIS, NUM_BUTTONS }; typedef struct { int button; // button index; -1 if notassigned SDL_Scancode key; // sdl keysym; SDL_SCANCODE_UNKNOWN if not assigned int axis, axis_dir; // aixs + direction (i.e. 0, 1 = X Axis +; 0, -1 = X Axis -); -1 if notassigned int axis_deadzone; // -1 for default, or >= 0 for custom value int hat, hat_pos; // hat + hat position; -1 if not assigned int mouse; // mouse button } SButtonMap; typedef struct { int button_a, button_b; // up/down or left/right; -1 if not assigned SDL_Scancode key_a, key_b; // up/down or left/right; SDL_SCANCODE_UNKNOWN if not assigned int axis_a, axis_b; // axis index; -1 if not assigned int axis_dir_a, axis_dir_b; // direction (1 = X+, 0, -1 = X-) int hat, hat_pos_a, hat_pos_b; // hat + hat position up/down and left/right; -1 if not assigned } SAxisMap; typedef struct { CONTROL *control; // pointer to CONTROL struct in Core library BUTTONS buttons; // mappings SButtonMap button[16]; // 14 buttons; in the order of EButton + mempak/rumblepak switches SAxisMap axis[2]; // 2 axis int device; // joystick device; -1 = keyboard; -2 = none int mouse; // mouse enabled: 0 = no; 1 = yes SDL_Joystick *joystick; // SDL joystick device #if SDL_VERSION_ATLEAST(2,0,0) SDL_Haptic *event_joystick; // the sdl device for force feeback #else int event_joystick; // the /dev/input/eventX device for force feeback #endif int axis_deadzone[2]; // minimum absolute value before analog movement is recognized int axis_peak[2]; // highest analog value returned by SDL, used for scaling float mouse_sens[2]; // mouse sensitivity } SController; /* global data definitions */ extern SController controller[4]; // 4 controllers /* global function definitions */ extern void DebugMessage(int level, const char *message, ...) ATTR_FMT(2,3); /* 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_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__ mupen64plus-input-sdl-2.5.9+55+g2129e94/src/sdl_key_converter.c000066400000000000000000001075741436635717600236710ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - sdl_key_converter.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2013 Mupen64plus development team * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "sdl_key_converter.h" #include #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) uint16_t sdl_keysym2scancode(uint16_t keysym) { static const uint16_t keysym2scancode[323] = { 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x002au, /* SDLK_BACKSPACE -> SDL_SCANCODE_BACKSPACE */ 0x002bu, /* SDLK_TAB -> SDL_SCANCODE_TAB */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x009cu, /* SDLK_CLEAR -> SDL_SCANCODE_CLEAR */ 0x0028u, /* SDLK_RETURN -> SDL_SCANCODE_RETURN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0048u, /* SDLK_PAUSE -> SDL_SCANCODE_PAUSE */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0029u, /* SDLK_ESCAPE -> SDL_SCANCODE_ESCAPE */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x002cu, /* SDLK_SPACE -> SDL_SCANCODE_SPACE */ 0x0000u, /* SDLK_EXCLAIM -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_QUOTEDBL -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_HASH -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_DOLLAR -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_AMPERSAND -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_QUOTE -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_LEFTPAREN -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_RIGHTPAREN -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_ASTERISK -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_PLUS -> SDL_SCANCODE_UNKNOWN */ 0x0036u, /* SDLK_COMMA -> SDL_SCANCODE_COMMA */ 0x002du, /* SDLK_MINUS -> SDL_SCANCODE_MINUS */ 0x0037u, /* SDLK_PERIOD -> SDL_SCANCODE_PERIOD */ 0x0038u, /* SDLK_SLASH -> SDL_SCANCODE_SLASH */ 0x0027u, /* SDLK_0 -> SDL_SCANCODE_0 */ 0x001eu, /* SDLK_1 -> SDL_SCANCODE_1 */ 0x001fu, /* SDLK_2 -> SDL_SCANCODE_2 */ 0x0020u, /* SDLK_3 -> SDL_SCANCODE_3 */ 0x0021u, /* SDLK_4 -> SDL_SCANCODE_4 */ 0x0022u, /* SDLK_5 -> SDL_SCANCODE_5 */ 0x0023u, /* SDLK_6 -> SDL_SCANCODE_6 */ 0x0024u, /* SDLK_7 -> SDL_SCANCODE_7 */ 0x0025u, /* SDLK_8 -> SDL_SCANCODE_8 */ 0x0026u, /* SDLK_9 -> SDL_SCANCODE_9 */ 0x0000u, /* SDLK_COLON -> SDL_SCANCODE_UNKNOWN */ 0x0033u, /* SDLK_SEMICOLON -> SDL_SCANCODE_SEMICOLON */ 0x0000u, /* SDLK_LESS -> SDL_SCANCODE_UNKNOWN */ 0x002eu, /* SDLK_EQUALS -> SDL_SCANCODE_EQUALS */ 0x0000u, /* SDLK_GREATER -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_QUESTION -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_AT -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x002fu, /* SDLK_LEFTBRACKET -> SDL_SCANCODE_LEFTBRACKET */ 0x0031u, /* SDLK_BACKSLASH -> SDL_SCANCODE_BACKSLASH */ 0x0030u, /* SDLK_RIGHTBRACKET -> SDL_SCANCODE_RIGHTBRACKET */ 0x0000u, /* SDLK_CARET -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_UNDERSCORE -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_BACKQUOTE -> SDL_SCANCODE_UNKNOWN */ 0x0004u, /* SDLK_a -> SDL_SCANCODE_A */ 0x0005u, /* SDLK_b -> SDL_SCANCODE_B */ 0x0006u, /* SDLK_c -> SDL_SCANCODE_C */ 0x0007u, /* SDLK_d -> SDL_SCANCODE_D */ 0x0008u, /* SDLK_e -> SDL_SCANCODE_E */ 0x0009u, /* SDLK_f -> SDL_SCANCODE_F */ 0x000au, /* SDLK_g -> SDL_SCANCODE_G */ 0x000bu, /* SDLK_h -> SDL_SCANCODE_H */ 0x000cu, /* SDLK_i -> SDL_SCANCODE_I */ 0x000du, /* SDLK_j -> SDL_SCANCODE_J */ 0x000eu, /* SDLK_k -> SDL_SCANCODE_K */ 0x000fu, /* SDLK_l -> SDL_SCANCODE_L */ 0x0010u, /* SDLK_m -> SDL_SCANCODE_M */ 0x0011u, /* SDLK_n -> SDL_SCANCODE_N */ 0x0012u, /* SDLK_o -> SDL_SCANCODE_O */ 0x0013u, /* SDLK_p -> SDL_SCANCODE_P */ 0x0014u, /* SDLK_q -> SDL_SCANCODE_Q */ 0x0015u, /* SDLK_r -> SDL_SCANCODE_R */ 0x0016u, /* SDLK_s -> SDL_SCANCODE_S */ 0x0017u, /* SDLK_t -> SDL_SCANCODE_T */ 0x0018u, /* SDLK_u -> SDL_SCANCODE_U */ 0x0019u, /* SDLK_v -> SDL_SCANCODE_V */ 0x001au, /* SDLK_w -> SDL_SCANCODE_W */ 0x001bu, /* SDLK_x -> SDL_SCANCODE_X */ 0x001cu, /* SDLK_y -> SDL_SCANCODE_Y */ 0x001du, /* SDLK_z -> SDL_SCANCODE_Z */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x004cu, /* SDLK_DELETE -> SDL_SCANCODE_DELETE */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_0 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_1 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_2 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_3 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_4 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_5 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_6 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_7 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_8 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_9 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_10 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_11 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_12 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_13 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_14 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_15 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_16 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_17 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_18 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_19 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_20 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_21 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_22 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_23 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_24 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_25 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_26 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_27 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_28 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_29 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_30 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_31 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_32 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_33 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_34 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_35 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_36 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_37 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_38 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_39 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_40 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_41 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_42 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_43 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_44 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_45 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_46 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_47 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_48 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_49 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_50 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_51 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_52 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_53 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_54 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_55 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_56 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_57 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_58 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_59 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_60 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_61 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_62 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_63 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_64 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_65 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_66 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_67 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_68 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_69 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_70 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_71 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_72 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_73 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_74 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_75 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_76 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_77 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_78 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_79 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_80 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_81 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_82 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_83 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_84 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_85 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_86 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_87 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_88 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_89 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_90 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_91 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_92 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_93 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_94 -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_WORLD_95 -> SDL_SCANCODE_UNKNOWN */ 0x0062u, /* SDLK_KP0 -> SDL_SCANCODE_KP_0 */ 0x0059u, /* SDLK_KP1 -> SDL_SCANCODE_KP_1 */ 0x005au, /* SDLK_KP2 -> SDL_SCANCODE_KP_2 */ 0x005bu, /* SDLK_KP3 -> SDL_SCANCODE_KP_3 */ 0x005cu, /* SDLK_KP4 -> SDL_SCANCODE_KP_4 */ 0x005du, /* SDLK_KP5 -> SDL_SCANCODE_KP_5 */ 0x005eu, /* SDLK_KP6 -> SDL_SCANCODE_KP_6 */ 0x005fu, /* SDLK_KP7 -> SDL_SCANCODE_KP_7 */ 0x0060u, /* SDLK_KP8 -> SDL_SCANCODE_KP_8 */ 0x0061u, /* SDLK_KP9 -> SDL_SCANCODE_KP_9 */ 0x0063u, /* SDLK_KP_PERIOD -> SDL_SCANCODE_KP_PERIOD */ 0x0054u, /* SDLK_KP_DIVIDE -> SDL_SCANCODE_KP_DIVIDE */ 0x0055u, /* SDLK_KP_MULTIPLY -> SDL_SCANCODE_KP_MULTIPLY */ 0x0056u, /* SDLK_KP_MINUS -> SDL_SCANCODE_KP_MINUS */ 0x0057u, /* SDLK_KP_PLUS -> SDL_SCANCODE_KP_PLUS */ 0x0058u, /* SDLK_KP_ENTER -> SDL_SCANCODE_KP_ENTER */ 0x0067u, /* SDLK_KP_EQUALS -> SDL_SCANCODE_KP_EQUALS */ 0x0052u, /* SDLK_UP -> SDL_SCANCODE_UP */ 0x0051u, /* SDLK_DOWN -> SDL_SCANCODE_DOWN */ 0x004fu, /* SDLK_RIGHT -> SDL_SCANCODE_RIGHT */ 0x0050u, /* SDLK_LEFT -> SDL_SCANCODE_LEFT */ 0x0049u, /* SDLK_INSERT -> SDL_SCANCODE_INSERT */ 0x004au, /* SDLK_HOME -> SDL_SCANCODE_HOME */ 0x004du, /* SDLK_END -> SDL_SCANCODE_END */ 0x004bu, /* SDLK_PAGEUP -> SDL_SCANCODE_PAGEUP */ 0x004eu, /* SDLK_PAGEDOWN -> SDL_SCANCODE_PAGEDOWN */ 0x003au, /* SDLK_F1 -> SDL_SCANCODE_F1 */ 0x003bu, /* SDLK_F2 -> SDL_SCANCODE_F2 */ 0x003cu, /* SDLK_F3 -> SDL_SCANCODE_F3 */ 0x003du, /* SDLK_F4 -> SDL_SCANCODE_F4 */ 0x003eu, /* SDLK_F5 -> SDL_SCANCODE_F5 */ 0x003fu, /* SDLK_F6 -> SDL_SCANCODE_F6 */ 0x0040u, /* SDLK_F7 -> SDL_SCANCODE_F7 */ 0x0041u, /* SDLK_F8 -> SDL_SCANCODE_F8 */ 0x0042u, /* SDLK_F9 -> SDL_SCANCODE_F9 */ 0x0043u, /* SDLK_F10 -> SDL_SCANCODE_F10 */ 0x0044u, /* SDLK_F11 -> SDL_SCANCODE_F11 */ 0x0045u, /* SDLK_F12 -> SDL_SCANCODE_F12 */ 0x0068u, /* SDLK_F13 -> SDL_SCANCODE_F13 */ 0x0069u, /* SDLK_F14 -> SDL_SCANCODE_F14 */ 0x006au, /* SDLK_F15 -> SDL_SCANCODE_F15 */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* unassigned -> SDL_SCANCODE_UNKNOWN */ 0x0053u, /* SDLK_NUMLOCK -> SDL_SCANCODE_NUMLOCKCLEAR */ 0x0039u, /* SDLK_CAPSLOCK -> SDL_SCANCODE_CAPSLOCK */ 0x0000u, /* SDLK_SCROLLOCK -> SDL_SCANCODE_UNKNOWN */ 0x00e5u, /* SDLK_RSHIFT -> SDL_SCANCODE_RSHIFT */ 0x00e1u, /* SDLK_LSHIFT -> SDL_SCANCODE_LSHIFT */ 0x00e4u, /* SDLK_RCTRL -> SDL_SCANCODE_RCTRL */ 0x00e0u, /* SDLK_LCTRL -> SDL_SCANCODE_LCTRL */ 0x00e6u, /* SDLK_RALT -> SDL_SCANCODE_RALT */ 0x00e2u, /* SDLK_LALT -> SDL_SCANCODE_LALT */ 0x0000u, /* SDLK_RMETA -> SDL_SCANCODE_UNKNOWN */ 0x0000u, /* SDLK_LMETA -> SDL_SCANCODE_UNKNOWN */ 0x00e3u, /* SDLK_LSUPER -> SDL_SCANCODE_LGUI */ 0x00e7u, /* SDLK_RSUPER -> SDL_SCANCODE_RGUI */ 0x0101u, /* SDLK_MODE -> SDL_SCANCODE_MODE */ 0x0000u, /* SDLK_COMPOSE -> SDL_SCANCODE_UNKNOWN */ 0x0075u, /* SDLK_HELP -> SDL_SCANCODE_HELP */ 0x0000u, /* SDLK_PRINT -> SDL_SCANCODE_UNKNOWN */ 0x009au, /* SDLK_SYSREQ -> SDL_SCANCODE_SYSREQ */ 0x0000u, /* SDLK_BREAK -> SDL_SCANCODE_UNKNOWN */ 0x0076u, /* SDLK_MENU -> SDL_SCANCODE_MENU */ 0x0066u, /* SDLK_POWER -> SDL_SCANCODE_POWER */ 0x0000u, /* SDLK_EURO -> SDL_SCANCODE_UNKNOWN */ 0x007au, /* SDLK_UNDO -> SDL_SCANCODE_UNDO */ }; if (keysym >= ARRAY_SIZE(keysym2scancode)) return 0; return keysym2scancode[keysym]; } uint16_t sdl_scancode2keysym(uint16_t scancode) { static const uint16_t scancode2keysym[285] = { 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0061u, /* SDL_SCANCODE_A -> SDLK_a */ 0x0062u, /* SDL_SCANCODE_B -> SDLK_b */ 0x0063u, /* SDL_SCANCODE_C -> SDLK_c */ 0x0064u, /* SDL_SCANCODE_D -> SDLK_d */ 0x0065u, /* SDL_SCANCODE_E -> SDLK_e */ 0x0066u, /* SDL_SCANCODE_F -> SDLK_f */ 0x0067u, /* SDL_SCANCODE_G -> SDLK_g */ 0x0068u, /* SDL_SCANCODE_H -> SDLK_h */ 0x0069u, /* SDL_SCANCODE_I -> SDLK_i */ 0x006au, /* SDL_SCANCODE_J -> SDLK_j */ 0x006bu, /* SDL_SCANCODE_K -> SDLK_k */ 0x006cu, /* SDL_SCANCODE_L -> SDLK_l */ 0x006du, /* SDL_SCANCODE_M -> SDLK_m */ 0x006eu, /* SDL_SCANCODE_N -> SDLK_n */ 0x006fu, /* SDL_SCANCODE_O -> SDLK_o */ 0x0070u, /* SDL_SCANCODE_P -> SDLK_p */ 0x0071u, /* SDL_SCANCODE_Q -> SDLK_q */ 0x0072u, /* SDL_SCANCODE_R -> SDLK_r */ 0x0073u, /* SDL_SCANCODE_S -> SDLK_s */ 0x0074u, /* SDL_SCANCODE_T -> SDLK_t */ 0x0075u, /* SDL_SCANCODE_U -> SDLK_u */ 0x0076u, /* SDL_SCANCODE_V -> SDLK_v */ 0x0077u, /* SDL_SCANCODE_W -> SDLK_w */ 0x0078u, /* SDL_SCANCODE_X -> SDLK_x */ 0x0079u, /* SDL_SCANCODE_Y -> SDLK_y */ 0x007au, /* SDL_SCANCODE_Z -> SDLK_z */ 0x0031u, /* SDL_SCANCODE_1 -> SDLK_1 */ 0x0032u, /* SDL_SCANCODE_2 -> SDLK_2 */ 0x0033u, /* SDL_SCANCODE_3 -> SDLK_3 */ 0x0034u, /* SDL_SCANCODE_4 -> SDLK_4 */ 0x0035u, /* SDL_SCANCODE_5 -> SDLK_5 */ 0x0036u, /* SDL_SCANCODE_6 -> SDLK_6 */ 0x0037u, /* SDL_SCANCODE_7 -> SDLK_7 */ 0x0038u, /* SDL_SCANCODE_8 -> SDLK_8 */ 0x0039u, /* SDL_SCANCODE_9 -> SDLK_9 */ 0x0030u, /* SDL_SCANCODE_0 -> SDLK_0 */ 0x000du, /* SDL_SCANCODE_RETURN -> SDLK_RETURN */ 0x001bu, /* SDL_SCANCODE_ESCAPE -> SDLK_ESCAPE */ 0x0008u, /* SDL_SCANCODE_BACKSPACE -> SDLK_BACKSPACE */ 0x0009u, /* SDL_SCANCODE_TAB -> SDLK_TAB */ 0x0020u, /* SDL_SCANCODE_SPACE -> SDLK_SPACE */ 0x002du, /* SDL_SCANCODE_MINUS -> SDLK_MINUS */ 0x003du, /* SDL_SCANCODE_EQUALS -> SDLK_EQUALS */ 0x005bu, /* SDL_SCANCODE_LEFTBRACKET -> SDLK_LEFTBRACKET */ 0x005du, /* SDL_SCANCODE_RIGHTBRACKET -> SDLK_RIGHTBRACKET */ 0x005cu, /* SDL_SCANCODE_BACKSLASH -> SDLK_BACKSLASH */ 0x0000u, /* SDL_SCANCODE_NONUSHASH -> SDLK_UNKNOWN */ 0x003bu, /* SDL_SCANCODE_SEMICOLON -> SDLK_SEMICOLON */ 0x0000u, /* SDL_SCANCODE_APOSTROPHE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_GRAVE -> SDLK_UNKNOWN */ 0x002cu, /* SDL_SCANCODE_COMMA -> SDLK_COMMA */ 0x002eu, /* SDL_SCANCODE_PERIOD -> SDLK_PERIOD */ 0x002fu, /* SDL_SCANCODE_SLASH -> SDLK_SLASH */ 0x012du, /* SDL_SCANCODE_CAPSLOCK -> SDLK_CAPSLOCK */ 0x011au, /* SDL_SCANCODE_F1 -> SDLK_F1 */ 0x011bu, /* SDL_SCANCODE_F2 -> SDLK_F2 */ 0x011cu, /* SDL_SCANCODE_F3 -> SDLK_F3 */ 0x011du, /* SDL_SCANCODE_F4 -> SDLK_F4 */ 0x011eu, /* SDL_SCANCODE_F5 -> SDLK_F5 */ 0x011fu, /* SDL_SCANCODE_F6 -> SDLK_F6 */ 0x0120u, /* SDL_SCANCODE_F7 -> SDLK_F7 */ 0x0121u, /* SDL_SCANCODE_F8 -> SDLK_F8 */ 0x0122u, /* SDL_SCANCODE_F9 -> SDLK_F9 */ 0x0123u, /* SDL_SCANCODE_F10 -> SDLK_F10 */ 0x0124u, /* SDL_SCANCODE_F11 -> SDLK_F11 */ 0x0125u, /* SDL_SCANCODE_F12 -> SDLK_F12 */ 0x0000u, /* SDL_SCANCODE_PRINTSCREEN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_SCROLLLOCK -> SDLK_UNKNOWN */ 0x0013u, /* SDL_SCANCODE_PAUSE -> SDLK_PAUSE */ 0x0115u, /* SDL_SCANCODE_INSERT -> SDLK_INSERT */ 0x0116u, /* SDL_SCANCODE_HOME -> SDLK_HOME */ 0x0118u, /* SDL_SCANCODE_PAGEUP -> SDLK_PAGEUP */ 0x007fu, /* SDL_SCANCODE_DELETE -> SDLK_DELETE */ 0x0117u, /* SDL_SCANCODE_END -> SDLK_END */ 0x0119u, /* SDL_SCANCODE_PAGEDOWN -> SDLK_PAGEDOWN */ 0x0113u, /* SDL_SCANCODE_RIGHT -> SDLK_RIGHT */ 0x0114u, /* SDL_SCANCODE_LEFT -> SDLK_LEFT */ 0x0112u, /* SDL_SCANCODE_DOWN -> SDLK_DOWN */ 0x0111u, /* SDL_SCANCODE_UP -> SDLK_UP */ 0x012cu, /* SDL_SCANCODE_NUMLOCKCLEAR -> SDLK_NUMLOCK */ 0x010bu, /* SDL_SCANCODE_KP_DIVIDE -> SDLK_KP_DIVIDE */ 0x010cu, /* SDL_SCANCODE_KP_MULTIPLY -> SDLK_KP_MULTIPLY */ 0x010du, /* SDL_SCANCODE_KP_MINUS -> SDLK_KP_MINUS */ 0x010eu, /* SDL_SCANCODE_KP_PLUS -> SDLK_KP_PLUS */ 0x010fu, /* SDL_SCANCODE_KP_ENTER -> SDLK_KP_ENTER */ 0x0101u, /* SDL_SCANCODE_KP_1 -> SDLK_KP1 */ 0x0102u, /* SDL_SCANCODE_KP_2 -> SDLK_KP2 */ 0x0103u, /* SDL_SCANCODE_KP_3 -> SDLK_KP3 */ 0x0104u, /* SDL_SCANCODE_KP_4 -> SDLK_KP4 */ 0x0105u, /* SDL_SCANCODE_KP_5 -> SDLK_KP5 */ 0x0106u, /* SDL_SCANCODE_KP_6 -> SDLK_KP6 */ 0x0107u, /* SDL_SCANCODE_KP_7 -> SDLK_KP7 */ 0x0108u, /* SDL_SCANCODE_KP_8 -> SDLK_KP8 */ 0x0109u, /* SDL_SCANCODE_KP_9 -> SDLK_KP9 */ 0x0100u, /* SDL_SCANCODE_KP_0 -> SDLK_KP0 */ 0x010au, /* SDL_SCANCODE_KP_PERIOD -> SDLK_KP_PERIOD */ 0x0000u, /* SDL_SCANCODE_NONUSBACKSLASH -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_APPLICATION -> SDLK_UNKNOWN */ 0x0140u, /* SDL_SCANCODE_POWER -> SDLK_POWER */ 0x0110u, /* SDL_SCANCODE_KP_EQUALS -> SDLK_KP_EQUALS */ 0x0126u, /* SDL_SCANCODE_F13 -> SDLK_F13 */ 0x0127u, /* SDL_SCANCODE_F14 -> SDLK_F14 */ 0x0128u, /* SDL_SCANCODE_F15 -> SDLK_F15 */ 0x0000u, /* SDL_SCANCODE_F16 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F17 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F18 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F19 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F20 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F21 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F22 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F23 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_F24 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_EXECUTE -> SDLK_UNKNOWN */ 0x013bu, /* SDL_SCANCODE_HELP -> SDLK_HELP */ 0x013fu, /* SDL_SCANCODE_MENU -> SDLK_MENU */ 0x0000u, /* SDL_SCANCODE_SELECT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_STOP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AGAIN -> SDLK_UNKNOWN */ 0x0142u, /* SDL_SCANCODE_UNDO -> SDLK_UNDO */ 0x0000u, /* SDL_SCANCODE_CUT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_COPY -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_PASTE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_FIND -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_MUTE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_VOLUMEUP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_VOLUMEDOWN -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_COMMA -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_EQUALSAS400 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL1 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL2 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL3 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL4 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL5 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL6 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL7 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL8 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_INTERNATIONAL9 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG1 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG2 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG3 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG4 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG5 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG6 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG7 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG8 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_LANG9 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_ALTERASE -> SDLK_UNKNOWN */ 0x013du, /* SDL_SCANCODE_SYSREQ -> SDLK_SYSREQ */ 0x0000u, /* SDL_SCANCODE_CANCEL -> SDLK_UNKNOWN */ 0x000cu, /* SDL_SCANCODE_CLEAR -> SDLK_CLEAR */ 0x0000u, /* SDL_SCANCODE_PRIOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_RETURN2 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_SEPARATOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_OUT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_OPER -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_CLEARAGAIN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_CRSEL -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_EXSEL -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_00 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_000 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_THOUSANDSSEPARATOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_DECIMALSEPARATOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_CURRENCYUNIT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_CURRENCYSUBUNIT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_LEFTPAREN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_RIGHTPAREN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_LEFTBRACE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_RIGHTBRACE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_TAB -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_BACKSPACE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_A -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_B -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_C -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_D -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_E -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_F -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_XOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_POWER -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_PERCENT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_LESS -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_GREATER -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_AMPERSAND -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_DBLAMPERSAND -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_VERTICALBAR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_DBLVERTICALBAR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_COLON -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_HASH -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_SPACE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_AT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_EXCLAM -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMSTORE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMRECALL -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMCLEAR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMADD -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMSUBTRACT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMMULTIPLY -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_MEMDIVIDE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_PLUSMINUS -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_CLEAR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_CLEARENTRY -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_BINARY -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_OCTAL -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_DECIMAL -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KP_HEXADECIMAL -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0132u, /* SDL_SCANCODE_LCTRL -> SDLK_LCTRL */ 0x0130u, /* SDL_SCANCODE_LSHIFT -> SDLK_LSHIFT */ 0x0134u, /* SDL_SCANCODE_LALT -> SDLK_LALT */ 0x0137u, /* SDL_SCANCODE_LGUI -> SDLK_LSUPER */ 0x0131u, /* SDL_SCANCODE_RCTRL -> SDLK_RCTRL */ 0x012fu, /* SDL_SCANCODE_RSHIFT -> SDLK_RSHIFT */ 0x0133u, /* SDL_SCANCODE_RALT -> SDLK_RALT */ 0x0138u, /* SDL_SCANCODE_RGUI -> SDLK_RSUPER */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0000u, /* unassigned -> SDLK_UNKNOWN */ 0x0139u, /* SDL_SCANCODE_MODE -> SDLK_MODE */ 0x0000u, /* SDL_SCANCODE_AUDIONEXT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AUDIOPREV -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AUDIOSTOP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AUDIOPLAY -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AUDIOMUTE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_MEDIASELECT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_WWW -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_MAIL -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_CALCULATOR -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_COMPUTER -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_SEARCH -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_HOME -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_BACK -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_FORWARD -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_STOP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_REFRESH -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_AC_BOOKMARKS -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_BRIGHTNESSDOWN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_BRIGHTNESSUP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_DISPLAYSWITCH -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KBDILLUMTOGGLE -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KBDILLUMDOWN -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_KBDILLUMUP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_EJECT -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_SLEEP -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_APP1 -> SDLK_UNKNOWN */ 0x0000u, /* SDL_SCANCODE_APP2 -> SDLK_UNKNOWN */ }; if (scancode >= ARRAY_SIZE(scancode2keysym)) return 0; return scancode2keysym[scancode]; } mupen64plus-input-sdl-2.5.9+55+g2129e94/src/sdl_key_converter.h000066400000000000000000000041341436635717600236620ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - sdl_key_converter.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2013 Mupen64plus development team * * * * 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 "osal_preproc.h" uint16_t sdl_keysym2scancode(uint16_t keysym); uint16_t sdl_scancode2keysym(uint16_t scancode); #if SDL_VERSION_ATLEAST(1,3,0) static osal_inline uint16_t sdl_keysym2native(uint16_t keysym) { return sdl_keysym2scancode(keysym); } static osal_inline uint16_t sdl_native2keysym(uint16_t native) { return sdl_scancode2keysym(native); } #else static osal_inline uint16_t sdl_keysym2native(uint16_t keysym) { return keysym; } static osal_inline uint16_t sdl_native2keysym(uint16_t native) { return native; } #endif mupen64plus-input-sdl-2.5.9+55+g2129e94/src/version.h000066400000000000000000000036331436635717600216310ustar00rootroot00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus-input-sdl - version.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * 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 SDL Input Plugin" #define PLUGIN_VERSION 0x020509 #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 */