--- /dev/null
+Mupen64Plus-Audio-SDL INSTALL
+-----------------------------
+
+This text file was written to explain the installation process of the
+Mupen64Plus-Audio-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-Audio-SDL module for installation in a
+home folder for a single user, you may build it like this (replacing
+<my-folder> with your desired local installation path):
+
+$ cd projects/unix
+$ make all
+$ make install LIBDIR=<my-folder>
+
+
--- /dev/null
+Mupen64Plus-audio-sdl LICENSE
+-----------------------------
+
+Mupen64Plus-audio-sdl is licensed under the GNU General Public License version 2.
+
+The authors of Mupen64Plus are:
+ * Richard Goedeken (Richard42)
+ * 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)
+ * Casualjames
+ * HyperHacker
+ * and others.
+
+Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by:
+ * Hacktarux
+ * Dave2001
+ * Zilmar
+ * Gregor Anich (Blight)
+ * Juha Luotio (JttL)
+ * and others.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
--- /dev/null
+SDL Audio plugin for Mupen64Plus
+---------------------------------
+
+Mupen64Plus-audio-sdl - v2.0 - July 4, 2013
+-------------------------------------------
+ - Add support for resampling with speexdsp library
+ - Add more resampling quality options
+ - Bugfix: Don't assume OSS is installed in all linux systems.
+ - Bugfix: Some combinations of VolumeSetLevel and VolumeMute caused VolumeGetString to return "Mute" when not muted
+ - Make SDL volume handling the default, since OSS is no longer included in the kernel.
+ - Minor refactoring of volume handling code.
+ - MS Visual Studio 2012 project files
+ - Makefile improvements
+ - support for ARM and MINGW architectures
+ - support for cross-compiling (MXE win32 builds under Unix)
+
+Mupen64Plus-audio-sdl v1.99.5 - March 10, 2012
+--------------------------------------------------
+ - added version number to SDL-audio plugin config parameters, to support future changes
+ - updated audio plugin for new Mupen64plus 2.0 API versioning scheme
+ - makefile fixes and improvements
+
+Mupen64Plus-audio-sdl v1.99.4 - November 22, 2010
+--------------------------------------------------
+ - Bugfix: Plugin should write default config values at startup time
+ - Bugfix: fixed fast-forward for banjo-kazooie and other games which was broken due to limitation in basic resampling algorithm
+ - many makefile fixes and improvements
+
+Mupen64Plus-audio-sdl v1.99.3 - February 13, 2010
+--------------------------------------------------
+ - sync with core<-->plugin API change for RomOpen()
+ - bugfix: logical error in previous audio refactoring causing slowdown/lockup on loading savestate or re-initializing audio
+ - Makefile improvements:
+ - 'sdl-config --libs' can give "-Wl,-rpath", so plugin must be linked with CC instead of LD
+ - issue #257: added to makefile OS type GNU/kFreeBSD
+
+Mupen64Plus-audio-sdl v1.99.2 - January 6, 2010
+-------------------------------------------------
+ - new feature: Completely re-wrote buffering/synchronization code:
+ - Buffer parameters now work as advertised and all use the same units
+ - Bugfix: previous defaults and algorithm behavior caused audio choppiness on slower PCs
+ - Bugfix: maximum speed was previously limited to low value by constraints from primary buffer size
+ - bugfix: SDL volume control will always be used on systems without OSS support
+ - new feature: added MSVC8 project file, minor code refactoring to build in Windows
+ - Makefile improvements:
+ - throw error if OS/CPU not supported
+ - use DESTDIR in install/uninstall paths
+ - Allow user-specified CC/CXX/LD paths
+
+Mupen64Plus-audio-sdl v1.99.1 - December 14, 2009
+-------------------------------------------------
+ - Converted to new Mupen64Plus 2.0 API
+ - Code cleanup to remove non-standard data types
+ - Refactored build system to separate source and object files
+ - bugfix #269: jttl_audio segfaults on exit due to incorrectly ordered shutdown code
+
+ Mupen64plus 1.5:
+ +Additional SDL modulation option for volume control.
+ +New Gtk GUI for plugin configuration.
+ +Improved no GUI support.
+
+ Mupen64plus 1.4:
+ +Extended plugin API to allow all for runtime volume changes via OSS.
+
+ 1.4:
+ +Use only standard frequency for higher compatibility
+ +Fast resample algorithm (use only integers)
+ +Slight improvements in buffer management : pausing audio when buffer underrun occur
+
+ 1.2:
+ +Added possibility to swap channels
+ +Some more optimizations
+ +Calling RomOpen() is not required anymore. Plugin should now follow Zilmar's specs.
+ +Added test functions.
+ +Added support for config file
+
+ 1.1.1:
+ +Fixed the bug that was causing terrible noise (thanks Law)
+ +Much more debugging data appears now if DEBUG is defined
+ +Few more error checks
+
+ 1.1:
+ +Audio device is opened now with native byte ordering of the machine. Just
+ for compatibility (thanks Flea).
+ +Fixed possible double freeing bug (thanks Flea)
+ +Optimizations in AiLenChanged
+ +Fixed segmentation fault when changing rom.
+ +Syncronization redone
+
+ 1.0.1.3:
+ +Smarter versioning. No more betas.
+ +More cleaning up done.
+ +Buffer underrun and overflow messages appear now at stderr (if DEBUG is
+ defined)
+ +Many things are now precalculated (this should bring a small performance
+ boost)
+ +Buffer underrun bug fixed.
+ +Segmentation fault when closing rom fixed (at least I think so)
+
+ 1.0 beta 2:
+ +Makefile fixed to get rid of annoying warning messages
+ +Cleaned up some old code
+ +Default frequency set to 33600Hz (for Master Quest compatibility)
+ +Better syncronization (needs some work still though)
+
+ 1.0 beta 1:
+ +First public release
+
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{96969748-EA54-43FC-8103-A346E9AD98E7}</ProjectGuid>
+ <RootNamespace>mupen64plusaudiosdl</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\main.c" />
+ <ClCompile Include="..\..\src\osal_dynamiclib_win32.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\main.h" />
+ <ClInclude Include="..\..\src\osal_dynamiclib.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mupen64plus-audio-sdl"
+ ProjectGUID="{96969748-EA54-43FC-8103-A346E9AD98E7}"
+ RootNamespace="mupen64plusaudiosdl"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\..\mupen64plus-win32-deps\SDL-1.2.14\lib\SDL.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\src\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\osal_dynamiclib_win32.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\src\main.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\osal_dynamiclib.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+# * Mupen64plus-audio-sdl - Makefile *
+# * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+# * Copyright (C) 2007-2009 Richard Goedeken *
+# * Copyright (C) 2007-2008 Tillin9 *
+# * *
+# * This program is free software; you can redistribute it and/or modify *
+# * it under the terms of the GNU General Public License as published by *
+# * the Free Software Foundation; either version 2 of the License, or *
+# * (at your option) any later version. *
+# * *
+# * This program is distributed in the hope that it will be useful, *
+# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+# * GNU General Public License for more details. *
+# * *
+# * You should have received a copy of the GNU General Public License *
+# * along with this program; if not, write to the *
+# * Free Software Foundation, Inc., *
+# * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+# Makefile for SDL Audio plugin in Mupen64plus
+
+# detect operation system
+UNAME ?= $(shell uname -s)
+OS := NONE
+ifeq ("$(UNAME)","Linux")
+ OS = LINUX
+ SHARED = -shared
+ SO_EXTENSION = so
+endif
+ifeq ("$(UNAME)","linux")
+ OS = LINUX
+ SHARED = -shared
+ SO_EXTENSION = so
+endif
+ifneq ("$(filter GNU hurd,$(UNAME))","")
+ OS = LINUX
+ SHARED = -shared
+ SO_EXTENSION = so
+endif
+ifeq ("$(UNAME)","Darwin")
+ OS = OSX
+ SHARED = -bundle
+ SO_EXTENSION = dylib
+endif
+ifeq ("$(UNAME)","FreeBSD")
+ OS = FREEBSD
+ SHARED = -shared
+ SO_EXTENSION = so
+endif
+ifeq ("$(UNAME)","OpenBSD")
+ OS = FREEBSD
+ SHARED = -shared
+ SO_EXTENSION = so
+ $(warning OS type "$(UNAME)" not officially supported.')
+endif
+ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","")
+ OS = LINUX
+ SHARED = -shared
+ SO_EXTENSION = so
+endif
+ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW")
+ OS = MINGW
+ SHARED = -shared
+ SO_EXTENSION = dll
+ PIC = 0
+ NO_OSS = 1
+endif
+ifeq ("$(OS)","NONE")
+ $(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
+
+# detect system architecture
+HOST_CPU ?= $(shell uname -m)
+NO_ASM ?= 1
+CPU := NONE
+ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
+ CPU := X86
+ ifeq ("$(BITS)", "32")
+ ARCH_DETECTED := 64BITS_32
+ PIC ?= 0
+ else
+ ARCH_DETECTED := 64BITS
+ PIC ?= 1
+ endif
+endif
+ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
+ CPU := X86
+ ARCH_DETECTED := 32BITS
+ PIC ?= 0
+endif
+ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","")
+ CPU := PPC
+ ARCH_DETECTED := 32BITS
+ BIG_ENDIAN := 1
+ PIC ?= 1
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
+ CPU := PPC
+ ARCH_DETECTED := 64BITS
+ BIG_ENDIAN := 1
+ PIC ?= 1
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter arm%,$(HOST_CPU))","")
+ ifeq ("$(filter arm%b,$(HOST_CPU))","")
+ CPU := ARM
+ ARCH_DETECTED := 32BITS
+ CFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a8 -fsigned-char
+ PIC ?= 1
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+ endif
+endif
+ifeq ("$(CPU)","NONE")
+ $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
+
+# base CFLAGS, LDLIBS, and LDFLAGS
+OPTFLAGS ?= -O3
+WARNFLAGS ?= -Wall
+CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src
+LDFLAGS += $(SHARED)
+
+# Since we are building a shared library, we must compile with -fPIC on some architectures
+# On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch
+ifeq ($(PIC), 1)
+ CFLAGS += -fPIC
+else
+ CFLAGS += -fno-PIC
+endif
+
+ifeq ($(BIG_ENDIAN), 1)
+ CFLAGS += -DM64P_BIG_ENDIAN
+endif
+
+# tweak flags for 32-bit build on 64-bit system
+ifeq ($(ARCH_DETECTED), 64BITS_32)
+ ifeq ($(OS), FREEBSD)
+ $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
+ endif
+ CFLAGS += -m32
+ LDFLAGS += -Wl,-m,elf_i386
+endif
+
+# set special flags per-system
+ifeq ($(OS), LINUX)
+ LDLIBS += -ldl
+endif
+ifeq ($(OS), OSX)
+ # Select the proper SDK
+ # Also, SDKs are stored in a different location since XCode 4.3
+ OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .)
+ OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .)
+ OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .)
+ OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`")
+ ifeq ($(OSX_XCODEGE43), 11)
+ OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
+ else
+ OSX_SYSROOT := /Developer/SDKs
+ endif
+
+ ifeq ($(CPU), X86)
+ ifeq ($(ARCH_DETECTED), 64BITS)
+ CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+ LDLIBS += -ldl
+ else
+ CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+ 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)sdl-config
+ ifeq ($(shell which $(SDL_CONFIG) 2>/dev/null),)
+ $(error No SDL development libraries found!)
+ endif
+ SDL_CFLAGS += $(shell $(SDL_CONFIG) --cflags)
+ SDL_LDLIBS += $(shell $(SDL_CONFIG) --libs)
+endif
+CFLAGS += $(SDL_CFLAGS)
+LDLIBS += $(SDL_LDLIBS)
+
+# test for essential build dependencies
+ifeq ($(origin PKG_CONFIG), undefined)
+ PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+ ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
+ $(error $(PKG_CONFIG) not found)
+ endif
+endif
+
+# test for presence of speexdsp
+ifneq ($(NO_SPEEX), 1)
+ ifeq ($(origin SPEEX_CFLAGS) $(origin SPEEX_LDLIBS), undefined undefined)
+ ifneq ($(strip $(shell $(PKG_CONFIG) speexdsp --modversion 2> /dev/null)),)
+ # set speexdsp flags and libraries
+ SPEEX_CFLAGS += $(shell $(PKG_CONFIG) speexdsp --cflags) -DUSE_SPEEX
+ SPEEX_LDLIBS += $(shell $(PKG_CONFIG) speexdsp --libs)
+ else
+ # warn user
+ $(warning No libspeexdsp development libraries found. Mupen64plus-sdl-audio will be built without speex-* resampler.)
+ endif
+ else
+ SPEEX_CFLAGS += -DUSE_SPEEX
+ endif
+ CFLAGS += $(SPEEX_CFLAGS)
+ LDLIBS += $(SPEEX_LDLIBS)
+endif
+
+# test for presence of libsamplerate
+ifneq ($(NO_SRC), 1)
+ ifeq ($(origin SRC_CFLAGS) $(origin SRC_LDLIBS), undefined undefined)
+ ifneq ($(strip $(shell $(PKG_CONFIG) samplerate --modversion 2> /dev/null)),)
+ # set libsamplerate flags and libraries
+ SRC_CFLAGS += $(shell $(PKG_CONFIG) samplerate --cflags) -DUSE_SRC
+ SRC_LDLIBS += $(shell $(PKG_CONFIG) samplerate --libs)
+ else
+ $(warning No libsamplerate development libraries found. Mupen64plus-sdl-audio will be built without src-* resampler.)
+ endif
+ else
+ SRC_CFLAGS += -DUSE_SRC
+ endif
+ CFLAGS += $(SRC_CFLAGS)
+ LDLIBS += $(SRC_LDLIBS)
+endif
+
+# test for the presence of OSS
+ifneq ($(wildcard /dev/mixer),)
+ ifneq ($(NO_OSS), 1)
+ CFLAGS += -DHAS_OSS_SUPPORT
+ endif
+endif
+
+# set mupen64plus core API header path
+ifneq ("$(APIDIR)","")
+ CFLAGS += "-I$(APIDIR)"
+else
+ TRYDIR = ../../../mupen64plus-core/src/api
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ TRYDIR = /usr/local/include/mupen64plus
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ TRYDIR = /usr/include/mupen64plus
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ $(error Mupen64Plus API header files not found! Use makefile parameter APIDIR to force a location.)
+ endif
+ endif
+ endif
+endif
+
+# reduced compile output when running make without V=1
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+ Q_CC = @echo ' CC '$@;
+ Q_LD = @echo ' LD '$@;
+endif
+endif
+
+# set base program pointers and flags
+CC = $(CROSS_COMPILE)gcc
+RM ?= rm -f
+INSTALL ?= install
+MKDIR ?= mkdir -p
+COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.o = $(Q_LD)$(CC) $(CFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+
+# set special flags for given Makefile parameters
+ifeq ($(DEBUG),1)
+ CFLAGS += -g
+ INSTALL_STRIP_FLAG ?=
+else
+ ifneq ($(OS),OSX)
+ INSTALL_STRIP_FLAG ?= -s
+ endif
+endif
+
+# set installation options
+ifeq ($(PREFIX),)
+ PREFIX := /usr/local
+endif
+ifeq ($(LIBDIR),)
+ LIBDIR := $(PREFIX)/lib
+endif
+ifeq ($(PLUGINDIR),)
+ PLUGINDIR := $(LIBDIR)/mupen64plus
+endif
+
+SRCDIR = ../../src
+OBJDIR = _obj$(POSTFIX)
+
+# list of source files to compile
+SOURCE = \
+ $(SRCDIR)/main.c \
+ $(SRCDIR)/volume.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-audio-sdl$(POSTFIX).$(SO_EXTENSION)
+
+targets:
+ @echo "Mupen64Plus-audio-sdl makefile. "
+ @echo " Targets:"
+ @echo " all == Build Mupen64Plus SDL audio plugin"
+ @echo " clean == remove object files"
+ @echo " rebuild == clean and re-build all"
+ @echo " install == Install Mupen64Plus SDL audio plugin"
+ @echo " uninstall == Uninstall Mupen64Plus SDL audio 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 " NO_SRC=1 == build without libsamplerate; disables src-* high-quality audio resampling"
+ @echo " NO_SPEEX=1 == build without libspeexdsp; disables speex-* high-quality audio resampling"
+ @echo " NO_OSS=1 == build without OSS; disables Open Sound System support"
+ @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 " LIBDIR=path == library prefix (default: PREFIX/lib)"
+ @echo " PLUGINDIR=path == path to install plugin libraries (default: LIBDIR/mupen64plus)"
+ @echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)"
+ @echo " Debugging Options:"
+ @echo " DEBUG=1 == add debugging symbols"
+ @echo " V=1 == show verbose compiler output"
+
+
+all: $(TARGET)
+
+install: $(TARGET)
+ $(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
+ $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
+
+uninstall:
+ $(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
+
+clean:
+ $(RM) -r $(OBJDIR) $(TARGET)
+
+rebuild: clean all
+
+# build dependency files
+CFLAGS += -MD
+-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
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-sdl-audio - main.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2007-2009 Richard Goedeken *
+ * Copyright (C) 2007-2008 Ebenblues *
+ * Copyright (C) 2003 JttL *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <SDL.h>
+#include <SDL_audio.h>
+
+#ifdef USE_SRC
+#include <samplerate.h>
+#endif
+#ifdef USE_SPEEX
+#include <speex/speex_resampler.h>
+#endif
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_types.h"
+#include "m64p_plugin.h"
+#include "m64p_common.h"
+#include "m64p_config.h"
+
+#include "main.h"
+#include "volume.h"
+#include "osal_dynamiclib.h"
+
+/* Default start-time size of primary buffer (in equivalent output samples).
+ This is the buffer where audio is loaded after it's extracted from n64's memory.
+ This value must be larger than PRIMARY_BUFFER_TARGET */
+#define PRIMARY_BUFFER_SIZE 16384
+
+/* this is the buffer fullness level (in equivalent output samples) which is targeted
+ for the primary audio buffer (by inserting delays) each time data is received from
+ the running N64 program. This value must be larger than the SECONDARY_BUFFER_SIZE.
+ Decreasing this value will reduce audio latency but requires a faster PC to avoid
+ choppiness. Increasing this will increase audio latency but reduce the chance of
+ drop-outs. The default value 10240 gives a 232ms maximum A/V delay at 44.1khz */
+#define PRIMARY_BUFFER_TARGET 10240
+
+/* Size of secondary buffer, in output samples. This is the requested size of SDL's
+ hardware buffer, and the size of the mix buffer for doing SDL volume control. The
+ SDL documentation states that this should be a power of two between 512 and 8192. */
+#define SECONDARY_BUFFER_SIZE 8192
+/*SEB 2048 before*/
+
+/* This sets default frequency what is used if rom doesn't want to change it.
+ Probably only game that needs this is Zelda: Ocarina Of Time Master Quest
+ *NOTICE* We should try to find out why Demos' frequencies are always wrong
+ They tend to rely on a default frequency, apparently, never the same one ;)*/
+#define DEFAULT_FREQUENCY 33600
+
+/* number of bytes per sample */
+#define N64_SAMPLE_BYTES 4
+#define SDL_SAMPLE_BYTES 4
+
+/* volume mixer types */
+#define VOLUME_TYPE_SDL 1
+#define VOLUME_TYPE_OSS 2
+
+/* local variables */
+static void (*l_DebugCallback)(void *, int, const char *) = NULL;
+static void *l_DebugCallContext = NULL;
+static int l_PluginInit = 0;
+static int l_PausedForSync = 1; /* Audio is started in paused state after SDL initialization */
+static m64p_handle l_ConfigAudio;
+
+enum resampler_type {
+ RESAMPLER_TRIVIAL,
+#ifdef USE_SRC
+ RESAMPLER_SRC,
+#endif
+#ifdef USE_SPEEX
+ RESAMPLER_SPEEX,
+#endif
+};
+
+/* Read header for type definition */
+static AUDIO_INFO AudioInfo;
+/* The hardware specifications we are using */
+static SDL_AudioSpec *hardware_spec;
+/* Pointer to the primary audio buffer */
+static unsigned char *primaryBuffer = NULL;
+static unsigned int primaryBufferBytes = 0;
+/* Pointer to the mixing buffer for voume control*/
+static unsigned char *mixBuffer = NULL;
+/* Position in buffer array where next audio chunk should be placed */
+static unsigned int buffer_pos = 0;
+/* Audio frequency, this is usually obtained from the game, but for compatibility we set default value */
+static int GameFreq = DEFAULT_FREQUENCY;
+/* timestamp for the last time that our audio callback was called */
+static unsigned int last_callback_ticks = 0;
+/* SpeedFactor is used to increase/decrease game playback speed */
+static unsigned int speed_factor = 100;
+// If this is true then left and right channels are swapped */
+static int SwapChannels = 0;
+// Size of Primary audio buffer in equivalent output samples
+static unsigned int PrimaryBufferSize = PRIMARY_BUFFER_SIZE;
+// Fullness level target for Primary audio buffer, in equivalent output samples
+static unsigned int PrimaryBufferTarget = PRIMARY_BUFFER_TARGET;
+// Size of Secondary audio buffer in output samples
+static unsigned int SecondaryBufferSize = SECONDARY_BUFFER_SIZE;
+// Resample type
+static enum resampler_type Resample = RESAMPLER_TRIVIAL;
+// Resampler specific quality
+static int ResampleQuality = 3;
+// volume to scale the audio by, range of 0..100
+// if muted, this holds the volume when not muted
+static int VolPercent = 80;
+// how much percent to increment/decrement volume by
+static int VolDelta = 5;
+// the actual volume passed into SDL, range of 0..SDL_MIX_MAXVOLUME
+static int VolSDL = SDL_MIX_MAXVOLUME;
+// Muted or not
+static int VolIsMuted = 0;
+//which type of volume control to use
+static int VolumeControlType = VOLUME_TYPE_SDL;
+
+static int OutputFreq;
+
+// Prototype of local functions
+static void my_audio_callback(void *userdata, unsigned char *stream, int len);
+static void InitializeAudio(int freq);
+static void ReadConfig(void);
+static void InitializeSDL(void);
+
+static int critical_failure = 0;
+
+/* definitions of pointers to Core config functions */
+ptr_ConfigOpenSection ConfigOpenSection = NULL;
+ptr_ConfigDeleteSection ConfigDeleteSection = NULL;
+ptr_ConfigSaveSection ConfigSaveSection = 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;
+
+/* Global functions */
+static 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);
+}
+
+/* Mupen64Plus plugin functions */
+EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
+ void (*DebugCallback)(void *, int, const char *))
+{
+ ptr_CoreGetAPIVersions CoreAPIVersionFunc;
+
+ int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion, bSaveConfig;
+ float fConfigParamsVersion = 0.0f;
+
+ 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))
+ {
+ 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");
+ ConfigSaveSection = (ptr_ConfigSaveSection) osal_dynlib_getproc(CoreLibHandle, "ConfigSaveSection");
+ 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");
+
+ if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter ||
+ !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
+ !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString)
+ return M64ERR_INCOMPATIBLE;
+
+ /* ConfigSaveSection was added in Config API v2.1.0 */
+ if (ConfigAPIVersion >= 0x020100 && !ConfigSaveSection)
+ return M64ERR_INCOMPATIBLE;
+
+ /* get a configuration section handle */
+ if (ConfigOpenSection("Audio-SDL", &l_ConfigAudio) != M64ERR_SUCCESS)
+ {
+ DebugMessage(M64MSG_ERROR, "Couldn't open config section 'Audio-SDL'");
+ return M64ERR_INPUT_NOT_FOUND;
+ }
+
+ /* check the section version number */
+ bSaveConfig = 0;
+ if (ConfigGetParameter(l_ConfigAudio, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS)
+ {
+ DebugMessage(M64MSG_WARNING, "No version number in 'Audio-SDL' config section. Setting defaults.");
+ ConfigDeleteSection("Audio-SDL");
+ ConfigOpenSection("Audio-SDL", &l_ConfigAudio);
+ bSaveConfig = 1;
+ }
+ else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION))
+ {
+ DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'Audio-SDL' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION);
+ ConfigDeleteSection("Audio-SDL");
+ ConfigOpenSection("Audio-SDL", &l_ConfigAudio);
+ bSaveConfig = 1;
+ }
+ else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f)
+ {
+ /* handle upgrades */
+ float fVersion = CONFIG_PARAM_VERSION;
+ ConfigSetParameter(l_ConfigAudio, "Version", M64TYPE_FLOAT, &fVersion);
+ DebugMessage(M64MSG_INFO, "Updating parameter set version in 'Audio-SDL' config section to %.2f", fVersion);
+ bSaveConfig = 1;
+ }
+
+ /* set the default values for this plugin */
+ ConfigSetDefaultFloat(l_ConfigAudio, "Version", CONFIG_PARAM_VERSION, "Mupen64Plus SDL Audio Plugin config parameter version number");
+ ConfigSetDefaultInt(l_ConfigAudio, "DEFAULT_FREQUENCY", DEFAULT_FREQUENCY, "Frequency which is used if rom doesn't want to change it");
+ ConfigSetDefaultBool(l_ConfigAudio, "SWAP_CHANNELS", 0, "Swaps left and right channels");
+ ConfigSetDefaultInt(l_ConfigAudio, "PRIMARY_BUFFER_SIZE", PRIMARY_BUFFER_SIZE, "Size of primary buffer in output samples. This is where audio is loaded after it's extracted from n64's memory.");
+ ConfigSetDefaultInt(l_ConfigAudio, "PRIMARY_BUFFER_TARGET", PRIMARY_BUFFER_TARGET, "Fullness level target for Primary audio buffer, in equivalent output samples");
+ ConfigSetDefaultInt(l_ConfigAudio, "SECONDARY_BUFFER_SIZE", SECONDARY_BUFFER_SIZE, "Size of secondary buffer in output samples. This is SDL's hardware buffer.");
+ ConfigSetDefaultString(l_ConfigAudio, "RESAMPLE", "trivial", "Audio resampling algorithm. src-sinc-best-quality, src-sinc-medium-quality, src-sinc-fastest, src-zero-order-hold, src-linear, speex-fixed-{10-0}, trivial");
+ ConfigSetDefaultInt(l_ConfigAudio, "VOLUME_CONTROL_TYPE", VOLUME_TYPE_SDL, "Volume control type: 1 = SDL (only affects Mupen64Plus output) 2 = OSS mixer (adjusts master PC volume)");
+ ConfigSetDefaultInt(l_ConfigAudio, "VOLUME_ADJUST", 5, "Percentage change each time the volume is increased or decreased");
+ ConfigSetDefaultInt(l_ConfigAudio, "VOLUME_DEFAULT", 80, "Default volume when a game is started. Only used if VOLUME_CONTROL_TYPE is 1");
+
+ if (bSaveConfig && ConfigAPIVersion >= 0x020100)
+ ConfigSaveSection("Audio-SDL");
+
+ 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;
+
+ /* make sure our buffer is freed */
+ if (mixBuffer != NULL)
+ {
+ free(mixBuffer);
+ mixBuffer = NULL;
+ }
+
+ 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_AUDIO;
+
+ if (PluginVersion != NULL)
+ *PluginVersion = SDL_AUDIO_PLUGIN_VERSION;
+
+ if (APIVersion != NULL)
+ *APIVersion = AUDIO_PLUGIN_API_VERSION;
+
+ if (PluginNamePtr != NULL)
+ *PluginNamePtr = "Mupen64Plus SDL Audio Plugin";
+
+ if (Capabilities != NULL)
+ {
+ *Capabilities = 0;
+ }
+
+ return M64ERR_SUCCESS;
+}
+
+/* ----------- Audio Functions ------------- */
+EXPORT void CALL AiDacrateChanged( int SystemType )
+{
+ int f = GameFreq;
+
+ if (!l_PluginInit)
+ return;
+
+ switch (SystemType)
+ {
+ case SYSTEM_NTSC:
+ f = 48681812 / (*AudioInfo.AI_DACRATE_REG + 1);
+ break;
+ case SYSTEM_PAL:
+ f = 49656530 / (*AudioInfo.AI_DACRATE_REG + 1);
+ break;
+ case SYSTEM_MPAL:
+ f = 48628316 / (*AudioInfo.AI_DACRATE_REG + 1);
+ break;
+ }
+ InitializeAudio(f);
+}
+
+
+EXPORT void CALL AiLenChanged( void )
+{
+ unsigned int LenReg;
+ unsigned char *p;
+ unsigned int CurrLevel, CurrTime, ExpectedLevel, ExpectedTime;
+
+ if (critical_failure == 1)
+ return;
+ if (!l_PluginInit)
+ return;
+
+ LenReg = *AudioInfo.AI_LEN_REG;
+ p = AudioInfo.RDRAM + (*AudioInfo.AI_DRAM_ADDR_REG & 0xFFFFFF);
+
+ if (buffer_pos + LenReg < primaryBufferBytes)
+ {
+ unsigned int i;
+
+ SDL_LockAudio();
+ for ( i = 0 ; i < LenReg ; i += 4 )
+ {
+
+ if(SwapChannels == 0)
+ {
+ // Left channel
+ primaryBuffer[ buffer_pos + i ] = p[ i + 2 ];
+ primaryBuffer[ buffer_pos + i + 1 ] = p[ i + 3 ];
+
+ // Right channel
+ primaryBuffer[ buffer_pos + i + 2 ] = p[ i ];
+ primaryBuffer[ buffer_pos + i + 3 ] = p[ i + 1 ];
+ } else {
+ // Left channel
+ primaryBuffer[ buffer_pos + i ] = p[ i ];
+ primaryBuffer[ buffer_pos + i + 1 ] = p[ i + 1 ];
+
+ // Right channel
+ primaryBuffer[ buffer_pos + i + 2 ] = p[ i + 2];
+ primaryBuffer[ buffer_pos + i + 3 ] = p[ i + 3 ];
+ }
+ }
+ buffer_pos += i;
+ SDL_UnlockAudio();
+ }
+ else
+ {
+ DebugMessage(M64MSG_WARNING, "AiLenChanged(): Audio buffer overflow.");
+ }
+
+ /* Now we need to handle synchronization, by inserting time delay to keep the emulator running at the correct speed */
+ /* Start by calculating the current Primary buffer fullness in terms of output samples */
+ CurrLevel = (unsigned int) (((long long) (buffer_pos/N64_SAMPLE_BYTES) * OutputFreq * 100) / (GameFreq * speed_factor));
+ /* Next, extrapolate to the buffer level at the expected time of the next audio callback, assuming that the
+ buffer is filled at the same rate as the output frequency */
+ CurrTime = SDL_GetTicks();
+ ExpectedTime = last_callback_ticks + ((1000 * SecondaryBufferSize) / OutputFreq);
+ ExpectedLevel = CurrLevel;
+ if (CurrTime < ExpectedTime)
+ ExpectedLevel += (ExpectedTime - CurrTime) * OutputFreq / 1000;
+ /* If the expected value of the Primary Buffer Fullness at the time of the next audio callback is more than 10
+ milliseconds ahead of our target buffer fullness level, then insert a delay now */
+ DebugMessage(M64MSG_VERBOSE, "%03i New audio bytes: %i Time to next callback: %i Current/Expected buffer level: %i/%i",
+ CurrTime % 1000, LenReg, (int) (ExpectedTime - CurrTime), CurrLevel, ExpectedLevel);
+ if (ExpectedLevel >= PrimaryBufferTarget + OutputFreq / 100)
+ {
+ unsigned int WaitTime = (ExpectedLevel - PrimaryBufferTarget) * 1000 / OutputFreq;
+ DebugMessage(M64MSG_VERBOSE, " AiLenChanged(): Waiting %ims", WaitTime);
+ if (l_PausedForSync)
+ SDL_PauseAudio(0);
+ l_PausedForSync = 0;
+ SDL_Delay(WaitTime);
+ }
+ /* Or if the expected level of the primary buffer is less than the secondary buffer size
+ (ie, predicting an underflow), then pause the audio to let the emulator catch up to speed */
+ else if (ExpectedLevel < SecondaryBufferSize)
+ {
+ DebugMessage(M64MSG_VERBOSE, " AiLenChanged(): Possible underflow at next audio callback; pausing playback");
+ if (!l_PausedForSync)
+ SDL_PauseAudio(1);
+ l_PausedForSync = 1;
+ }
+ /* otherwise the predicted buffer level is within our tolerance, so everything is okay */
+ else
+ {
+ if (l_PausedForSync)
+ SDL_PauseAudio(0);
+ l_PausedForSync = 0;
+ }
+}
+
+EXPORT int CALL InitiateAudio( AUDIO_INFO Audio_Info )
+{
+ if (!l_PluginInit)
+ return 0;
+
+ AudioInfo = Audio_Info;
+ return 1;
+}
+
+static int underrun_count = 0;
+
+#ifdef USE_SRC
+static float *_src = NULL;
+static unsigned int _src_len = 0;
+static float *_dest = NULL;
+static unsigned int _dest_len = 0;
+static int error;
+static SRC_STATE *src_state;
+static SRC_DATA src_data;
+#endif
+#ifdef USE_SPEEX
+SpeexResamplerState* spx_state = NULL;
+static int error;
+#endif
+
+static int resample(unsigned char *input, int input_avail, int oldsamplerate, unsigned char *output, int output_needed, int newsamplerate)
+{
+ int *psrc = (int*)input;
+ int *pdest = (int*)output;
+ int i = 0, j = 0;
+
+#ifdef USE_SPEEX
+ spx_uint32_t in_len, out_len;
+ if(Resample == RESAMPLER_SPEEX)
+ {
+ if(spx_state == NULL)
+ {
+ spx_state = speex_resampler_init(2, oldsamplerate, newsamplerate, ResampleQuality, &error);
+ if(spx_state == NULL)
+ {
+ memset(output, 0, output_needed);
+ return 0;
+ }
+ }
+ speex_resampler_set_rate(spx_state, oldsamplerate, newsamplerate);
+ in_len = input_avail / 4;
+ out_len = output_needed / 4;
+
+ if ((error = speex_resampler_process_interleaved_int(spx_state, (const spx_int16_t *)input, &in_len, (spx_int16_t *)output, &out_len)))
+ {
+ memset(output, 0, output_needed);
+ return input_avail; // number of bytes consumed
+ }
+ return in_len * 4;
+ }
+#endif
+#ifdef USE_SRC
+ if(Resample == RESAMPLER_SRC)
+ {
+ // the high quality resampler needs more input than the samplerate ratio would indicate to work properly
+ if (input_avail > output_needed * 3 / 2)
+ input_avail = output_needed * 3 / 2; // just to avoid too much short-float-short conversion time
+ if (_src_len < input_avail*2 && input_avail > 0)
+ {
+ if(_src) free(_src);
+ _src_len = input_avail*2;
+ _src = malloc(_src_len);
+ }
+ if (_dest_len < output_needed*2 && output_needed > 0)
+ {
+ if(_dest) free(_dest);
+ _dest_len = output_needed*2;
+ _dest = malloc(_dest_len);
+ }
+ memset(_src,0,_src_len);
+ memset(_dest,0,_dest_len);
+ if(src_state == NULL)
+ {
+ src_state = src_new (ResampleQuality, 2, &error);
+ if(src_state == NULL)
+ {
+ memset(output, 0, output_needed);
+ return 0;
+ }
+ }
+ src_short_to_float_array ((short *) input, _src, input_avail/2);
+ src_data.end_of_input = 0;
+ src_data.data_in = _src;
+ src_data.input_frames = input_avail/4;
+ src_data.src_ratio = (float) newsamplerate / oldsamplerate;
+ src_data.data_out = _dest;
+ src_data.output_frames = output_needed/4;
+ if ((error = src_process (src_state, &src_data)))
+ {
+ memset(output, 0, output_needed);
+ return input_avail; // number of bytes consumed
+ }
+ src_float_to_short_array (_dest, (short *) output, output_needed/2);
+ return src_data.input_frames_used * 4;
+ }
+#endif
+ // RESAMPLE == TRIVIAL
+ if (newsamplerate >= oldsamplerate)
+ {
+ int sldf = oldsamplerate;
+ int const2 = 2*sldf;
+ int dldf = newsamplerate;
+ int const1 = const2 - 2*dldf;
+ int criteria = const2 - dldf;
+ for (i = 0; i < output_needed/4; i++)
+ {
+ pdest[i] = psrc[j];
+ if(criteria >= 0)
+ {
+ ++j;
+ criteria += const1;
+ }
+ else criteria += const2;
+ }
+ return j * 4; //number of bytes consumed
+ }
+ // newsamplerate < oldsamplerate, this only happens when speed_factor > 1
+ for (i = 0; i < output_needed/4; i++)
+ {
+ j = i * oldsamplerate / newsamplerate;
+ pdest[i] = psrc[j];
+ }
+ return j * 4; //number of bytes consumed
+}
+
+static void my_audio_callback(void *userdata, unsigned char *stream, int len)
+{
+ int oldsamplerate, newsamplerate;
+
+ if (!l_PluginInit)
+ return;
+
+ /* mark the time, for synchronization on the input side */
+ last_callback_ticks = SDL_GetTicks();
+
+ newsamplerate = OutputFreq * 100 / speed_factor;
+ oldsamplerate = GameFreq;
+
+ if (buffer_pos > (unsigned int) (len * oldsamplerate) / newsamplerate)
+ {
+ int input_used;
+#if defined(HAS_OSS_SUPPORT)
+ if (VolumeControlType == VOLUME_TYPE_OSS)
+ {
+ input_used = resample(primaryBuffer, buffer_pos, oldsamplerate, stream, len, newsamplerate);
+ }
+ else
+#endif
+ {
+ input_used = resample(primaryBuffer, buffer_pos, oldsamplerate, mixBuffer, len, newsamplerate);
+ memset(stream, 0, len);
+ SDL_MixAudio(stream, mixBuffer, len, VolSDL);
+ }
+ memmove(primaryBuffer, &primaryBuffer[input_used], buffer_pos - input_used);
+ buffer_pos -= input_used;
+ DebugMessage(M64MSG_VERBOSE, "%03i my_audio_callback: used %i samples",
+ last_callback_ticks % 1000, len / SDL_SAMPLE_BYTES);
+ }
+ else
+ {
+ unsigned int SamplesNeeded = (len * oldsamplerate) / (newsamplerate * SDL_SAMPLE_BYTES);
+ unsigned int SamplesPresent = buffer_pos / N64_SAMPLE_BYTES;
+ underrun_count++;
+ DebugMessage(M64MSG_VERBOSE, "%03i Buffer underflow (%i). %i samples present, %i needed",
+ last_callback_ticks % 1000, underrun_count, SamplesPresent, SamplesNeeded);
+ memset(stream , 0, len);
+ }
+}
+EXPORT int CALL RomOpen(void)
+{
+ if (!l_PluginInit)
+ return 0;
+
+ ReadConfig();
+ InitializeAudio(GameFreq);
+ return 1;
+}
+
+static void InitializeSDL(void)
+{
+ DebugMessage(M64MSG_INFO, "Initializing SDL audio subsystem...");
+
+ if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
+ {
+ DebugMessage(M64MSG_ERROR, "Failed to initialize SDL audio subsystem; forcing exit.\n");
+ critical_failure = 1;
+ return;
+ }
+ critical_failure = 0;
+
+}
+
+static void CreatePrimaryBuffer(void)
+{
+ unsigned int newPrimaryBytes = (unsigned int) ((long long) PrimaryBufferSize * GameFreq * speed_factor /
+ (OutputFreq * 100)) * N64_SAMPLE_BYTES;
+ if (primaryBuffer == NULL)
+ {
+ DebugMessage(M64MSG_VERBOSE, "Allocating memory for audio buffer: %i bytes.", newPrimaryBytes);
+ primaryBuffer = (unsigned char*) malloc(newPrimaryBytes);
+ memset(primaryBuffer, 0, newPrimaryBytes);
+ primaryBufferBytes = newPrimaryBytes;
+ }
+ else if (newPrimaryBytes > primaryBufferBytes) /* primary buffer only grows; there's no point in shrinking it */
+ {
+ unsigned char *newPrimaryBuffer = (unsigned char*) malloc(newPrimaryBytes);
+ unsigned char *oldPrimaryBuffer = primaryBuffer;
+ SDL_LockAudio();
+ memcpy(newPrimaryBuffer, oldPrimaryBuffer, primaryBufferBytes);
+ memset(newPrimaryBuffer + primaryBufferBytes, 0, newPrimaryBytes - primaryBufferBytes);
+ primaryBuffer = newPrimaryBuffer;
+ primaryBufferBytes = newPrimaryBytes;
+ SDL_UnlockAudio();
+ free(oldPrimaryBuffer);
+ }
+}
+
+static void InitializeAudio(int freq)
+{
+ SDL_AudioSpec *desired, *obtained;
+
+ if(SDL_WasInit(SDL_INIT_AUDIO|SDL_INIT_TIMER) == (SDL_INIT_AUDIO|SDL_INIT_TIMER) )
+ {
+ DebugMessage(M64MSG_VERBOSE, "InitializeAudio(): SDL Audio sub-system already initialized.");
+ SDL_PauseAudio(1);
+ SDL_CloseAudio();
+ }
+ else
+ {
+ DebugMessage(M64MSG_VERBOSE, "InitializeAudio(): Initializing SDL Audio");
+ DebugMessage(M64MSG_VERBOSE, "Primary buffer: %i output samples.", PrimaryBufferSize);
+ DebugMessage(M64MSG_VERBOSE, "Primary target fullness: %i output samples.", PrimaryBufferTarget);
+ DebugMessage(M64MSG_VERBOSE, "Secondary buffer: %i output samples.", SecondaryBufferSize);
+ InitializeSDL();
+ }
+ if (critical_failure == 1)
+ return;
+ GameFreq = freq; // This is important for the sync
+ if(hardware_spec != NULL) free(hardware_spec);
+
+ // Allocate space for SDL_AudioSpec
+ desired = malloc(sizeof(SDL_AudioSpec));
+ obtained = malloc(sizeof(SDL_AudioSpec));
+
+ if(freq < 11025) OutputFreq = 11025;
+ else if(freq < 22050) OutputFreq = 22050;
+ else OutputFreq = 44100;
+
+ desired->freq = OutputFreq;
+
+ DebugMessage(M64MSG_VERBOSE, "Requesting frequency: %iHz.", desired->freq);
+ /* 16-bit signed audio */
+ desired->format=AUDIO_S16SYS;
+ DebugMessage(M64MSG_VERBOSE, "Requesting format: %i.", desired->format);
+ /* Stereo */
+ desired->channels=2;
+ /* reload these because they gets re-assigned from SDL data below, and InitializeAudio can be called more than once */
+ PrimaryBufferSize = ConfigGetParamInt(l_ConfigAudio, "PRIMARY_BUFFER_SIZE");
+ PrimaryBufferTarget = ConfigGetParamInt(l_ConfigAudio, "PRIMARY_BUFFER_TARGET");
+ SecondaryBufferSize = ConfigGetParamInt(l_ConfigAudio, "SECONDARY_BUFFER_SIZE");
+ desired->samples = SecondaryBufferSize;
+ /* Our callback function */
+ desired->callback = my_audio_callback;
+ desired->userdata = NULL;
+
+ /* Open the audio device */
+ l_PausedForSync = 1;
+ if (SDL_OpenAudio(desired, obtained) < 0)
+ {
+ DebugMessage(M64MSG_ERROR, "Couldn't open audio: %s", SDL_GetError());
+ critical_failure = 1;
+ return;
+ }
+ if (desired->format != obtained->format)
+ {
+ DebugMessage(M64MSG_WARNING, "Obtained audio format differs from requested.");
+ }
+ if (desired->freq != obtained->freq)
+ {
+ DebugMessage(M64MSG_WARNING, "Obtained frequency differs from requested.");
+ }
+
+ /* desired spec is no longer needed */
+ free(desired);
+ hardware_spec=obtained;
+
+ /* allocate memory for audio buffers */
+ OutputFreq = hardware_spec->freq;
+ SecondaryBufferSize = hardware_spec->samples;
+ if (PrimaryBufferTarget < SecondaryBufferSize)
+ PrimaryBufferTarget = SecondaryBufferSize;
+ if (PrimaryBufferSize < PrimaryBufferTarget)
+ PrimaryBufferSize = PrimaryBufferTarget;
+ if (PrimaryBufferSize < SecondaryBufferSize * 2)
+ PrimaryBufferSize = SecondaryBufferSize * 2;
+ CreatePrimaryBuffer();
+ if (mixBuffer != NULL)
+ free(mixBuffer);
+ mixBuffer = (unsigned char*) malloc(SecondaryBufferSize * SDL_SAMPLE_BYTES);
+
+ /* preset the last callback time */
+ if (last_callback_ticks == 0)
+ last_callback_ticks = SDL_GetTicks();
+
+ DebugMessage(M64MSG_VERBOSE, "Frequency: %i", hardware_spec->freq);
+ DebugMessage(M64MSG_VERBOSE, "Format: %i", hardware_spec->format);
+ DebugMessage(M64MSG_VERBOSE, "Channels: %i", hardware_spec->channels);
+ DebugMessage(M64MSG_VERBOSE, "Silence: %i", hardware_spec->silence);
+ DebugMessage(M64MSG_VERBOSE, "Samples: %i", hardware_spec->samples);
+ DebugMessage(M64MSG_VERBOSE, "Size: %i", hardware_spec->size);
+
+ /* set playback volume */
+#if defined(HAS_OSS_SUPPORT)
+ if (VolumeControlType == VOLUME_TYPE_OSS)
+ {
+ VolPercent = volGet();
+ }
+ else
+#endif
+ {
+ VolSDL = SDL_MIX_MAXVOLUME * VolPercent / 100;
+ }
+
+}
+EXPORT void CALL RomClosed( void )
+{
+ if (!l_PluginInit)
+ return;
+ if (critical_failure == 1)
+ return;
+ DebugMessage(M64MSG_VERBOSE, "Cleaning up SDL sound plugin...");
+
+ // Shut down SDL Audio output
+ SDL_PauseAudio(1);
+ SDL_CloseAudio();
+
+ // Delete the buffer, as we are done producing sound
+ if (primaryBuffer != NULL)
+ {
+ primaryBufferBytes = 0;
+ free(primaryBuffer);
+ primaryBuffer = NULL;
+ }
+ if (mixBuffer != NULL)
+ {
+ free(mixBuffer);
+ mixBuffer = NULL;
+ }
+
+ // Delete the hardware spec struct
+ if(hardware_spec != NULL) free(hardware_spec);
+ hardware_spec = NULL;
+
+ // Shutdown the respective subsystems
+ if(SDL_WasInit(SDL_INIT_AUDIO) != 0) SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ if(SDL_WasInit(SDL_INIT_TIMER) != 0) SDL_QuitSubSystem(SDL_INIT_TIMER);
+}
+
+EXPORT void CALL ProcessAList(void)
+{
+}
+
+EXPORT void CALL SetSpeedFactor(int percentage)
+{
+ if (!l_PluginInit)
+ return;
+ if (percentage >= 10 && percentage <= 300)
+ speed_factor = percentage;
+ // we need a different size primary buffer to store the N64 samples when the speed changes
+ CreatePrimaryBuffer();
+}
+
+static void ReadConfig(void)
+{
+ const char *resampler_id;
+
+ /* read the configuration values into our static variables */
+ GameFreq = ConfigGetParamInt(l_ConfigAudio, "DEFAULT_FREQUENCY");
+ SwapChannels = ConfigGetParamBool(l_ConfigAudio, "SWAP_CHANNELS");
+ PrimaryBufferSize = ConfigGetParamInt(l_ConfigAudio, "PRIMARY_BUFFER_SIZE");
+ PrimaryBufferTarget = ConfigGetParamInt(l_ConfigAudio, "PRIMARY_BUFFER_TARGET");
+ SecondaryBufferSize = ConfigGetParamInt(l_ConfigAudio, "SECONDARY_BUFFER_SIZE");
+ resampler_id = ConfigGetParamString(l_ConfigAudio, "RESAMPLE");
+ VolumeControlType = ConfigGetParamInt(l_ConfigAudio, "VOLUME_CONTROL_TYPE");
+ VolDelta = ConfigGetParamInt(l_ConfigAudio, "VOLUME_ADJUST");
+ VolPercent = ConfigGetParamInt(l_ConfigAudio, "VOLUME_DEFAULT");
+
+ if (!resampler_id) {
+ Resample = RESAMPLER_TRIVIAL;
+ DebugMessage(M64MSG_WARNING, "Could not find RESAMPLE configuration; use trivial resampler");
+ return;
+ }
+ if (strcmp(resampler_id, "trivial") == 0) {
+ Resample = RESAMPLER_TRIVIAL;
+ return;
+ }
+#ifdef USE_SPEEX
+ if (strncmp(resampler_id, "speex-fixed-", strlen("speex-fixed-")) == 0) {
+ int i;
+ static const char *speex_quality[] = {
+ "speex-fixed-0",
+ "speex-fixed-1",
+ "speex-fixed-2",
+ "speex-fixed-3",
+ "speex-fixed-4",
+ "speex-fixed-5",
+ "speex-fixed-6",
+ "speex-fixed-7",
+ "speex-fixed-8",
+ "speex-fixed-9",
+ "speex-fixed-10",
+ };
+ Resample = RESAMPLER_SPEEX;
+ for (i = 0; i < sizeof(speex_quality) / sizeof(*speex_quality); i++) {
+ if (strcmp(speex_quality[i], resampler_id) == 0) {
+ ResampleQuality = i;
+ return;
+ }
+ }
+ DebugMessage(M64MSG_WARNING, "Unknown RESAMPLE configuration %s; use speex-fixed-4 resampler", resampler_id);
+ ResampleQuality = 4;
+ return;
+ }
+#endif
+#ifdef USE_SRC
+ if (strncmp(resampler_id, "src-", strlen("src-")) == 0) {
+ Resample = RESAMPLER_SRC;
+ if (strcmp(resampler_id, "src-sinc-best-quality") == 0) {
+ ResampleQuality = SRC_SINC_BEST_QUALITY;
+ return;
+ }
+ if (strcmp(resampler_id, "src-sinc-medium-quality") == 0) {
+ ResampleQuality = SRC_SINC_MEDIUM_QUALITY;
+ return;
+ }
+ if (strcmp(resampler_id, "src-sinc-fastest") == 0) {
+ ResampleQuality = SRC_SINC_FASTEST;
+ return;
+ }
+ if (strcmp(resampler_id, "src-zero-order-hold") == 0) {
+ ResampleQuality = SRC_ZERO_ORDER_HOLD;
+ return;
+ }
+ if (strcmp(resampler_id, "src-linear") == 0) {
+ ResampleQuality = SRC_LINEAR;
+ return;
+ }
+ DebugMessage(M64MSG_WARNING, "Unknown RESAMPLE configuration %s; use src-sinc-medium-quality resampler", resampler_id);
+ ResampleQuality = SRC_SINC_MEDIUM_QUALITY;
+ return;
+ }
+#endif
+ DebugMessage(M64MSG_WARNING, "Unknown RESAMPLE configuration %s; use trivial resampler", resampler_id);
+ Resample = RESAMPLER_TRIVIAL;
+}
+
+// Returns the most recent ummuted volume level.
+static int VolumeGetUnmutedLevel(void)
+{
+#if defined(HAS_OSS_SUPPORT)
+ // reload volume if we're using OSS
+ if (!VolIsMuted && VolumeControlType == VOLUME_TYPE_OSS)
+ {
+ return volGet();
+ }
+#endif
+
+ return VolPercent;
+}
+
+// Sets the volume level based on the contents of VolPercent and VolIsMuted
+static void VolumeCommit(void)
+{
+ int levelToCommit = VolIsMuted ? 0 : VolPercent;
+
+#if defined(HAS_OSS_SUPPORT)
+ if (VolumeControlType == VOLUME_TYPE_OSS)
+ {
+ //OSS mixer volume
+ volSet(levelToCommit);
+ }
+ else
+#endif
+ {
+ VolSDL = SDL_MIX_MAXVOLUME * levelToCommit / 100;
+ }
+}
+
+EXPORT void CALL VolumeMute(void)
+{
+ if (!l_PluginInit)
+ return;
+
+ // Store the volume level in order to restore it later
+ if (!VolIsMuted)
+ VolPercent = VolumeGetUnmutedLevel();
+
+ // Toogle mute
+ VolIsMuted = !VolIsMuted;
+ VolumeCommit();
+}
+
+EXPORT void CALL VolumeUp(void)
+{
+ if (!l_PluginInit)
+ return;
+
+ VolumeSetLevel(VolumeGetUnmutedLevel() + VolDelta);
+}
+
+EXPORT void CALL VolumeDown(void)
+{
+ if (!l_PluginInit)
+ return;
+
+ VolumeSetLevel(VolumeGetUnmutedLevel() - VolDelta);
+}
+
+EXPORT int CALL VolumeGetLevel(void)
+{
+ return VolIsMuted ? 0 : VolumeGetUnmutedLevel();
+}
+
+EXPORT void CALL VolumeSetLevel(int level)
+{
+ if (!l_PluginInit)
+ return;
+
+ //if muted, unmute first
+ VolIsMuted = 0;
+
+ // adjust volume
+ VolPercent = level;
+ if (VolPercent < 0)
+ VolPercent = 0;
+ else if (VolPercent > 100)
+ VolPercent = 100;
+
+ VolumeCommit();
+}
+
+EXPORT const char * CALL VolumeGetString(void)
+{
+ static char VolumeString[32];
+
+ if (VolIsMuted)
+ {
+ strcpy(VolumeString, "Mute");
+ }
+ else
+ {
+ sprintf(VolumeString, "%i%%", VolPercent);
+ }
+
+ return VolumeString;
+}
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus - main.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2008-2012 Tillin9, Richard42 *
+ * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* version info */
+#define SDL_AUDIO_PLUGIN_VERSION 0x020000
+#define AUDIO_PLUGIN_API_VERSION 0x020000
+#define CONFIG_API_VERSION 0x020100
+#define CONFIG_PARAM_VERSION 1.00
+
+#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)
+
+/* declarations of pointers to Core config functions */
+extern ptr_ConfigListSections ConfigListSections;
+extern ptr_ConfigOpenSection ConfigOpenSection;
+extern ptr_ConfigDeleteSection ConfigDeleteSection;
+extern ptr_ConfigSaveSection ConfigSaveSection;
+extern ptr_ConfigListParameters ConfigListParameters;
+extern ptr_ConfigSaveFile ConfigSaveFile;
+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;
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-core - osal/dynamiclib.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if !defined(OSAL_DYNAMICLIB_H)
+#define OSAL_DYNAMICLIB_H
+
+#include "m64p_types.h"
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName);
+
+#endif /* #define OSAL_DYNAMICLIB_H */
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-core - osal/dynamiclib_unix.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include "m64p_types.h"
+#include "osal_dynamiclib.h"
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
+{
+ if (pccProcedureName == NULL)
+ return NULL;
+
+ return dlsym(LibHandle, pccProcedureName);
+}
+
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-ui-console - osal_dynamiclib_win32.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "m64p_types.h"
+#include "osal_dynamiclib.h"
+
+m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath)
+{
+ if (pLibHandle == NULL || pccLibraryPath == NULL)
+ return M64ERR_INPUT_ASSERT;
+
+ *pLibHandle = LoadLibrary(pccLibraryPath);
+
+ if (*pLibHandle == NULL)
+ {
+ char *pchErrMsg;
+ DWORD dwErr = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+ fprintf(stderr, "LoadLibrary('%s') error: %s\n", pccLibraryPath, pchErrMsg);
+ LocalFree(pchErrMsg);
+ return M64ERR_INPUT_NOT_FOUND;
+ }
+
+ return M64ERR_SUCCESS;
+}
+
+void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName)
+{
+ if (pccProcedureName == NULL)
+ return NULL;
+
+ return GetProcAddress(LibHandle, pccProcedureName);
+}
+
+m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle)
+{
+ int rval = FreeLibrary(LibHandle);
+
+ if (rval == 0)
+ {
+ char *pchErrMsg;
+ DWORD dwErr = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL);
+ fprintf(stderr, "FreeLibrary() error: %s\n", pchErrMsg);
+ LocalFree(pchErrMsg);
+ return M64ERR_INTERNAL;
+ }
+
+ return M64ERR_SUCCESS;
+}
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-sdl-audio - volume.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2007-2008 Richard42 Ebenblues *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if defined(HAS_OSS_SUPPORT)
+
+/* Sound volume functions. */
+#include <sys/soundcard.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h> /* close() */
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "volume.h"
+
+/* volSet
+ * Sets volume of left and right PCM channels to given percentage (0-100) value.
+ */
+void volSet(int percent)
+{
+ int ret, vol;
+ int mixerfd = open("/dev/mixer", O_RDONLY);
+
+ if(mixerfd < 0)
+ {
+ perror("/dev/mixer");
+ return;
+ }
+
+ if(percent > 100)
+ percent = 100;
+ else if(percent < 0)
+ percent = 0;
+
+ vol = (percent << 8) + percent; // set both left/right channels to same vol
+ ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &vol);
+ if(ret < 0)
+ perror("Setting PCM volume");
+
+ close(mixerfd);
+}
+
+/* volGet
+ * Returns volume of PCM channel as a percentage (0-100).
+ * Returns 0 on error.
+ */
+int volGet(void)
+{
+ int vol, ret;
+ int mixerfd = open("/dev/mixer", O_RDONLY);
+
+ if(mixerfd < 0)
+ {
+ perror("/dev/mixer");
+ return 0;
+ }
+
+ ret = ioctl(mixerfd, MIXER_READ(SOUND_MIXER_PCM), &vol);
+ if(ret < 0)
+ perror("Reading PCM volume");
+
+ close(mixerfd);
+
+ return vol & 0xff; // just return the left channel
+}
+
+#endif /* defined(HAS_OSS_SUPPORT) */
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus - nogui.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2007-2008 Richard42 Ebenblues *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Sound volume functions.
+ */
+
+#ifndef __VOLUME_H__
+#define __VOLUME_H__
+
+void volSet(int);
+int volGet(void);
+
+#endif // __VOLUME_H__
+