commit c553ce3bebdaae934cb0573ad5b1abd7d5f2ef6c Author: Scott Duensing Date: Mon Nov 11 14:53:02 2019 -0600 Initial commit diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/HOW_TO_COMPILE_LINUX.txt b/HOW_TO_COMPILE_LINUX.txt new file mode 100644 index 000000000..9f6a4a002 --- /dev/null +++ b/HOW_TO_COMPILE_LINUX.txt @@ -0,0 +1,89 @@ +At the time of this writing, DAPHNE will compile fully under these unix'ish +platforms: +- Ubuntu Linux version 11.04 (x86) +- i386 GNU/Linux (primary platform) +- i386 FreeBSD +- Sparc Solaris (untested) + +MAC OSX USERS SHOULD USE THE XCODE PROJ INSIDE THE MACOSX DIRECTORY!!! +The MAC OSX Makefile method is obsolete and is no longer maintained! + +-------------------------- +STEP BY STEP INSTRUCTIONS: +-------------------------- + +- Make sure you have g++, make, and sed installed. + +- Install these libraries (with headers) if you don't already have them: + SDL 1.2 (tested with 1.2.14, older versions may work fine) + SDL NOTE: + To have minimum hardware acceleration, SDL needs to be built with "xv" support. + "OpenGL" support is also recommended for better hardware acceleration. + SLD_image + SDL_ttf + libfreetype6-dev + Ogg Vorbis (libogg, libvorbis, libvorbisfile) + Zlib + GLEW (http://glew.sourceforge.net) + +- You will most likely have to convert the source files line endings to Unix format. +Install dos2unix or similar tool for this. + +- Now you are ready to compile. Daphne doesn't use the traditional +autoconf/automake nonsense. Instead, it uses a separate Makefile for +each platform. To compile under GNU/Linux, open up a termianl window and +type this (from the src directory): + + cp Makefile.vars.linux_x86 Makefile.vars + make + +(You'd do something similar if you were compiling under the other platforms.) + +- You also need to compile libvldp2.so which comes with DAPHNE and has its +own set of instructions inside the vldp2 directory. When you get there +type: + + chmod +x configure + ./configure + make -f Makefile.linux + +- If compiling SINGE then you also need to comple libsinge.so separately +before making Daphne. Go to the game/singe folder and type: + +make -f Makefile.linux + +- Once you got your libraries compiled then return to the main "src" +directory. Begin the compiling process by typing "make". + +----------------------------------------------------------------------------- + +An alternate way... + +Go to the "src" folder and rename the appropriate Makefile.vars.linux_x?? +to Makefile.vars. Open up a terminal window and type the following: + + chmod +x buildme.sh + ./buildme.sh + + +If everything goes correctly it should compile daphne with the vldp2 +and singe libraries. + + +---------------------- LINUX QUESTIONS ------------------------- + ++ "Can't load VLDP2 library" + +Open up a terminal window. Navigate to daphne's main directory and type: + + export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH + +Another way is to copy libvldp2.so and linsinge.so to /usr/lib. + + sudo cp libvldp2.so /usr/lib + sudo cp libsinge.so /usr/lib + ++ Daphne hangs after quitting. + +This is a known issue with static singe builds under linux. +Use a dynamic build instead. diff --git a/HOW_TO_COMPILE_WIN32.txt b/HOW_TO_COMPILE_WIN32.txt new file mode 100644 index 000000000..7aef4dd8d --- /dev/null +++ b/HOW_TO_COMPILE_WIN32.txt @@ -0,0 +1,432 @@ +******************************************************************************* +HOW TO COMPILE DAPHNE UNDER WIN32 +******************************************************************************* + +The following document explains how to compile Daphne under Windows. +Start by reading "The Short Version" to get an general idea of what +you need to do. From there proceed to read the rest of the document +for more specific details that may help you solve or avoid potential +problems. + + +Contents: + + A. The Short Version + B. Tested development enviroments + C. Compiler Quirks + D. Library Quirks + E. Libraries to Get + F. Organizing your libraries + G. Opening and compiling the Daphne project + H. Troubleshooting Compiler and Linking Errors + I. Installing your generated daphne file + + +******************************************************************************* +A. The Short Version +******************************************************************************* + + 1. Check part E for what libraries you need to get. If you need + to generate your own libraries then go ahead and do so. + 2. On the very same folder where you found this text file double click + on the solution file "daphne_vs2003.sln". + 3. Select the type of build you wish to create (debug or release). + 4. Take a minute to add the necessary paths to your project's directory + lists for "include" and "library" settings. + 5. Check daphne's C++ pre-processor settings and if needed modify + it to meet your needs (eg, add/remove ZLIB_WINAPI or BUILD_SINGE). + 6. Check daphne's Linker Input Settings so all libraries + are correctly spelled. + 7. Build your solution. + + +******************************************************************************* +B. Tested Development Environments +******************************************************************************* + + +Daphne has been tested to compile under the following Microsoft products: + + Visual C++ 6 + Visual C++ .NET 2003 (a.k.a. Visual C++ 7.1) + Visual C++ 2005 (a.k.a. Visual C++ 8.0) + Visual C++ 2008 (a.k.a. Visual C++ 9.0) + Visual C++ 2010 (a.k.a. Visual C++ 10.0) + + +******************************************************************************* +C. Compiler Quirks: +******************************************************************************* + +If you are using Visual C++ 6: + + - Make sure you have MASM installed. VS7.1 automatically comes with this + installed. If you are using VS6, you may need to upgrade to + service pack 5 and then install the Processor Pack in order to get MASM. + There are other ways to get it installed, but this way requires the + shortest explanation :). + + - Get SDL-devel-1.x.xx-VC6.zip. + + +If you are using Visual C++ 2003: + + - If compiling your own libogg and libvorbis libraries then get + version 1.2.0 for both. That's the last version that supported this + compiler. You can find it by browsing older release versions + at the xiph.org address below: + + http://downloads.xiph.org/releases/ogg/ + + +If you are using Visual C++ 2005: + + - Make sure you apply Service Pack 1. Some newer libraries (eg, libSDL) + may generate errors if you don't. + + +If you are using Visual Studio 2010 Express Edition: + + - Be aware this edition may not compile libogg nor libvorbis + right out of the box. Visual Studio 2008 Express Edition does + not have this problem. + + +The following may apply to any Visual Studio version: + + - It is very likely you will have to update your project's linker + properties so that it correctly spells the right filenames for the + libraries you want to compile against. For example depending on what you + use you may have to rename vorbis.lib to libvorbis.lib or + zlib.lib to zlibwapi.lib. This is usually done at the property pages for + your Daphne project: + + + For VS2003: At the Solution Explorer right click on "daphne" + and select "Properties". From there choose "Linker"-->"Input" + + + For VS2005/2008/2010: + + (Alt+F7)-->Configuration Properties-->Linker-->Input + Check the field "Additional Dependencies". + + - Visual Studio VC++ 2005 and newer need an additional package called + "VC Redistributable Package" (eg, vcredist_x86.exe) installed for + any compiled program to work outside the developing environment. + + Some computers have this installed by other programs or Windows updates. + This will solve error messages like "the application configuration is + incorrect". Keep this in mind when installing your custom created + Daphne on a target machine. + + +******************************************************************************* +D. Library Quirks (applies to all compilers): +******************************************************************************* + + + + +++++++++ SDL Libraries +++++++++ + + - When dealing with SDL libraries make sure + to choose the correct one for the version of Visual C you + are using. Usually there is a separate zip file with the suffix + "VC6", "VC8" or "VC". + + +++++++++ OGG and VORBIS +++++++++ + + - When working with libogg and libvorbis you will have to + compile the libraries on your own. Take a look inside + the directory structure libogg and libvorbis. Be sure to select + the right folder pointing the project or solution file + corresponding to the compiler version you are using. + These folders are usually named "vs2003", "vs2005" or "vs2008". + Failure to match these with the correct compiler may result + in compiler errors. + + - libvorbis uses libogg, so compile libogg first and later add the + library path to your compiler "VC++ directories" configuration + for libvorbis. + + - libvorbis has four main projects, but the ones you need + are libvorbis and libvorbisfile. + + + +++++++++ ZLIB +++++++++ + + - Save some time by downloading pre-compiled zlib libraries. + You can find them at http://www.winimage.com/zLibDll/index.html + Be aware you will still need to get the header files as well. + - Latest ZLIB versions require the word "ZLIB_WINAPI" + declared in the project's pre-processor project settings. + - Library naming conventions changed too. + Use "zlibwapi.lib" instead of "zlib.lib" + + + +******************************************************************************* +E. Libraries to Get: +******************************************************************************* + + + To compile Daphne you need to have the following libraries: + + + libSDL - http://www.libsdl.org + + libGLEW - http://glew.sourceforge.net + + libOgg - http://xiph.org/downloads/ + + libVorbis - http://xiph.org/downloads/ + + zlib - http://www.zlib.net/ + + + +++++++++ Optional: Compiling SINGE with Daphne +++++++++ + + To compile the SINGE add-on for Daphne you also need to add: + + + libSDL_image - http://www.libsdl.org/projects/SDL_image/ + + libSDL_ttf - http://www.libsdl.org/projects/SDL_ttf/ + + + SINGE add-on is built by default. If you wish to disable it then + remove the words "BUILD_SINGE" on daphne's pre-processor project settings. + + + + +******************************************************************************* +F. Organizing your libraries: +******************************************************************************* + + + It's recommended you create a folder where to extract + all the downloaded librares. You will need to add new directories to the + Include category to point to the include files for the packages you + just downloaded. For example, you might add an entries like these: + + c:\mylibs\sdl-1.2\include + c:\mylibs\libogg-1.2.0\include + c:\mylibs\zlib-1.14 + c:\mylibs\glew\include + + + To access the Directories tab of your compiler: + + + VS6, go to Tools->Options then click on + Projects->Directories tab. + + VS7.1 go to Tools->Options->Projects then click on the + Directories tab. + + VS2005/2008 go to: + Tools->Options->Projects and Solutions->VC++ Directories. + + + You will also need to add entries to the "Library" category (as opposed + to the "Include" category you just added entries for). + Your library entries might look like this: + + c:\mylibs\sdl-1.2\lib + c:\mylibs\sdl_mixer-1.2.0\lib + C:\mylibs\libogg-1.2.0\win32\VS2005\Win32\Release + c:\mylibs\zlib-1.14\dll32 + c:\mylibs\glew\lib + + + + - How to set Global VC++ Directories in Visual Studio 2010: + + VS2010 does things a little bit differently. Use the following + instructions to set a group of directories globally to all + projects inside a solution: + + 1. Select Tools->Settings->Expert Settings. + 2. Open up the daphne_vs2010.sln solution file. + 3. Select View->Property Manager and expand the node for 'daphne'. + 4. Expand the node for either "Debug" or "Release". + 5. Right click on "Microsoft.Corp..user" + and select "Properties". + 6. At the "Daphne Property Pages" window, select + Configuration Properties->VC++ Directories + + 7. Add the additional directories for include and library. + Hit OK when you are done. + 8. Save your project and exit Visual Studio altogether. + 9. Relaunch Visual studio and open your daphne solution. + Your directories changes should now apply globally + to all the projects in the solution. + + + + +******************************************************************************* +G. Opening and Compiling the Daphne project: +******************************************************************************* + + + + Go to File->Open Solution and open the daphne_vs2003.sln (or double click + on the solution in the src folder). + + + If using a newer Visual C++ compiler versions then you will see the + Conversion Wizard pop up. Let it convert your project to your Visual C++ + version. Take a moment to read "Troubleshooting Compiler/Linker Errors" and + fix the problem with ".\daphne.rc(10) fatal error RC1015". + + + Select the kind of build you want (Debug or Release). + + + Make sure your C++ pre-processor settings have all the right values! + Make sure your Linker "Input" settings have all the libraries + correctly spelled! + + + On the menu toolbar select "Build->Build Solution". + + +At this point you should be ready to compile. Good Luck! + + + +******************************************************************************* +H. Troubleshooting Compiler and Linking Errors: +******************************************************************************* + + ++ .\daphne.rc(10) : fatal error RC1015: cannot open include file 'afxres.h' + + Happens when converting the VS2003 project solution to a newer + Visual Studio version. Open up daphne.rc and change the + following line: + + #include "afxres.h" + + + to this: + + #include "windows.h" + ++ LINK : fatal error LNK????: cannot open input file '*******.lib' + + Visual Studio can't find the specified library. + Probably the file is misspelled in the linker properties. + Usually happens with zlib, libogg or libvorbis libraries. + + Check that the library files declared in the project linker + "INPUT" properties are correctly spelled and that your library + directories are pointing to the right places. + ++ error PRJ0019: A tool returned an error code from + "Performing Custom Build Step" + + Happens when compiling SINGE. Fix it by moving your "src" folder + to a path that does not use spaces in its name. + ++ error LNK2001: unresolved external symbol __imp___CrtDbgReportW + + Happens when trying to generate a multi-threaded release build + on a debug build. + + Fix it by going to daphne's Property Pages (right click + on the project name in the Solution Explorer pane then choose + "Properties"). Once you are there select + + Configuration Properties->C/C++->Code Generation + + Change the value in the "Runtime Library" option + to "Multi-threaded Debug DLL". + ++ error LNK2005: already defined in LIBCMTD.lib + + You'll get this error when using VS2005 without + the Service Pack 1 installed against the libraries in the SDL package + "SDL-devel-1.?.??-VC8.zip". Fix it by updating your compiler + to SP1 or by using "SDL-devel-1.?.??-VC6.zip" instead. + ++ vorbisfile.h(59): error C3861: '_fseeki64': identifier not found, even with + argument-dependent lookup + + Happens when tryping to compile a newer libvorbis library + with the older Visual Studio 2003. Quick fix is to + use an older libvorbis version (or a newer VS compiler). + + Long fix: Open up vorbisfile.h and go to line 59. Change the + following: + + return _fseeki64(f,off,whence); + + to this: + + return fseek(f,off,whence); + + ++ LINK: ... unresolved external symbol _crc32 .... + + Happens when trying to compile with the latest + zlib versions. Add the word "ZLIB_WINAPI" (without the quotes) + to the preprocessor compile settings for the "daphne" project. + + + ++ "This application has failed to start because was not found. + Re-installing the application may fix this problem" + + Project "daphne_test" expects to find SDL.dll and inpout32.dll + after it's done compiling. When it doesn't it complains with this + message, but the project will finish successfully. You can happily + hit OK and ignore this message. + + ...Or you can copy SDL.dll and inpout32.dll to the place + where Visual Studio dumps all the generated programs (one directory + above the "src" folder). + + +******************************************************************************* +I. Installing your generated daphne file +******************************************************************************* + +You got through all the hurdles and got daphne to compile. Congrats. +Now what next? At this point you might be tempted to simply copy +the generated daphne.exe to the folder where your official daphne release +is located. + +While this may work, the official daphne distribution may have +DLL files that are incompatible with your custom created daphne. +If you get DLL related errors then you need to copy the appropriate +DLL files as well. Those binary files can be found at each of the +library directories you setup previously. In order to save you some time +here is a list of what you need to look for. Copy these files in the same +location where you place your generated daphne.exe file: + + + + vldp2.dll and singe.dll from the same folder you + got daphne.exe. + + + SDL.dll from the SDL-1.x.xx folder + + + glew32.dll from the libglew folder + + + zlib.dll (if using version 1.14) or + zlibwapi.dll (if using a newer zlib version like 1.2.5) + + + SDL_image.dll, zlib1.dll, libpng12-0.dll from + the SDL_image folder. + + + SDL_ttf.dll and libfreetype-6.dll from the SDL_ttf folder. + + + libogg.dll from somewhere inside the libogg folder. + + + libvorbis.dll and libvorbisfile.dll from within the libvorbis folder. + + + inpout32.dll is found in the official daphne build. + If you don't see it then run Daphne Loader and + update to the latest version. + + + msvcp71.dll and msvcr71.dll if using VS2003. + + + For VS2005 and newer you need to install the Visual C++ + Redistibutable package (vcredist_x86.exe) on the target machine. + Simply copying the DLLs over won't work. + + +******************************************************************************* + +"The magic of myth and legend has come true in our time. One types the correct +incantation on a keyboard, and a display screen comes to life, showing things +that never were nor could be." + + - Frederick Brooks. "The Mythical Man-Month". + +******************************************************************************* diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..70f2ad545 --- /dev/null +++ b/Makefile @@ -0,0 +1,86 @@ +# Makefile for DAPHNE +# Written by Matt Ownby + +# You need to symlink the set of variables that correspond to that platform +# that you are using. For example, if you are compiling for linux, you would +# do "ln -s Makefile.vars.linux Makefile.vars" +include Makefile.vars + +# send these to all the sub-Makefiles + +# name of the executable and dynamic libraries +EXE = ../singe.bin +LIB_VLDP = ../libvldp2.so +LIB_SINGE = ../libsinge.so + +VLDP_OBJS = +SINGE_OBJS = + +# if we are statically linking VLDP (instead of dynamic) +# NOTE : these libs must be compiled separately beforehand (as if building a shared vldp) +ifeq ($(STATIC_VLDP),1) +VLDP_OBJS = vldp2/vldp/vldp.o vldp2/vldp/vldp_internal.o vldp2/vldp/mpegscan.o \ + vldp2/libmpeg2/cpu_accel.o vldp2/libmpeg2/alloc.o vldp2/libmpeg2/cpu_state.o vldp2/libmpeg2/decode.o \ + vldp2/libmpeg2/header.o vldp2/libmpeg2/motion_comp.o vldp2/libmpeg2/idct.o vldp2/libmpeg2/idct_mmx.o \ + vldp2/libmpeg2/motion_comp_mmx.o vldp2/libmpeg2/slice.o vldp2/libvo/video_out.o vldp2/libvo/video_out_null.o +DEFINE_STATIC_VLDP = -DSTATIC_VLDP +endif + +# if doing the same for SINGE... by RDG2010 +ifeq ($(STATIC_SINGE),1) +SINGE_OBJS = game/singe/lbaselib.o game/singe/ldblib.o \ + game/singe/ldump.o game/singe/lapi.o game/singe/lauxlib.o \ + game/singe/lcode.o game/singe/ldebug.o game/singe/ldo.o \ + game/singe/lfunc.o game/singe/linit.o game/singe/lgc.o \ + game/singe/liolib.o game/singe/llex.o game/singe/lmathlib.o \ + game/singe/lmem.o game/singe/loadlib.o game/singe/lobject.o \ + game/singe/lopcodes.o game/singe/loslib.o game/singe/lparser.o \ + game/singe/lstate.o game/singe/lstring.o game/singe/lstrlib.o game/singe/ltable.o \ + game/singe/ltablib.o game/singe/ltm.o game/singe/lundump.o \ + game/singe/lvm.o game/singe/lzio.o game/singe/lrandom.o game/singe/random.o \ + game/singe/singeproxy.o + +DEFINE_STATIC_SINGE = -DSTATIC_SINGE +endif + +# Platform specific cflags defined in the Makefile.vars file +export CFLAGS = ${PFLAGS} ${DEFINE_STATIC_VLDP} ${DEFINE_STATIC_SINGE} -Wall #-Werror + +OBJS = ldp-out/*.o game/*.o io/*.o manymouse/*.o timer/*.o video/*.o sound/*.o daphne.o ${SINGE_OBJS} ${VLDP_OBJS} + +LOCAL_OBJS = daphne.o + +.SUFFIXES: .cpp + +all: ${LOCAL_OBJS} sub + ${CXX} ${DFLAGS} ${OBJS} -o ${EXE} ${LIBS} + +sub: + cd game/singe && $(MAKE) + cd ldp-out && $(MAKE) + cd game && $(MAKE) + cd io && $(MAKE) + cd manymouse && $(MAKE) + cd timer && $(MAKE) + cd video && $(MAKE) + cd sound && $(MAKE) + +include $(LOCAL_OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +clean_deps: + find . -name "*.d" -exec rm {} \; + +clean: clean_deps + find . -name "*.o" -exec rm {} \; + rm -f ${EXE} + rm -f ${LIB_VLDP} + rm -f ${LIB_SINGE} + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + diff --git a/Makefile.vars.freebsd_x86 b/Makefile.vars.freebsd_x86 new file mode 100644 index 000000000..6d41d409b --- /dev/null +++ b/Makefile.vars.freebsd_x86 @@ -0,0 +1,23 @@ +# This file contains FreeBSD-specific environment variables +# It is included by Makefile if a symlink is created to point to it + +export CXX=g++ +export CC=gcc + +# debugging version +#DFLAGS = -g -DCPU_DEBUG + +# optimized version +DFLAGS = -O3 -march=i686 -DX86_ASM -DGCC_X86_ASM -fomit-frame-pointer \ + -fexpensive-optimizations -funroll-loops \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +# to tell Makefile to assemble the MMX code +export USE_MMX = 1 + +# platform-specific compile flags +PFLAGS = ${DFLAGS} `sdl11-config --cflags` -DUNIX -DFREEBSD \ + -DNATIVE_CPU_X86 -DMMX_RGB2YUV + +# platform-specific lib flags +LIBS = `sdl11-config --libs` -lSDL_mixer -lz -logg -lvorbis -lvorbisfile diff --git a/Makefile.vars.linux_x64 b/Makefile.vars.linux_x64 new file mode 100644 index 000000000..13a631430 --- /dev/null +++ b/Makefile.vars.linux_x64 @@ -0,0 +1,30 @@ +# This file contains linux-specific environment variables +# It is included by Makefile if a symlink is created to point to it + +export CXX=g++ +export CC=gcc + +# debugging version +#DFLAGS = -g -DCPU_DEBUG +#DFLAGS = -ggdb -DCPU_DEBUG -DDEBUG -O0 + +# optimized version +# NOTE : gcc 3.x has a bug that causes compilation to choke on m80.cpp +# If you want to -DGCC_X86_ASM for extra speed, you have to use g++ 3.0 or earlier +DFLAGS = -O3 -fexpensive-optimizations -funroll-loops -fPIC \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +# this is to be exported for MMX assembly optimization +#export USE_MMX = 1 + +# uncomment this to link VLDP statically instead of dynamically +#export STATIC_VLDP = 1 +#export STATIC_SINGE = 1 + +# platform-specific compile flags +# Add -DBUILD_SINGE to enable SINGE +PFLAGS = ${DFLAGS} `sdl-config --cflags` -DUNIX -DLINUX \ + -DUSE_OPENGL -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +# platform-specific lib flags +LIBS = `sdl-config --libs` -ldl -lz -logg -lvorbis -lvorbisfile -lGLEW diff --git a/Makefile.vars.linux_x86 b/Makefile.vars.linux_x86 new file mode 100644 index 000000000..e866ac950 --- /dev/null +++ b/Makefile.vars.linux_x86 @@ -0,0 +1,32 @@ +# This file contains linux-specific environment variables +# It is included by Makefile if a symlink is created to point to it + +export CXX=g++ +export CC=gcc + +# debugging version +#DFLAGS = -pg +#DFLAGS = -ggdb -DCPU_DEBUG -DDEBUG -O0 + +# optimized version +# NOTE : gcc 3.x has a bug that causes compilation to choke on m80.cpp +# If you want to -DGCC_X86_ASM for extra speed, you have to use g++ 3.0 or earlier +DFLAGS = -O3 -march=i686 -fomit-frame-pointer \ + -fexpensive-optimizations -funroll-loops \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +# this is to be exported for MMX assembly optimization +export USE_MMX = 1 + +# uncomment these to link VLDP statically instead of dynamically +#export STATIC_VLDP = 1 +#export STATIC_SINGE = 1 + +# platform-specific compile flags +# Add -DBUILD_SINGE to enable SINGE +PFLAGS = ${DFLAGS} `sdl-config --cflags` -DUNIX -DLINUX -DNATIVE_CPU_X86 \ + -DUSE_MMX -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 -DUSE_OPENGL + + +# platform-specific lib flags +LIBS = `sdl-config --libs` -ldl -lz -logg -lvorbis -lvorbisfile -lGLEW diff --git a/Makefile.vars.mac_osx b/Makefile.vars.mac_osx new file mode 100644 index 000000000..d824c0c9e --- /dev/null +++ b/Makefile.vars.mac_osx @@ -0,0 +1,58 @@ +# This file contains Mac-specific environment variables +# It is included by Makefile if a symlink is created to point to it + +# IF YOU WANT TO MAKE ONLY MINIMAL CHANGES TO THIS MAKEFILE, FOLLOW THESE +# INSTRUCTIONS!!! + +# 1 - Build all required libraries (SDL, SDL_mixer, Ogg, Vorbis) from source. +# When configuring, use "./configure --prefix $HOME/slibs --disable-shared" +# When "make install"ing, it will install everything into your $HOME directory +# inside the slibs directory. That way, you don't need to be root. +# 2 - Add $HOME/slibs/bin to your PATH, by doing: +# "export PATH=$PATH:$HOME/slibs/bin" +# (This allows the sdl-config script to run properly.) +# 3 - Copy this file to Makefile.vars, type make, and you should be good to go. + +# where your library include files are installed +INC_DIR=${HOME}/slibs/include + +# which type of linking you want to do +LIBS=${PRE_TIGER_LIBS} + +# static library path +SLIBS = $(HOME)/slibs/lib + +export CXX=g++ +export CC=gcc + +# debugging version +#DFLAGS = -g -DCPU_DEBUG + +# optimized version +DFLAGS = -O3 -fomit-frame-pointer -funroll-loops + +# not using an intel CPU, so no MMX +export USE_MMX_RGB2YUV = 0 + +# platform-specific compile flags +PFLAGS = ${DFLAGS} `sdl-config --cflags` -DUNIX -DMAC_OSX -DNATIVE_CPU_PPC \ + -DUSE_OPENGL -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 \ + -I ${INC_DIR} + +# Dynamic linking ... +DYNAMIC_LIBS = `sdl-config --libs` -lSDL_mixer -lz -ldl -logg -lvorbis \ + -lvorbisfile -framework Quicktime + +# Static linking (probably better for Mac OSX users) +TIGER_LIBS = -lz \ + `sdl-config --static-libs` \ + $(SLIBS)/libSDL_mixer.a \ + $(SLIBS)/libogg.a $(SLIBS)/libvorbis.a $(SLIBS)/libvorbisfile.a \ + /usr/lib/libSystemStubs.a + +# Old libs, probably work for pre Tiger OSX +PRE_TIGER_LIBS = -lz \ + `sdl-config --static-libs` \ + $(SLIBS)/libSDL_mixer.a \ + $(SLIBS)/libogg.a $(SLIBS)/libvorbis.a $(SLIBS)/libvorbisfile.a \ + $(SLIBS)/libdl.a diff --git a/Makefile.vars.solaris_sparc b/Makefile.vars.solaris_sparc new file mode 100644 index 000000000..abf6027f0 --- /dev/null +++ b/Makefile.vars.solaris_sparc @@ -0,0 +1,28 @@ +# This file contains solaris-specific (SPARC version) environment variables +# It is included by Makefile if a symlink is created to point to it + +# NOTE : This won't fully compile Daphne on Solaris unless you strip out +# all audio-related stuff. If someone has full access to a Solaris box, +# feel free to complete this port. + +export CXX=g++ +export CC=gcc + +# debugging version +#DFLAGS = -g -DCPU_DEBUG + +# optimized version +DFLAGS = -O3 -fomit-frame-pointer -fexpensive-optimizations -funroll-loops + +# we don't really need this, but for completeness I added it ... +export USE_MMX_RGB2YUV = 0 + +# platform-specific compile flags +PFLAGS = ${DFLAGS} `sdl-config --cflags` -DUNIX -DSOLARIS \ + -DNATIVE_CPU_SPARC \ + -DUSE_OPENGL -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +# platform-specific lib flags +# I removed the audio stuff because the stupid solaris machine I'm working on +# doesn't have it and my quota is too small to build it. +LIBS = `sdl-config --libs` -ldl -lz -lsocket -lnsl diff --git a/blend_mmx-masm.obj b/blend_mmx-masm.obj new file mode 100644 index 000000000..b84e31a0e Binary files /dev/null and b/blend_mmx-masm.obj differ diff --git a/buildme.sh b/buildme.sh new file mode 100644 index 000000000..94f6f9539 --- /dev/null +++ b/buildme.sh @@ -0,0 +1,11 @@ +make clean +cd vldp2 +chmod +x configure +./configure +make -f Makefile.linux +cd .. +make +cd .. +echo . +echo done! +echo . diff --git a/convert2unix.sh b/convert2unix.sh new file mode 100644 index 000000000..81b63f219 --- /dev/null +++ b/convert2unix.sh @@ -0,0 +1,68 @@ +dos2unix * +cd game +dos2unix * +cd singe +dos2unix * +cd ../.. +cd io +dos2unix * +cd .. +cd ldp-out +dos2unix * +cd .. +cd lib +dos2unix * +cd .. +cd macosx +dos2unix * +cd .. +cd manymouse +dos2unix * +cd .. +cd sound +dos2unix * +cd .. +cd timer +dos2unix * +cd .. +cd video +dos2unix * +cd .. +cd vldp2 +dos2unix * +cd .. +cd 940 +dos2unix * +cd .. +cd autotools +dos2unix * +cd .. +cd include +dos2unix * +cd .. +cd libmpeg2 +dos2unix * +cd .. +cd libvo +dos2unix * +cd .. +cd src +dos2unix * +cd .. +cd vc++ +dos2unix * +cd .. +cd vldp +dos2unix * +cd .. +cd .. +echo . +echo . +echo . +echo Dos2Unix conversion complete. +echo . +echo . +echo . + + + diff --git a/daphne.cpp b/daphne.cpp new file mode 100644 index 000000000..dc692a853 --- /dev/null +++ b/daphne.cpp @@ -0,0 +1,430 @@ +/* +* daphne.cpp +* +* Copyright (C) 2001 Matt Ownby +* +* This file is part of DAPHNE, a laserdisc arcade game emulator +* +* DAPHNE 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. +* +* DAPHNE 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 +*/ + +// DAPHNE : Dragon's Lair / Space Ace Emulator +// Started by Matt Ownby, many people have contributed since then +// Begun August 3rd, 1999 + +// ORIGINAL GOAL (we've obviously done much more than this now hehe): + +// To emulate the original Dragon's Lair / Space Ace game such that the original ROM's are executed +// properly, the joystick and buttons are emulated, and the Laserdisc Player is properly +// controlled +// In short, so that the original game may be played with the following requirements: +// - Original Dragon's Lair Laserdisc +// - Original Dragon's Lair ROM's (disk files, not the physical ROM's heh) +// - A laserdisc player +// - A common modern computer (i386 Win32, i386 Linux most likely) +// No other original hardware (motherboard, power supply, harness) required! + +#include +#include "io/my_stdio.h" +#include + +using namespace std; + +#ifdef MAC_OSX +#include "mmxdefs.h" +#endif + +#ifndef FREEBSD +#include +#else +#include "/usr/local/include/SDL11/SDL_main.h" +#endif + +#ifdef WIN32 +// win32 doesn't have regular chdir apparently +#define chdir _chdir +#include + +#endif + +#ifdef UNIX +#include // for chdir +#endif + +#include "io/homedir.h" +#include "io/input.h" +#include "daphne.h" +#include "timer/timer.h" +//#include "io/serial.h" +#include "sound/sound.h" +#include "io/conout.h" +#include "io/conin.h" +#include "io/cmdline.h" +#include "io/network.h" +#include "video/video.h" +//#include "video/led.h" +#include "ldp-out/ldp.h" +#include "video/SDL_Console.h" +#include "io/error.h" +//#include "cpu/cpu-debug.h" +//#include "cpu/cpu.h" +#include "game/game.h" +#include "game/singe.h" + +#include "globals.h" +// some global data is stored in this file + +// ------------------------------------------------------------------------------------------------- + +const char *get_daphne_version() +{ + return "1.0.11"; +} + +unsigned char get_filename(char *s, unsigned char n) +// prepares a filename using any wildcards we may have +// returns filename in s +// returns 1 if this filename contains wild characters +// returns 0 if this filename does not contain any wild characters +{ + + unsigned int i = 0; + unsigned char result = 0; + + for (i = 0; i < strlen(s); i++) + { + if (s[i] == '+') + { + result = 1; + s[i] = (char) (n + 0x30); // convert wildcard to number + } + } + + return(result); + +} + +void set_quitflag() +// sets the quit flag +{ + + quitflag = 1; + +} + +unsigned char get_quitflag() +// returns the quit flag +{ + + return(quitflag); + +} + +bool change_dir(const char *cpszNewDir) +{ + int i = chdir(cpszNewDir); + return (i == 0); +} + +// sets current directory based on the full path of the executable +// This solves the problem of someone running daphne without first being in the daphne directory +void set_cur_dir(const char *exe_loc) +{ + int index = strlen(exe_loc) - 1; // start on last character + string path = ""; + + // locate the preceeding / or \ character + while ((index >= 0) && (exe_loc[index] != '/') && (exe_loc[index] != '\\')) + { + index--; + } + + // if we found a leading / or \ character + if (index >= 0) + { + path = exe_loc; + path.erase(index); // erase from here to the end + change_dir(path.c_str()); + } +} + +/////////////////////// MAIN ///////////////////// + +// the main function for both Windows and Linux +int main(int argc, char **argv) +{ + int result_code = 1; // assume an error unless we find otherwise + + set_cur_dir(argv[0]); // set active directory + + reset_logfile(argc, argv); + + // initialize SDL without any subsystems but with the no parachute option so + // 1 - we can initialize either audio or video first + // 2 - we can trace segfaults using a debugger + if (SDL_Init(SDL_INIT_NOPARACHUTE) < 0) + { + printerror("Could not initialize SDL!"); + exit(1); + } + + // parse the command line (which allocates game and ldp) and continue if no errors + // this is important! if game_type or ldp_type fails to allocate g_game and g_ldp, + // then the program will segfault and daphne must NEVER segfault! hehe + if (parse_cmd_line(argc, argv)) + { + // MATT : we have to wait until after the command line is parsed before we do anything with the LEDs in case the + // user does not enable them +// remember_leds(); // memorizes the status of keyboard leds +// change_led(false, false, false); // turns all keyboard leds off + + + // if the display initialized properly + if (load_bmps() && init_display()) + { + if (sound_init()) + { + if (SDL_input_init()) + { + + // if the video was initialized successfully + if (g_game->video_init()) + { + // if the game has some problems, notify the user before the user plays the game + if (g_game->get_issues()) + { + printnowookin(g_game->get_issues()); + } + + SDL_Delay(1000); + // delay for a bit before the LDP is intialized to make sure + // all video is done getting drawn before VLDP is initialized + + // if the laserdisc player was initialized properly + if (g_ldp->pre_init()) + { + if (g_game->pre_init()) // initialize all cpu's + { + printline("Booting ROM ..."); + g_game->start(); // HERE IS THE MAIN LOOP RIGHT HERE + g_game->pre_shutdown(); + + // Send our game/ldp type to server to create stats. + // This was moved to after the game has finished running because it creates a slight delay (like 1 second), + // which throws off the think_delay function in the LDP class. + //net_send_data_to_server(); + + result_code = 0; // daphne will exit without any errors + } + else + { + //exit if returns an error but don't print error message to avoid repetition + } + g_ldp->pre_shutdown(); + } + else + { + printerror("Could not initialize laserdisc player!"); + } + g_game->video_shutdown(); + } // end if game video was initted properly + else + { + printerror("Game-specific video initialization failed!"); + } + + SDL_input_shutdown(); + } + else + { + printerror("Could not initialize input!"); + } + sound_shutdown(); + } + else + { + printerror("Sound initialization failed!"); + } + shutdown_display(); // shut down the display + } // end init display + else + { + printerror("Video initialization failed!"); + } + } // end game class allocated properly + + // if command line was bogus, quit + else + { + char s1[500]; + sprintf(s1,"Bad command line or initialization problem (see daphne_log.txt for details).\n"); + sprintf(s1,"%sTo run SINGE, you must specify which script to run.\n\n",s1); + sprintf(s1,"%sE,g., singe.exe myscript.singe",s1); + printerror(s1); + } + + // if our g_game class was allocated + if (g_game) + { + delete(g_game); + } + + // if g_ldp was allocated, de-allocate it + if (g_ldp) + { + delete(g_ldp); + } + + free_bmps(); // always do this no matter what + +// restore_leds(); // sets keyboard leds back how they were (this is safe even if we have the led's disabled) + + SDL_Quit(); + exit(result_code); + +} + + +// sets the serial port to be used to control LDP +void set_serial_port(unsigned char i) +{ + serial_port = i; +} + + +unsigned char get_serial_port() +{ + return(serial_port); +} + +void set_baud_rate(int i) +{ + baud_rate = i; +} + +int get_baud_rate() +{ + return(baud_rate); +} + +void set_search_offset(int i) +{ + search_offset = i; +} + +int get_search_offset() +{ + return(search_offset); +} + +unsigned char get_frame_modifier() +{ + return(frame_modifier); +} + +void set_frame_modifier(unsigned char value) +{ + frame_modifier = value; +} + +void set_scoreboard(unsigned char value) +{ + realscoreboard = value; +} + +unsigned char get_scoreboard() +{ + return (realscoreboard); +} + +void set_scoreboard_port(unsigned int value) +{ + rsb_port = value; +} + +unsigned int get_scoreboard_port() +{ + return(rsb_port); +} + +void reset_logfile(int argc, char **argv) +{ + int i = 0; + char s[160]; + string str; + + snprintf(s, sizeof(s), "--DAPHNE version %s", get_daphne_version()); + printline(s); + str = "--Command line is: "; + for (i = 0; i < argc; i++) + { + str = str + argv[i] + " "; + } + printline(str.c_str()); + snprintf(s, sizeof(s), "--CPU : %s %d MHz || Mem : %d megs", get_cpu_name(), get_cpu_mhz(), get_sys_mem()); + printline(s); + snprintf(s, sizeof(s), "--OS : %s || Video : %s", get_os_description(), get_video_description()); + printline(s); + outstr("--OpenGL: "); +#ifdef USE_OPENGL + printline("Compiled In"); +#else + printline("Not Compiled In"); +#endif // USE_OPENGL + + outstr("--RGB2YUV Function: "); +#ifdef USE_MMX + printline("MMX"); +#else + printline("C"); +#endif + outstr("--Line Blending Function: "); +#ifdef USE_MMX + printline("MMX"); +#else + printline("C"); +#endif // blend MMX + + outstr("--Audio Mixing Function: "); +#ifdef USE_MMX + printline("MMX"); +#else + printline("C"); +#endif // blend MMX +} + +// added by JFA for -idleexit +void set_idleexit(unsigned int value) +{ + idleexit = value; +} + +unsigned int get_idleexit() +{ + return(idleexit); +} +// end edit + +// added by JFA for -startsilent +void set_startsilent(unsigned char value) +{ + startsilent = value; +} + +unsigned char get_startsilent() +{ + return(startsilent); +} +// end edit diff --git a/daphne.h b/daphne.h new file mode 100644 index 000000000..47a9675cc --- /dev/null +++ b/daphne.h @@ -0,0 +1,69 @@ +/* + * daphne.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// daphne.h + +#ifndef DAPHNE_H +#define DAPHNE_H + +// global definitions ... + +// The current version of DAPHNE will now be returned by this function alone. +// I was having problems with VS6's dependency detector (it wasn't detecting when I was changing +// the version in the .h file). Another advantage to having it here is not having to change +// a header file. +const char *get_daphne_version(); +unsigned char get_filename(char *s, unsigned char n); +void set_quitflag(); +unsigned char get_quitflag(); +bool change_dir(const char *pszNewDir); +void set_cur_dir(const char *exe_loc); +int main(int, char **); +void set_unix_signals(); +void handle_unix_signals(int); +void set_serial_port(unsigned char i); +unsigned char get_serial_port(); +void set_baud_rate(int i); +int get_baud_rate(); +void set_search_offset(int i); +int get_search_offset(); +void set_file_mask(char *mask); +char *get_file_mask(); +unsigned char get_autostart(); +unsigned char get_frame_modifier(); +void set_frame_modifier(unsigned char value); +void set_scoreboard(unsigned char value); +unsigned char get_scoreboard(); +void set_scoreboard_port(unsigned int value); +unsigned int get_scoreboard_port(); +void reset_logfile(int argc, char **argv); +void set_scoreboard_text(char sb_text[]); + +void set_idleexit(unsigned int value); // added by JFA for -idleexit +unsigned int get_idleexit(); // added by JFA for -idleexit +// added by JFA for -startsilent +void set_startsilent(unsigned char value); +unsigned char get_startsilent(); +// end edit + +#endif // DAPHNE_H + diff --git a/daphne_vs2003.sln b/daphne_vs2003.sln new file mode 100644 index 000000000..a5b94fc8c --- /dev/null +++ b/daphne_vs2003.sln @@ -0,0 +1,34 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daphne", "daphne_vs2008.vcproj", "{D6F69305-8810-439B-A6E1-554175951DE3}" + ProjectSection(ProjectDependencies) = postProject + {7F8CEA42-F687-4755-BD58-54A6B25659A7} = {7F8CEA42-F687-4755-BD58-54A6B25659A7} + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0} = {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vldp2", "vldp2_vs2008.vcproj", "{9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "singe", "game\singe\singe_vs2008.vcproj", "{7F8CEA42-F687-4755-BD58-54A6B25659A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6F69305-8810-439B-A6E1-554175951DE3}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Debug|Win32.Build.0 = Debug|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Release|Win32.ActiveCfg = Release|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Release|Win32.Build.0 = Release|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Debug|Win32.Build.0 = Debug|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Release|Win32.ActiveCfg = Release|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Release|Win32.Build.0 = Release|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Debug|Win32.ActiveCfg = Debug|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Debug|Win32.Build.0 = Debug|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Release|Win32.ActiveCfg = Release|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/daphne_vs2003.vcproj b/daphne_vs2003.vcproj new file mode 100644 index 000000000..ab784c757 --- /dev/null +++ b/daphne_vs2003.vcproj @@ -0,0 +1,957 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/daphne_vs2008.vcproj b/daphne_vs2008.vcproj new file mode 100644 index 000000000..9c3356697 --- /dev/null +++ b/daphne_vs2008.vcproj @@ -0,0 +1,645 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/game/Makefile b/game/Makefile new file mode 100644 index 000000000..c3eba2576 --- /dev/null +++ b/game/Makefile @@ -0,0 +1,21 @@ +# sub Makefile for GAME folder + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = game.o singe.o + +.SUFFIXES: .cpp + +all: ${OBJS} + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +clean: + rm ${OBJS} *.d + diff --git a/game/game.cpp b/game/game.cpp new file mode 100644 index 000000000..c0e4e0d8b --- /dev/null +++ b/game/game.cpp @@ -0,0 +1,1201 @@ +/* + * game.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// game.cpp +// by Matt Ownby + +#ifdef WIN32 +#pragma warning (disable:4100) // disable warning about unreferenced parameter + +// this doesn't disable the warnings I want disabled :( +#pragma warning (disable:4244) // disable stupid warnings in MSVC's include files +#pragma warning (disable:4511) +#pragma warning (disable:4512) +#pragma warning (disable:4663) +#endif + +#include // for CRC checking +#include // STL strings, useful to prevent buffer overrun +#include "../daphne.h" // for get_quitflag() +#include "../io/homedir.h" +#include "../io/conout.h" +#include "../io/error.h" +#include "../io/unzip.h" +#include "../io/mpo_fileio.h" +#include "../io/mpo_mem.h" // for better malloc +#include "../io/numstr.h" +#include "../ldp-out/ldp.h" +//#include "../cpu/cpu-debug.h" // for set_cpu_trace +#include "../timer/timer.h" +#include "../io/input.h" +//#include "../io/sram.h" +#include "../io/logger_console.h" // for writing to daphne_log.txt file +#include "../video/video.h" // for get_screen +#include "../video/palette.h" +#include "game.h" + +#ifdef USE_OPENGL +#ifdef MAC_OSX +#include +#else +#include +#endif +#endif + +using namespace std; // for STL string to compile without problems ... + +/////////////////////////////////////////////////////////// + +#ifdef CPU_DEBUG + + +// a generic example of how to setup debug names +struct addr_name game_addr_names[] = +{ + { "Start", 0x0000 }, + { NULL, 0 } +}; +#endif + +// breaks cpu execution into trace mode from whichever point the program is at +// This function is executed by typing "break" at the daphne console +// This can't be part of the class because I can't figure out how to make it work =] +void g_cpu_break (char *s) +{ + + // I put this here simply to get rid of warning messages + if (s) + { + } + +#ifdef CPU_DEBUG +// set_cpu_trace(1); +#else + printline("You have to compile with CPU_DEBUG defined to use the debugger!"); +#endif + +} + + +/////////////////////////////////////////////////////////// + +game::game() : + m_game_paused(false), + m_game_uses_video_overlay(true), // since most games do use video overlay, we'll default this to true + m_overlay_size_is_dynamic(false), // the overlay size is usually static + m_video_overlay_scaled(0), // " " " + m_video_overlay_matrix(0), // + m_video_screen_width(0), // + m_video_screen_height(0), // + m_video_screen_size(0), // + m_bFullScale(false), // full-scale is disabled by default + m_video_overlay_count(2), // default to double buffering because it is conservative + m_active_video_overlay(0), // the first overlay (0) starts out as the active one + m_finished_video_overlay(0), + m_palette_color_count(0), // force game to specify this + m_video_row_offset(0), // most games will want this to be 0 + m_video_col_offset(0), // " " " + m_video_overlay_width(0), // " " " + m_video_overlay_height(0), // " " " + m_video_overlay_needs_update(true), // it always needs to be updated the first time + m_uVideoOverlayVisibleLines(240), // (480/2) for almost all games with overlay + m_bMouseEnabled(false) // mouse is disabled for most games +{ + memset(m_video_overlay, 0, sizeof(m_video_overlay)); // clear this structure so we can easily detect whether we are using video overlay or not + m_uDiscFPKS = 0; + m_disc_fps = 0.0; +// m_disc_ms_per_frame = 0.0; + m_game_type = GAME_UNDEFINED; + m_game_issues = NULL; // assume game has no issues unless we specify some + m_miceDetected = -1; + m_bPauseKeyEnabled = true; +#ifdef CPU_DEBUG + addr_names = game_addr_names; +#endif + + m_num_sounds = 0; + m_cheat_requested = false; // no cheats until specifically requested + m_shortgamename = "game"; // change this to match your game + + m_nvram_begin = NULL; + m_nvram_size = 0; // no nvram by default + m_EEPROM_9536 = false; + + m_rom_list = NULL; + m_crc_disabled = false; + m_prefer_samples = false; // default to emulated sound + m_fastboot = false; + + m_pLogger = ConsoleLogger::GetInstance(); +} + +game::~game() +{ + // cleanup logger + m_pLogger->DeleteInstance(); +} + +// call this instead of init() directly to ensure that some universal stuff gets taken care of +bool game::pre_init() +{ + // compute integer values that we will actually use in practice + // (floating point is too expensive on GP2X so we're eliminating it for recurring computations) + if (m_disc_fps != 0.0) + { + m_uDiscFPKS = (unsigned int) ((m_disc_fps * 1000.0) + 0.5); // frames per kilosecond (same precision, but an int instead of a float) + } +/* + // if we have nvram that we need to load + if (m_nvram_size > 0) + { + + if (m_EEPROM_9536) + { + string filename = m_nvram_filename; + filename += ".gz"; // trail w/ gz since it'll be compressed + sram_load(filename.c_str(), (unsigned char *) m_EEPROM_9536_begin, m_nvram_size); + } + else + { + string filename = m_shortgamename; + filename += ".gz"; // trail w/ gz since it'll be compressed + sram_load(filename.c_str(), m_nvram_begin, m_nvram_size); + } + } + */ + return init(); +} + +// generic game initialization +bool game::init() +{ + bool result = true; + +// cpu_init(); + return result; +} + +// generic game start function. Starts the game playing (usually just begins executing the cpu(s) ) +void game::start() +{ +// cpu_execute(); +} + +// call this instead of shutdown directly +void game::pre_shutdown() +{ + save_sram(); + shutdown(); +} + +// called to ensure sram is saved even if Daphne is terminated improperly +void game::save_sram() +{ + /* + // if we have nvram that we need to save to disk + if (m_nvram_size > 0) + { + if (m_EEPROM_9536) + { + string filename = m_nvram_filename; + filename += ".gz"; // trail w/ gz since it'll be compressed + sram_save(filename.c_str(), (unsigned char *) m_EEPROM_9536_begin, m_nvram_size); + } + else + { + string filename = m_shortgamename; + filename += ".gz"; // trail w/ gz since it'll be compressed + sram_save(filename.c_str(), m_nvram_begin, m_nvram_size); + } + } */ +} + +// generic game shutdown function +void game::shutdown() +{ +// cpu_shutdown(); +} + +// generic game reset function +void game::reset() +{ +// cpu_reset(); +} + +// does anything special needed to send an IRQ +void game::do_irq(unsigned int which_irq) +{ + // get rid of warnings + if (which_irq) + { + } + + printline("WARNING : Unhandled IRQ in generic game class! This is probably not what you want!"); +} + +// does anything special needed to send an NMI +void game::do_nmi() +{ + printline("WARNING : Unhandled NMI in generic game class! This is probably not what you want!"); +} + +// reads a byte from a 16-bit address space +Uint8 game::cpu_mem_read(Uint16 addr) +{ +// return m_cpumem[addr]; + return 0; +} + +// reads a byte from a 32-bit address space +Uint8 game::cpu_mem_read(Uint32 addr) +{ +// return m_cpumem[addr]; + return 0; +} + +// writes a byte to a 16-bit addresss space +void game::cpu_mem_write(Uint16 addr, Uint8 value) +{ +// m_cpumem[addr] = value; +} + +// writes a byte to a 32-bit address space +void game::cpu_mem_write(Uint32 addr, Uint8 value) +{ +// m_cpumem[addr] = value; +} + +// reads a byte from the cpu's port +Uint8 game::port_read(Uint16 port) +{ + char s[81] = { 0 }; + + port &= 0xFF; + sprintf(s, "ERROR: CPU port %x read requested, but this function is unimplemented!", port); + printline(s); + + return(0); +} + +// writes a byte to the cpu's port +void game::port_write(Uint16 port, Uint8 value) +{ + char s[81] = { 0 }; + + port &= 0xFF; + sprintf(s, "ERROR: CPU port %x write requested (value %x) but this function is unimplemented!", port, value); + printline(s); + +} + +// notifies us of the new Program Counter (which most games usually don't care about) +void game::update_pc(Uint32 new_pc) +{ + // I put this here to get rid of warnings + if (new_pc) + { + } +} + +void game::input_enable(Uint8 input, int mouseID) +{ + // get rid of warnings + if (input) + { + } + + printline("Warning: generic input_enable function called, does nothing"); +} + +void game::input_disable(Uint8 input, int mouseID) +{ + // get rid of warnings + if (input) + { + } + + printline("Warning: generic input_disable function called, does nothing"); +} + +// Added by ScottD +void game::OnMouseMotion(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID) +{ + // get rid of warnings + if (x || y || xrel || yrel) + { + } + + printline("Warning: generic mouse_motion function called, does nothing"); +} + +// by default, this is ignored, but it should be used by specific game drivers to stay in sync with the laserdisc +void game::OnVblank() +{ +} + +void game::OnLDV1000LineChange(bool bIsStatus, bool bIsEnabled) +{ + // get rid of warnings + if (bIsStatus || bIsEnabled) + { + } +} + +// does any video initialization we might need +// returns 'true' if the initialization was successful, false if it failed +// It is good to use generic video init and shutdown functions because then we minimize the possibility of errors such as forgetting to call palette_shutdown +bool game::video_init() +{ + bool result = false; + int index = 0; + int w; + int h; + int x; + int y; + float dx; + float dy; + float srcx; + float srcy; + + // set instance variables and local variables to the actual screen (or window) dimension + m_video_screen_width = w = get_screen_blitter()->w; + m_video_screen_height = h = get_screen_blitter()->h; + + // if this particular game uses video overlay (most do) + if (m_game_uses_video_overlay) + { + // safety check, make sure variables are initialized like we expect them to be ... + if ((m_video_overlay_width != 0) && (m_video_overlay_height != 0) && (m_palette_color_count != 0)) + { + result = true; // it's easier to assume true here and find out false, than the reverse + + if (m_bFullScale) + { + m_video_overlay_scaled = + SDL_CreateRGBSurface(SDL_SWSURFACE, + w, + h, 8, 0, 0, 0, 0); // create an 8-bit surface + + // create matrix for scaling the overlay pixmap to the physical surface + // - size of overlay pixmap m_video_overlay_width x m_video_overlay_height + // - size of physical surface is get_screen()->w x get_screen()->h + // - matrix is created as 2dimensional array of "long" values, with size of + // the physical surface + // each entry in the matrix holds an offset into the overlay pixmap array from + // which the pixel is copied into to the corresponding surface pixmap + if ( (m_video_overlay_matrix = (long*) MPO_MALLOC(sizeof(long)*w*h)) == NULL) { + printline("MEM ERROR : malloc failed in video_init!"); + return false; + } /*endif*/ + + dx=(float)m_video_overlay_width/(float)w; // 256/640=0.4 + dy=(float)m_video_overlay_height/(float)h; // 256/480=0.5333 + + srcx=0; + srcy=0; + + for (y=0; yw*dst->h; + + Uint8* srcpixmap=(Uint8*)src->pixels; + Uint8* dstpixmap=(Uint8*)dst->pixels; + + for (i=0; i= instead of >) + if (m_active_video_overlay >= m_video_overlay_count) + { + m_active_video_overlay = 0; + } + video_repaint(); // call game-specific function to get palette refreshed + m_video_overlay_needs_update = false; // game will need to set this value to true next time it becomes needful for us to redraw the screen + + // if we are in non-VLDP mode, then we can blit to the main surface right here, + // otherwise we do nothing because the yuv_callback in ldp-vldp.cpp will take care of it + if (!g_ldp->is_vldp()) + { +#ifdef USE_OPENGL + // if we're not in OpenGL mode + if (!get_use_opengl()) + { +#endif + // If we're not scaling the video + if (!m_bFullScale) + { + vid_blit(m_video_overlay[m_active_video_overlay], 0, 0); + } + else + { + // scale game graphics to the screen dimensions + Scale(m_video_overlay[m_active_video_overlay], + m_video_overlay_scaled, + m_video_overlay_matrix); + vid_blit(m_video_overlay_scaled, 0, 0); + } /*endelse*/ +#ifdef USE_OPENGL + } + // else we're using OpenGL + else + { + vid_blank(); // openGL requires this + + if (!m_bFullScale) + { + SDL_Surface *srf = m_video_overlay[m_active_video_overlay]; + + // blit in the center of the screen + vid_blit(srf, + (m_video_screen_width >> 1) - (srf->w >> 1), + (m_video_screen_height >> 1) - (srf->h >> 1)); + } + + // else if 'fullscale' is enabled + else + { + GLfloat fXScale = (GLfloat) m_video_screen_width / m_video_overlay_width; + GLfloat fYScale = (GLfloat) m_video_screen_height / m_video_overlay_height; + + glPushMatrix(); + glScalef(fXScale, fYScale, 1.0); + + // blit in the center of the screen + SDL_Surface *srf = m_video_overlay[m_active_video_overlay]; + vid_blit(srf, + (m_video_screen_width >> 1) - (srf->w >> 1), + (m_video_screen_height >> 1) - (srf->h >> 1)); + glPopMatrix(); + } + } // end if using opengl + +#endif // USE_OPENGL + vid_flip(); + } // end if this isn't VLDP + + m_finished_video_overlay = m_active_video_overlay; + } +} + +// forces the video overlay to be redrawn to the screen +// This is necessary when the screen has been clobbered (such as when the debug console is down) +void game::video_force_blit() +{ + // if the game uses a video overlay, we have to go through this video_blit routine to update a bunch of variables + if (m_game_uses_video_overlay) + { + m_video_overlay_needs_update = true; + video_blit(); + } + + // otherwise we can just call video repaint directly + else + { + video_repaint(); + } +} + +// sets up the game's palette, this is a game-specific function +void game::palette_calculate() +{ + SDL_Color temp_color = { 0 }; + + // fill color palette with sensible grey defaults + for (int i = 0; i < m_palette_color_count; i++) + { + temp_color.r = (unsigned char) i; + temp_color.g = (unsigned char) i; + temp_color.b = (unsigned char) i; + palette_set_color(i, temp_color); + } +} + +// redraws the current active video overlay buffer (but doesn't blit anything to the screen) +// This is a game-specific function +void game::video_repaint() +{ +} + +void game::set_video_overlay_needs_update(bool value) +{ + m_video_overlay_needs_update = value; +} + +unsigned int game::get_video_overlay_height() +{ + return m_video_overlay_height; +} + +unsigned int game::get_video_overlay_width() +{ + return m_video_overlay_width; +} + +void game::set_prefer_samples(bool value) +{ + m_prefer_samples = value; +} + +void game::set_fastboot(bool value) +{ + m_fastboot = value; +} + +// generic preset function, does nothing +void game::set_preset(int preset) +{ + printline("NOTE: There are no presets defined for the game you have chosen!"); +} + +// generic version function, does nothing +void game::set_version(int version) +{ + printline("NOTE: There are no alternate versions defined for the game you have chosen!"); +} + +// returns false if there was an error trying to set the bank value (ie if the user requested an illegal bank) +bool game::set_bank(unsigned char which_bank, unsigned char value) +{ + bool result = false; // give them an error to help them troubleshoot any problem they are having with their command line + + printline("ERROR: The ability to set bank values is not supported in this game."); + + return result; +} + +// this is called by cmdline.cpp if it gets any cmdline parameters that it doesn't recognize +// returns true if this argument was recognized and processed, +// or false is this argument wasn't recognized (and therefore the command line is bad on a whole) +bool game::handle_cmdline_arg(const char *arg) +{ + return false; // no extra arguments supported by default +} + +// prevents daphne from verifying that the ROM images' CRC values are correct, useful when testing new ROMs +void game::disable_crc() +{ + m_crc_disabled = true; +} + +// routine to load roms +// returns true if there were no errors +bool game::load_roms() +{ + bool result = true; // we must assume result is true in case the game has no roms to load at all + + // if a rom list has been defined, then begin loading roms + if (m_rom_list) + { + int index = 0; + const struct rom_def *rom = &m_rom_list[0]; + string opened_zip_name = ""; // the name of the zip file that we currently have open (if we have one open) + unzFile zip_file = NULL; // pointer to open zip file (NULL if file is closed) + + // go until we get an error or we run out of roms to load + do + { + string path, zip_path = ""; + unsigned int crc = crc32(0L, Z_NULL, 0); + + // if this game explicitely specifies a subdirectory + if (rom->dir) + { + path = rom->dir; + zip_path = path + ".zip"; // append zip extension ... + } + + // otherwise use shortgamename by default + else + { + path = m_shortgamename; + zip_path = path + ".zip"; // append zip extension ... + } + + //Use homedir to locate the compressed rom + zip_path = g_homedir.get_romfile(zip_path); + + // if we have not opened a ZIP file, or if we need to open a new zip file ... + if ((!zip_file) || (zip_path.compare(opened_zip_name) != 0)) + { + // if we need to open a zip file ... + if (!zip_file) + { + zip_file = unzOpen(zip_path.c_str()); + } + + // we need to open a different zip file ... + else + { +// string s = "Closing " + opened_zip_name + " and attempting to open " + zip_path; // just for debugging to make sure this is behaving properly + unzClose(zip_file); + zip_file = unzOpen(zip_path.c_str()); + } + + // if we successfully opened the file ... + if (zip_file) + { + opened_zip_name = zip_path; + } + } + + result = false; + // if we have a zip file open, try to load the ROM from this file first ... + if (zip_file) + { + result = load_compressed_rom(rom->filename, zip_file, rom->buf, rom->size); + } + + // if we were unable to open the rom from a zip file, try to open it as an uncompressed file + if (!result) + { + result = load_rom(rom->filename, path.c_str(), rom->buf, rom->size); + } + + // if file was loaded and was proper length, check CRC + if (result) + { + if (!m_crc_disabled) //skip if user doesn't care + { + crc = crc32(crc, rom->buf, rom->size); + if (rom->crc32 == 0) //skip if crc is set to 0 (game driver doesn't care) + { + crc=0; + } + // if CRC's don't match + if (crc != rom->crc32) + { + char s[160]; + sprintf(s, "ROM CRC checked failed for %s, expected %x, got %x", rom->filename, rom->crc32, crc); + printerror(s); // warn them about this disaster :) + printline(s); + } + } + } + + // if ROM could not be loaded + else + { + string s = "ROM "; + s += rom->filename; + s += " couldn't be found in roms/"; + s += path; + s += "/, or in "; + s += zip_path; + printerror(s.c_str()); + // if this game borrows roms from another game, point that out to the user to help + // them troubleshoot + if (rom->dir) + { + s = "NOTE : this ROM comes from the folder '"; + s += rom->dir; + s += "', which belongs to another game."; + printline(s.c_str()); + s = "You also NEED to get the ROMs for the game that uses the directory '"; + s += rom->dir; + s += "'."; + printline(s.c_str()); + } + } + + index++; + rom = &m_rom_list[index]; // move to next entry + } while (result && rom->filename); + + // if we had a zip file open, close it now + if (zip_file) + { + unzClose(zip_file); + zip_file = NULL; + } + + patch_roms(); + } + + return(result); +} + +// returns true if the file in question exists, and has the proper CRC32 +// 'gamedir' is which rom directory (or .ZIP file) this file is expected to be in +bool game::verify_required_file2(const char *filename, const char *gamedir, Uint32 filecrc32) +{ + Uint8 *readme_test = NULL; + bool passed_test = false; + string path = "/"; + path += gamedir; + path += "/"; + path += filename; + + // TRY UNCOMPRESSED FIRST + string uncompressed_path = g_homedir.get_homedir(); + uncompressed_path.append(path); + + struct mpo_io *io; + + io = mpo_open(uncompressed_path.c_str(), MPO_OPEN_READONLY); + // if file is opened successfully + if (io) + { + + readme_test = new Uint8[io->size]; // allocate file buffer + + if (readme_test) + { + unsigned int crc = crc32(0L, Z_NULL, 0); // zlib crc32 + + // if we are able to read in + mpo_read(readme_test, io->size, NULL, io); + + crc = crc32(crc, readme_test, io->size); + + // if the required file has been unaltered, allow user to continue + + //char s1[255]; + //sprintf(s1,"CRC returns %d",crc); + //printline(s1); + // commenting this for now... --RDG + + //if (crc == filecrc32) + { + passed_test = true; + } + + delete [] readme_test; // free allocated mem + readme_test = NULL; + } + + mpo_close(io); + } + return passed_test; +} + +// loads size # of bytes from filename into buf +// returns true if successful, or false if there was an error +bool game::load_rom(const char *filename, Uint8 *buf, Uint32 size) +{ + struct mpo_io *F; + MPO_BYTES_READ bytes_read = 0; + bool result = false; + string fullpath = g_homedir.get_romfile(filename); // pathname to roms directory + string s = ""; + + outstr("Loading "); + outstr(fullpath.c_str()); + outstr(" ... "); + + F = mpo_open(fullpath.c_str(), MPO_OPEN_READONLY); + + // if file was opened successfully + if (F) + { + mpo_read(buf, size, &bytes_read, F); + + // if we read in the # of bytes we expected to + if (bytes_read == size) + { + result = true; + } + // notify the user what the problem is + else + { + s = "error in rom_load: expected " + numstr::ToStr(size) + " but only read " + numstr::ToStr((unsigned int) bytes_read); + printline(s.c_str()); + } + mpo_close(F); + } + + s = numstr::ToStr((unsigned int) bytes_read) + " bytes read into memory"; + printline(s.c_str()); + + return(result); + +} + +// transition function ... +bool game::load_rom(const char *filename, const char *directory, Uint8 *buf, Uint32 size) +{ + string full_path = directory; + full_path += "/"; + full_path += filename; + return load_rom(full_path.c_str(), buf, size); +} + +// similar to load_rom except this function loads a rom image from a .zip file +// the previously-opened zip file is indicated by 'opened_zip_file' +// true is returned only if the rom was loaded, and it was the expected length +bool game::load_compressed_rom(const char *filename, unzFile opened_zip_file, Uint8 *buf, Uint32 size) +{ + bool result = false; + + outstr("Loading compressed ROM image "); + outstr(filename); + outstr("..."); + + // try to locate requested rom file inside .ZIP archive and proceed if successful + // (the '2' indicates case-insensitivity) + if (unzLocateFile(opened_zip_file, filename, 2) == UNZ_OK) + { + // try to open the current file that we've located + if (unzOpenCurrentFile(opened_zip_file) == UNZ_OK) + { + // read this file + Uint32 bytes_read = (Uint32) unzReadCurrentFile(opened_zip_file, buf, size); + unzCloseCurrentFile(opened_zip_file); + + // if we read what we expected to read ... + if (bytes_read == size) + { + char s[81]; + sprintf(s, "%d bytes read.", bytes_read); + printline(s); + result = true; + } + else + { + printline("unexpected read result!"); + } + } + else + { + printline("could not open current file!"); + } + } + else + { + printline("file not found in .ZIP archive!"); + } + + return result; +} + + +// modify roms (apply cheats, for example) after they are loaded +// this can also be used for any post-rom-loading procedure, such as verifying the existence of readme files for DLE/SAE +void game::patch_roms() +{ +} + +// how many pixels down to shift video overlay +int game::get_video_row_offset() +{ + return m_video_row_offset; +} + +// how many pixels to the right to shift video overlay +int game::get_video_col_offset() +{ + return m_video_col_offset; +} + +unsigned game::get_video_visible_lines() +{ + return m_uVideoOverlayVisibleLines; +} + +SDL_Surface *game::get_video_overlay(int index) +{ + SDL_Surface *result = NULL; + + // safety check + if (index < m_video_overlay_count) + { + result = m_video_overlay[index]; + } + + return result; +} + +// gets surface that's being drawn +SDL_Surface *game::get_active_video_overlay() +{ + return m_video_overlay[m_active_video_overlay]; +} + +// gets last surface to be completely drawn (so it can be displayed without worrying about tearing or flickering) +SDL_Surface *game::get_finished_video_overlay() +{ + return m_video_overlay[m_finished_video_overlay]; +} + +// mainly used by ldp-vldp.cpp so it doesn't print a huge warning message if the overlay's size is dynamic +bool game::is_overlay_size_dynamic() +{ + return m_overlay_size_is_dynamic; +} + +SDL_Surface *game::get_scaled_video_overlay() +{ + return m_video_overlay_scaled; +} + +bool game::IsFullScaleEnabled() +{ + return m_bFullScale; +} + +void game::SetFullScale(bool bEnabled) +{ + m_bFullScale = bEnabled; +} +// end-add + +// enables a cheat (any cheat) in the current game. Unlimited lives is probably the most common. +void game::enable_cheat() +{ + m_cheat_requested = true; +} + +unsigned int game::get_disc_fpks() +{ + return m_uDiscFPKS; +} + +// UPDATE : it's too expensive to use floating point on GP2X, so we are phasing this function out in +// favor of integer operations. +// returns how many ms per frame the disc runs at +//double game::get_disc_ms_per_frame() +//{ +// return m_disc_ms_per_frame; +//} + +Uint8 game::get_game_type() +{ + return m_game_type; +} + +Uint32 game::get_num_sounds() +{ + return m_num_sounds; +} + +const char *game::get_sound_name(int whichone) +{ + return m_sound_name[whichone]; +} + +// returns a string of text that explains the problems with the game OR else null if the game has no problems :) +const char *game::get_issues() +{ + return m_game_issues; +} + +void game::set_issues(const char *issues) +{ + m_game_issues = issues; +} + +void game::toggle_game_pause() +{ + // if the game is already paused ... + if (m_game_paused) + { +// cpu_unpause(); + g_ldp->pre_play(); + m_game_paused = false; + } + + // for now we will only support game pausing if the disc is playing + else if (g_ldp->get_status() == LDP_PLAYING) + { +// char frame[6]; +// Uint16 cur_frame = g_ldp->get_current_frame(); + +// cpu_pause(); + g_ldp->pre_pause(); + + // If seek delay is enabled, we can't search here because the seek delay depends + // upon the cpu running (ie pre_think getting called regularly) + /* + g_ldp->framenum_to_frame(cur_frame, frame); + g_ldp->pre_search(frame, false); // pause the disc on the frame we think we're on (not the frame we're actually on) + + // wait for seek to complete + // (using non-blocking seeking to avoid an extra cpu_pause) + while (g_ldp->get_status() == LDP_SEARCHING) + { + make_delay(1); + } + */ + + m_game_paused = true; + } +} + +const char *game::get_shortgamename() +{ + return m_shortgamename; +} + +#ifdef CPU_DEBUG +// returns either a name for the address or else NULL if no name exists +// Used for debugging to improve readability (to assign function and variable names) +const char *game::get_address_name(unsigned int addr) +{ + + const char *name = NULL; + int i = 0; + + // loop until we've hit the end of our memory names or until we've found a match + for (;;) + { + // if we're at the end of the list + if (addr_names[i].name == NULL) + { + break; + } + else if (addr_names[i].address == addr) + { + name = addr_names[i].name; + break; + } + i++; + } + + return(name); +} + +#endif // CPU_DEBUG + +bool game::get_mouse_enabled() +{ + return m_bMouseEnabled; +} + +void game::set_mouse_enabled(bool thisFlag) +{ + m_bMouseEnabled = thisFlag; +} + +int game::get_mice_detected() +{ + return m_miceDetected; +} + +void game::set_mice_detected(int thisMany) +{ + m_miceDetected = thisMany; +} + +bool game::get_pause_key_flag() +{ + return m_bPauseKeyEnabled; +} + +void game::set_pause_key_flag(bool thisBol) +{ + m_bPauseKeyEnabled = thisBol; +} diff --git a/game/game.h b/game/game.h new file mode 100644 index 000000000..5e1cd5a64 --- /dev/null +++ b/game/game.h @@ -0,0 +1,272 @@ +/* + * game.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// game.h +// by Matt Ownby + +// declares a generic game class structure + +// To add a new game to DAPHNE, make a new class that inherits from the game class +// You must supply a constructor, but you do not need to supply +// any other functions if you don't want to (but your game won't work if you don't hehe) +// See Dragon's Lair (no port functions) and Cliff Hanger (no memory functions) for examples of how you don't +// have to redeclare every single function + +#ifndef GAME_H +#define GAME_H + +// we allow up to triple buffering +#define MAX_VIDEO_OVERLAY_BUFFERS 3 + +// by RDG2010 -- added GAME_SINGE +enum +{ + GAME_UNDEFINED, GAME_LAIR, GAME_LAIR2, GAME_ACE, GAME_ACE91, GAME_CLIFF, GAME_GTG, GAME_SUPERD, GAME_THAYERS, GAME_ASTRON, + GAME_GALAXY, GAME_ESH, GAME_LAIREURO, GAME_BADLANDS, GAME_STARRIDER, GAME_BEGA, GAME_INTERSTELLAR, + GAME_SAE, GAME_MACH3, GAME_UVT, GAME_BADLANDP, GAME_DLE1, GAME_DLE2, GAME_SINGE +}; // game types + +////////////////////////////////// + +#include +#include "../sound/sound.h" +//#include "../cpu/cpu.h" // for CPU_MEM_SIZE +#include "../io/input.h" // for SWITCH definitions, most/all games need them +#include "../io/logger.h" + +typedef void * unzFile; // because including the unzip header file gives some compiler error + +// structure for the cpu debugger... a memory address and its corresponding name +// This is so when debugging, you can have function names instead of numbers (it is easier to read) +struct addr_name +{ + const char *name; // arbitrary name assigned to that address + unsigned int address; // memory address +}; + +void g_cpu_break(char *); + +// each game can define an array of these to faciliate ROM loading +struct rom_def +{ + const char *filename; // name of the rom to be loaded + const char *dir; // name of the subdirectory where rom is (NULL means to use m_shortgamename) + Uint8 *buf; // where in memory to load the rom + unsigned int size; // expected size of the rom + unsigned int crc32; // CRC32 of the ROM +}; + +class game +{ +public: + game(); + virtual ~game(); // to avoid compiler warnings + bool pre_init(); + virtual bool init(); + virtual void start(); + void pre_shutdown(); + + // saves this game's static ram to a compressed file + // (can be called to ensure sram is saved even if Daphne is terminated improperly) + void save_sram(); + + virtual void shutdown(); + virtual void reset(); + virtual void do_irq(unsigned int); // does an IRQ tick + virtual void do_nmi(); // does an NMI tick + virtual Uint8 cpu_mem_read(Uint16 addr); // 16-bit addressing memory read routine + virtual Uint8 cpu_mem_read(Uint32 addr); // 32-bit addressing memory read routine + virtual void cpu_mem_write(Uint16 addr, Uint8 value); // memory write routine + virtual void cpu_mem_write(Uint32 addr, Uint8 value); // 32-bit addressing memory write routine + virtual Uint8 port_read(Uint16 port); // read from port + virtual void port_write(Uint16 port, Uint8 value); // write to a port + virtual void update_pc(Uint32 new_pc); // update the PC + virtual void input_enable(Uint8, int); + virtual void input_disable(Uint8, int); + virtual void OnMouseMotion(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID); // Added by ScottD + virtual void OnVblank(); // this gets called by the ldp class every vblank (since many games use vblank for their interrupt) + + // This optional function will get called 4 times by the ldv1000 driver IF the game driver has first called ldv1000_report_vsync. + // If 'bIsStatus' is false, then this is the command strobe. + virtual void OnLDV1000LineChange(bool bIsStatus, bool bIsEnabled); + + // generic function to initialize video + // m_palette_color_count, m_video_overlay_width, and m_video_overlay_height should all be initialized before this function is called + // This function called palette_initialize + bool video_init(); + + // generic function to shutdown video + // This function calls palette_shutdown + void video_shutdown(); + + // generic function to ensure that the video buffer gets drawn to the screen, will call video_repaint() + // this will not do anything if m_video_overlay_needs_update is false + void video_blit(); + + // forces the screen to always be redrawn (useful if you know the screen has been clobbered, such as when using the drop-down console) + void video_force_blit(); + + // game-specific function that calculates and sets the game's color palette + // This function is called by video_init + virtual void palette_calculate(); + + // game-specific function to force the video buffer to be drawn from scratch (does not blit), + // this function is called by video_blit + virtual void video_repaint(); + + // a way for external functions to indicate that video needs update + // (currently the tms9128nl routines need to use this because they aren't part of the game class) + void set_video_overlay_needs_update(bool value); + + // returns m_video_overlay_width + unsigned int get_video_overlay_width(); + + // returns m_video_overlay_height + unsigned int get_video_overlay_height(); + + virtual void set_prefer_samples(bool); + virtual void set_fastboot(bool); + virtual void set_preset(int); // set up dip switches/rom names, etc with prepared values + virtual void set_version(int); // selects alternate rom revs, or whatever + virtual bool set_bank (unsigned char, unsigned char); // set dip switch values + virtual bool handle_cmdline_arg(const char *arg); // the cmd line will pass on any unknown variables to the game to see if there is a game-specific option to be parsed + void disable_crc(); // skips CRC check on ROM load + virtual bool load_roms(); // load roms into memory + bool verify_required_file2(const char *filename, const char *gamedir, Uint32 filecrc32); // verifies existence of a required file (such as a readme.txt for DLE) + virtual void patch_roms(); // do any modifications (cheats, etc) to roms after they're loaded + int get_video_row_offset(); + int get_video_col_offset(); + unsigned get_video_visible_lines(); // returns m_uVideoOverlayVisibleLines + SDL_Surface *get_video_overlay(int index); // returns pointer to video overlay specified, or NULL if index is out of range + SDL_Surface *get_active_video_overlay(); // returns the current active video overlay (that is currently being drawn) + SDL_Surface *get_finished_video_overlay(); // returns the last complete video overlay (that isn't currently being drawn) + bool is_overlay_size_dynamic(); // returns m_overlay_size_is_dynamic + SDL_Surface *get_scaled_video_overlay(); // returns pointer to the video overlay which is used for scaling + bool IsFullScaleEnabled(); // returns m_bFullScale + void SetFullScale(bool bEnabled); // sets m_bFullScale + + void enable_cheat(); + unsigned int get_disc_fpks(); // return # of frames per kilosecond (to avoid using gp2x-unfriendly floats) +// double get_disc_fps(); // return FPS of the laserdisc +// double get_disc_ms_per_frame(); + Uint8 get_game_type(); + Uint32 get_num_sounds(); + const char *get_sound_name(int); + const char *get_issues(); // does the game have any performance issues the user should know about? + void set_issues(const char *); + void toggle_game_pause(); // toggles whether the game is paused or not + const char *get_shortgamename(); // returns short game name +#ifdef CPU_DEBUG + const char *get_address_name(unsigned int addr); // get a potential name for a memory address (very useful for debugging) +#endif + + // returns m_bMouseEnabled + bool get_mouse_enabled(); + void set_mouse_enabled(bool); // RDG + int get_mice_detected(); + void set_mice_detected(int); + bool get_pause_key_flag(); + void set_pause_key_flag(bool); + +protected: + bool m_game_paused; // whether the game is paused or not + const char *m_shortgamename; // a one-word name for this game (ie "lair" "ace" "dle", etc) + const struct rom_def *m_rom_list; // pointer to a null-terminated array of roms to be loaded +// Uint8 m_cpumem[CPU_MEM_SIZE]; // generic buffer that most 16-bit addressing cpu's can use + unsigned int m_uDiscFPKS; // frames per kilosecond of the game's laserdisc (to avoid using gp2x-unfriendly float) + double m_disc_fps; // frames per second of the game's laserdisc; (only used initially since it is expensive on gp2x) +// double m_disc_ms_per_frame; // how many ms per frame of the game's laserdisc (same value as fps, just re-arranged) + Uint8 m_game_type; // which game it is + Uint32 m_num_sounds; // how many samples the game has to load + const char *m_sound_name[MAX_NUM_SOUNDS]; // names for each sound file + const char *m_game_issues; // description of any issues the game has (NULL if no issues) + bool m_cheat_requested; // whether user has requested any cheats to be enabled + bool m_crc_disabled; // set to true to disable CRC check on ROM load + bool m_prefer_samples; + bool m_fastboot; + + const char *m_nvram_filename; // filename for nvram (only for DL2/SA91 for now) + Uint8 *m_nvram_begin; // points to where our nvram begins + Uint16 *m_EEPROM_9536_begin; // points to the 9536 EEPROM for DL2/SA91 + bool m_EEPROM_9536; + Uint32 m_nvram_size; // how big the nvram area is (if this is 0, nvram is not loaded/saved) + + // variables relating to graphics generated by the game ROM (ie non-laserdisc video) + bool m_game_uses_video_overlay; // whether the game uses video overlay (most games do) + bool m_overlay_size_is_dynamic; // whether the game dynamically re-allocates its overlay to match the size of the mpeg (thayer's quest, seektest both do this) + SDL_Surface *m_video_overlay[MAX_VIDEO_OVERLAY_BUFFERS]; // graphic buffers to hold ROM-generated video + + // fullscale variables + SDL_Surface *m_video_overlay_scaled; // temporary graphic buffer which receives the scaled game graphics from m_video_overlay[...] + long* m_video_overlay_matrix; // the precalculated matrix used for scaling the game graphics to the target screen dimension + Uint32 m_video_screen_width; // the width of the target screen (according to the graphic mode set by Daphne) + Uint32 m_video_screen_height; // the height of the target screen (according to the graphic mode set by Daphne) + Uint32 m_video_screen_size; // m_video_screen_width x m_video_screen_height, just to speedup things a bit + bool m_bFullScale; // whether fullscale is enabled or not + // end fullscale variables + + int m_video_overlay_count; // how many video overlay buffers we have + int m_active_video_overlay; // index of the active SDL_Surface that serves as our video overlay (the one we make changes to) + int m_finished_video_overlay; // index of the last SDL_Surface to be completely drawn (ie finished) + int m_palette_color_count; // the # of colors to be allocated for the color palette, not to exceed 256 (surfaces are only 8-bit) + + // How many rows down to shift video (can be negative if you want to shift up) + // IMPORTANT: The rows are relative to the ROM-generated video overlay! + // So if the video window is 480 pixels high and the ROM overlay has 240 visible rows, + // then shifting 1 row would shift 2 pixels. + int m_video_row_offset; + + int m_video_col_offset; // how many pixels right to shift video (can be negative if you want to shift left) + Uint32 m_video_overlay_width; // the width of the ROM-generated video (should be defined in game constructor) + Uint32 m_video_overlay_height; // the height of the ROM-generated video (should be defined in game constructor) + bool m_video_overlay_needs_update; // whether the video overlay has changed + // Sometimes the game ROM will write the same values to the video overlay buffer, and it is cheaper not to redraw + // the video overlay buffer if nothing is being changed. Thus, m_video_overlay_needs_update's purpose. + // The game is responsible for setting this value to true when it knows that the video_repaint needs to be called + + // how many lines are visible in the video overlay + // (usually 240 for almost all games, that is, half the resolution of the laserdisc player) + // Firefox is the only current exception. + unsigned int m_uVideoOverlayVisibleLines; + + // if the game uses the mouse, this should be set to true IN THE GAME'S CONSTRUCTOR + bool m_bMouseEnabled; // rdg + int m_miceDetected; + bool m_bPauseKeyEnabled; + + // logger interface (for writing to daphne_log.txt file) + ILogger *m_pLogger; + +#ifdef CPU_DEBUG + struct addr_name *addr_names; +#endif + +private: + bool load_rom(const char *filename, Uint8 *buf, Uint32 size); + bool load_rom(const char *filename, const char *directory, Uint8 *bif, Uint32 size); + bool load_compressed_rom(const char *filename, unzFile opened_zip_file, Uint8 *buf, Uint32 size); + +}; + +extern game *g_game; // our global game class. Instead of having every .cpp file define this, we put it here. + +#endif diff --git a/game/singe.cpp b/game/singe.cpp new file mode 100644 index 000000000..8851d2675 --- /dev/null +++ b/game/singe.cpp @@ -0,0 +1,731 @@ +/* +* singe.cpp +* +* Copyright (C) 2006 Scott C. Duensing +* +* This file is part of DAPHNE, a laserdisc arcade game emulator +* +* DAPHNE 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. +* +* DAPHNE 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 +*/ + +/* +* This is SINGE - the Somewhat Interactive Nostalgic Game Engine! +*/ + +#include +#include "singe.h" +#include "singe/singe_interface.h" + + +// Win32 doesn't use strcasecmp, it uses stricmp (lame) +#ifdef WIN32 +#define strcasecmp stricmp +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// For intercepting the VLDP MPEG data + +extern struct vldp_in_info g_local_info; +extern const struct vldp_out_info *g_vldp_info; +extern SDL_Surface *g_screen_blitter; +//extern SDL_Surface *g_screen; +//extern SDL_Surface *get_screen_blitter(); +extern void vid_blank(); +extern void vid_flip(); +extern void vid_blit(SDL_Surface *srf, int x, int y); + +//////////////////////////////////////////////////////////////////////////////// + +typedef const struct singe_out_info *(*singeinitproc)(const struct singe_in_info *in_info); + +// pointer to all info SINGE PROXY gives to us +const struct singe_out_info *g_pSingeOut = NULL; + +// info that we provide to the SINGE PROXY DLL +struct singe_in_info g_SingeIn; + +//////////////////////////////////////////////////////////////////////////////// + +// by RDG2010 +const int singe::i_full_keybd_defs[] = {SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_PAUSE, + SDLK_SPACE, SDLK_QUOTE, SDLK_COMMA, SDLK_SEMICOLON, + SDLK_EQUALS, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, + SDLK_BACKSLASH, SDLK_SLASH, SDLK_DELETE, SDLK_PERIOD }; + +#define KEYBD_ARRAY_SIZE 15 + +singe::singe() +{ + m_strGameScript = ""; + m_shortgamename = "singe"; + m_strScriptPath = ""; + m_strName = "[Undefined scripted game]"; + m_video_overlay_width = 320; // sensible default + m_video_overlay_height = 240; // " " " + m_palette_color_count = 256; + m_overlay_size_is_dynamic = true; // this 'game' does reallocate the size of its overlay + m_bMouseEnabled = true; + m_dll_instance = NULL; + // by RDG2010 + m_game_type = GAME_SINGE; + i_keyboard_mode = KEYBD_NORMAL; + +} + +bool singe::init() +{ + bool bSuccess = false; + singeinitproc pSingeInit; // pointer to the init proc ... + +#ifndef STATIC_SINGE // if we're loading SINGE dynamically +#ifndef DEBUG + m_dll_instance = M_LOAD_LIB(singe); // load SINGE.DLL +#else + m_dll_instance = M_LOAD_LIB(singe_dbg); // load SINGED.DLL (debug version) +#endif + + // If the handle is valid, try to get the function address. + if (m_dll_instance) + { + pSingeInit = (singeinitproc) M_GET_SYM(m_dll_instance, "singeproxy_init"); + + // if init function was found + if (pSingeInit) + { + bSuccess = true; + } + else + { + printerror("SINGE LOAD ERROR : singeproxy_init could not be loaded"); + } + } + else + { + printerror("ERROR: could not open the SINGE dynamic library (file not found maybe?)"); + } + +#else // else if we're loading SINGE statically + pSingeInit = singeproxy_init; + bSuccess = true; +#endif // STATIC_SINGE + + // if pSingeInit is valid ... + if (bSuccess) + { + // DLL basics can be confusing so I am writing this down to remind myself in the future. + // These g_SingeIn declarations wires functions located on the daphne side + // so they can be called on the DLL side of singe. + // An alias is used by the DLL source code to refer to them. + // + // Looking below: + // The name on the right of the declaration is the actual daphne function or variable. + // The name on the left of the declaration is the alias used by the DLL. + + // Before you can add a g_SingeIn declaration here, you must have + // the function properly declared in singe.h + + g_SingeIn.uVersion = SINGE_INTERFACE_API_VERSION; + g_SingeIn.printline = printline; + g_SingeIn.set_quitflag = set_quitflag; + g_SingeIn.disable_audio1 = disable_audio1; + g_SingeIn.disable_audio2 = disable_audio2; + g_SingeIn.enable_audio1 = enable_audio1; + g_SingeIn.enable_audio2 = enable_audio2; + g_SingeIn.framenum_to_frame = framenum_to_frame; + g_SingeIn.get_current_frame = get_current_frame; + g_SingeIn.pre_change_speed = pre_change_speed; + g_SingeIn.pre_pause = pre_pause; + g_SingeIn.pre_play = pre_play; + g_SingeIn.pre_search = pre_search; + g_SingeIn.pre_skip_backward = pre_skip_backward; + g_SingeIn.pre_skip_forward = pre_skip_forward; + g_SingeIn.pre_step_backward = pre_step_backward; + g_SingeIn.pre_step_forward = pre_step_forward; + g_SingeIn.pre_stop = pre_stop; + g_SingeIn.set_search_blanking = set_search_blanking; + g_SingeIn.set_skip_blanking = set_skip_blanking; + g_SingeIn.g_local_info = &g_local_info; + g_SingeIn.g_vldp_info = g_vldp_info; + g_SingeIn.get_video_height = get_video_height; + g_SingeIn.get_video_width = get_video_width; + g_SingeIn.draw_string = draw_string; + g_SingeIn.samples_play_sample = samples_play_sample; + g_SingeIn.set_last_error = set_last_error; + + // by RDG2010 + g_SingeIn.get_vldp_status = get_vldp_status; + g_SingeIn.get_singe_version = get_singe_version; + g_SingeIn.set_ldp_verbose = set_ldp_verbose; + g_SingeIn.samples_set_state = samples_set_state; + g_SingeIn.samples_is_sample_playing = samples_is_sample_playing; + g_SingeIn.samples_end_early = samples_end_early; + g_SingeIn.set_soundchip_nonvldp_volume = set_soundchip_nonvldp_volume; + g_SingeIn.get_soundchip_nonvldp_volume = get_soundchip_nonvldp_volume; + g_SingeIn.samples_flush_queue = samples_flush_queue; + //g_SingeIn.g_screen_blitter = g_screen_blitter; + + // Special cases where it is needed to access or change values + // inside the singe class require special wrapper functions. + // These functions allow the DLL side of SINGE call the + // functions set_keyboard_mode and get_keyboard_mode inside this very class. + // Take a look a singe.h for the full declarations of these functions: + + g_SingeIn.dll_side_set_keyboard_mode = daphne_side_set_keyboard_mode; + g_SingeIn.dll_side_get_keyboard_mode = daphne_side_get_keyboard_mode; + g_SingeIn.dll_side_get_script_path = daphne_side_get_script_path; + g_SingeIn.dll_side_set_caption = daphne_side_set_caption; + g_SingeIn.dll_side_mouse_enable = daphne_side_mouse_enable; + g_SingeIn.dll_side_mouse_disable = daphne_side_mouse_disable; + g_SingeIn.dll_side_mouse_get_how_many = daphne_side_mouse_get_how_many; + g_SingeIn.dll_side_set_mouse_mode = daphne_side_set_mouse_mode; + g_SingeIn.dll_side_pause_enable = daphne_side_pause_enable; + g_SingeIn.dll_side_pause_disable = daphne_side_pause_disable; + + /* + Why a wrapper? + + A function on the DLL side can't change or refer to a value + inside the singe class because the pointer types don't match. + Go around this by creating a special pointer to this class + and also declaring a function between the Singe method inside + the class and the DLL function that needs access to it. + + Pointer declaration below... + */ + + g_SingeIn.pSingeInstance = this; + + // establish link betwixt singe proxy and us + g_pSingeOut = pSingeInit(&g_SingeIn); + +#ifdef WIN32 + // do something here.... + +#else + // version check + if (g_pSingeOut->uVersion != SINGE_INTERFACE_API_VERSION) + { + printline("Singe API version mismatch! Something needs to be recompiled..."); + bSuccess = false; + } +#endif + + } + + // if we're not using VLDP, then singe will segfault, so abort ... + if (g_vldp_info == NULL) + { + printerror("You must use VLDP when using Singe."); + bSuccess = false; + } + if (!bSuccess) + { +#ifndef STATIC_SINGE + M_FREE_LIB(m_dll_instance); +#endif // STATIC_SINGE + + + + } + + return bSuccess; +} + +void singe::start() +{ + int intReturn = 0; + char s1[100]; + sprintf(s1,"Starting Singe version %.2f",get_singe_version()); + printline(s1); + // comment these two lines for official releases -- rdg + sprintf(s1,"Singe v%.2f BETA", get_singe_version()); + SDL_WM_SetCaption(s1, "Singe"); + // BETA + + g_pSingeOut->sep_set_surface(m_video_overlay_width, m_video_overlay_height); + g_pSingeOut->sep_set_static_pointers(&m_disc_fps, &m_uDiscFPKS); + g_pSingeOut->sep_startup(m_strGameScript.c_str()); + + // if singe didn't get an error during startup... + if (!get_quitflag()) + { + while (!get_quitflag()) + { + g_pSingeOut->sep_call_lua("onOverlayUpdate", ">i", &intReturn); + if (intReturn == 1) + { + m_video_overlay_needs_update = true; + } + video_blit(); + SDL_check_input(); + samples_do_queued_callbacks(); // hack to ensure sound callbacks are called at a time when lua can accept them without crashing + g_ldp->think_delay(10); // don't hog cpu, and advance timer + } + + g_pSingeOut->sep_call_lua("onShutdown", ""); + } // end if there was no startup error + + // always call sep_shutdown just to make sure everything gets cleaned up + g_pSingeOut->sep_shutdown(); +} + +void singe::shutdown() +{ +#ifndef STATIC_SINGE + // if a DLL is loaded, then free it + if (m_dll_instance) + { + M_FREE_LIB(m_dll_instance); + m_dll_instance = NULL; + } + // else do nothing ... +#endif // STATIC_SINGE +} + +void singe::input_enable(Uint8 input, int mouseID) +{ + if (g_pSingeOut) // by RDG2010 + g_pSingeOut->sep_call_lua("onInputPressed", "ii", input, mouseID); +} + +void singe::input_disable(Uint8 input, int mouseID) +{ + if (g_pSingeOut) // by RDG2010 + g_pSingeOut->sep_call_lua("onInputReleased", "ii", input, mouseID); +} + +void singe::OnMouseMotion(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID) +{ + if (g_pSingeOut) + { + g_pSingeOut->sep_do_mouse_move(x, y, xrel, yrel, mouseID); + } +} + +// game-specific command line arguments handled here +bool singe::handle_cmdline_arg(const char *s) +{ + + bool bResult = false; + static bool scriptLoaded = false; + + if (mpo_file_exists(s)) + { + if (!scriptLoaded) + { + bResult = scriptLoaded = true; + m_strGameScript = s; + } + else + { + printline("Only one game script may be loaded at a time!"); + } + } + else + { + string strErrMsg = "Script "; + strErrMsg += s; + strErrMsg += " does not exist."; + printline(strErrMsg.c_str()); + } + + /* + char s[81] = { 0 }; + + if (strcasecmp(arg, "-script") == 0) + { + get_next_word(s, sizeof(s)); + + if (mpo_file_exists(s)) + { + if (!scriptLoaded) + { + bResult = scriptLoaded = true; + m_strGameScript = s; + } + else + { + printline("Only one game script may be loaded at a time!"); + bResult = false; + } + } + else + { + string strErrMsg = "Script "; + strErrMsg += s; + strErrMsg += " does not exist."; + printline(strErrMsg.c_str()); + } + + } + */ + + return bResult; + +} + + +void singe::palette_calculate() +{ + SDL_Color temp_color; + + temp_color.unused = 0; // Eliminates a warning. + + // go through all colors and compute the palette + // (start at 2 because 0 and 1 are a special case) + for (unsigned int i = 2; i < 256; i++) + { + temp_color.r = i & 0xE0; // Top 3 bits for red + temp_color.g = (i << 3) & 0xC0; // Middle 2 bits for green + temp_color.b = (i << 5) & 0xE0; // Bottom 3 bits for blue + palette_set_color(i, temp_color); + } + + // special case: 00 is reserved for transparency, so 01 becomes fully black + temp_color.r = temp_color.g = temp_color.b = 0; + palette_set_color(1, temp_color); + + // safety : 00 should never be visible so we'll make it a bright color to help us + // catch errors + temp_color.r = temp_color.g = temp_color.b = 0xFF; + palette_set_color(0, temp_color); +} + + +// redraws video +void singe::video_repaint() +{ + Uint32 cur_w = g_ldp->get_discvideo_width() >> 1; // width overlay should be + Uint32 cur_h = g_ldp->get_discvideo_height() >> 1; // height overlay should be + + // if the width or height of the mpeg video has changed since we last were here (ie, opening a new mpeg) + // then reallocate the video overlay buffer + if ((cur_w != m_video_overlay_width) || (cur_h != m_video_overlay_height)) + { + if (g_ldp->lock_overlay(1000)) + { + m_video_overlay_width = cur_w; + m_video_overlay_height = cur_h; + + g_pSingeOut->sep_set_surface(m_video_overlay_width, m_video_overlay_height); + + video_shutdown(); + if (!video_init()) + { + printline("Fatal Error, trying to re-create the surface failed!"); + set_quitflag(); + } + g_ldp->unlock_overlay(1000); // unblock game video overlay + } + else + { + g_pSingeOut->sep_print("Timed out trying to get a lock on the yuv overlay"); + return; + } + } // end if dimensions are incorrect + + g_pSingeOut->sep_do_blit(m_video_overlay[m_active_video_overlay]); + + //g_pSingeOut->sep_do_blit(g_screen_blitter); + + //vid_blank(); + //vid_blit(g_screen_blitter, 0, 0); + //SDL_BlitSurface(g_screen_blitter, NULL, g_screen, NULL); + //vid_flip(); + +} + +void singe::set_last_error(const char *cpszErrMsg) +{ + // TODO : figure out reliable way to call printerror (maybe there isn't one?) + printline(cpszErrMsg); +} + +// by RDG2010 +void singe::set_keyboard_mode(int thisVal) +{ + if (thisVal != KEYBD_NORMAL && thisVal != KEYBD_FULL) + { + //printline("Singe tried to se an invalid keyboard mode. Defaulting to normal."); + i_keyboard_mode = KEYBD_NORMAL; + } + else + i_keyboard_mode = thisVal; + +} + +int singe::get_keyboard_mode() +{ + return i_keyboard_mode; +} + +double singe::get_singe_version() +{ + double thisVersion = SINGE_VERSION; + return thisVersion; +} + +// Have SINGE deal directly with SDL input +// This handles when a key is pressed down +void singe::process_keydown(SDLKey key, int keydefs[][2]) +{ + /* Normal Daphne use has the program look for a set of default keys. + * These are read from daphne.ini (or if daphne.ini is absent, then set + * a default configuration). The rest of the keyboard is ignored. + * This is the default mode that works for most gamees. + * + * The alternate mode is to scan for all keys. + * In this mode daphne.ini settings are ignored. + * The ESCAPE key is hardwired to quit. + * + * i_keyboard_mode stores the scanning mode. + * It is set by default to KEYBD_NORMAL. + * A singe script can change this to KEYBD_FULL + * typing "keyboardSetMode" command in the lua + * scripting side. + * + * RDG2010 + * + * */ + + if (i_keyboard_mode == KEYBD_NORMAL) // Using normal keyboard mappings + { // traverse the keydef array for mapped keys. + for (Uint8 move = 0; move < SWITCH_COUNT; move++) + { + if ((key == keydefs[move][0]) || (key == keydefs[move][1])) + { + if (move != SWITCH_PAUSE) input_enable(move, NOMOUSE); + } + } + + } else { // Using full keyboard access.... + + if (key >= SDLK_a && key <= SDLK_z) + input_enable(key, NOMOUSE); + // check to see if key is a number on the top row of the keyboard (not keypad) + else if (key >= SDLK_MINUS && key <= SDLK_9) + input_enable(key, NOMOUSE); + // numeric keypad keys + else if (key >= SDLK_KP0 && key <= SDLK_KP_EQUALS) + input_enable(key, NOMOUSE); + // arrow keys and insert, delete, home, end, pgup, pgdown + else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) + input_enable(key, NOMOUSE); + // function keys + else if (key >= SDLK_F1 && key <= SDLK_F15) + input_enable(key, NOMOUSE); + // Key state modifier keys (left and right ctrls, alts) + else if (key >= SDLK_NUMLOCK && key <= SDLK_LMETA) + input_enable(key, NOMOUSE); + // International keys + else if (key >= SDLK_WORLD_0 && key <= SDLK_WORLD_95) + input_enable(key, NOMOUSE); + else + { + + /* + * SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_PAUSE, + * SDLK_SPACE, SDLK_QUOTE, SDLK_COMMA, SDLK_SEMICOLON, + * SDLK_EQUALS, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, + * SDLK_BACKSLASH, SDLK_SLASH, SDLK_DELETE, SDLK_PERIOD }; + */ + + for (int k=0;kget_pause_key_flag()) // rdg + { + g_game->toggle_game_pause(); + //input_disable(SWITCH_PAUSE, NOMOUSE); // -1 is for no mouse. + + } + input_disable(SWITCH_PAUSE, NOMOUSE); // -1 is for no mouse. + + } else if (key == keydefs[SWITCH_QUIT][0] || key == keydefs[SWITCH_QUIT][1]) { + + set_quitflag(); + + } else if (key == keydefs[SWITCH_SCREENSHOT][0]) { + + printline("Screenshot requested!"); + g_ldp->request_screenshot(); + + } else { + + for (Uint8 move = 0; move < SWITCH_COUNT; move++) + { + if ((key == keydefs[move][0]) || (key == keydefs[move][1])) + { + if (move != SWITCH_PAUSE) input_disable(move, NOMOUSE); + } + + } // end for + + } // endif + + } else { // Using full keyboard access.... + + // Hardwire ESCAPE key to quit + if (key == SDLK_ESCAPE) + set_quitflag(); + // letter keys + else if (key >= SDLK_a && key <= SDLK_z) + input_disable(key, NOMOUSE); + // check to see if key is a number on the top row of the keyboard (not keypad) + else if (key >= SDLK_MINUS && key <= SDLK_9) + input_disable(key, NOMOUSE); + // numeric keypad keys + else if (key >= SDLK_KP0 && key <= SDLK_KP_EQUALS) + input_disable(key, NOMOUSE); + // arrow keys and insert, delete, home, end, pgup, pgdown + else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) + input_disable(key, NOMOUSE); + // function keys + else if (key >= SDLK_F1 && key <= SDLK_F15) + input_disable(key, NOMOUSE); + // Key state modifier keys (left and right ctrls, alts) + else if (key >= SDLK_NUMLOCK && key <= SDLK_LMETA) + input_disable(key, NOMOUSE); + // International keys + else if (key >= SDLK_WORLD_0 && key <= SDLK_WORLD_95) + input_disable(key, NOMOUSE); + else + { + /* + * SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_PAUSE, + * SDLK_SPACE, SDLK_QUOTE, SDLK_COMMA, SDLK_SEMICOLON, + * SDLK_EQUALS, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, + * SDLK_BACKSLASH, SDLK_SLASH, SDLK_DELETE, SDLK_PERIOD }; + */ + + for (int k=0;k + +using namespace std; + +// by rdg2010 +// INCREASE THIS NUMBER EVERY TIME YOU CHANGE SOMETHING IN SINGE!!! +#define SINGE_VERSION 1.18 +#define NOMOUSE -1 +enum { KEYBD_NORMAL, KEYBD_FULL }; + +//////////////////////////////////////////////////////////////////////////////// + +class singe : public game +{ +public: + singe(); + bool init(); + void start(); + void shutdown(); + void input_enable(Uint8, int); + void input_disable(Uint8, int); + void OnMouseMotion(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID); + bool handle_cmdline_arg(const char *arg); + void palette_calculate(); + void video_repaint(); + + // g_ldp function wrappers (to make function pointers out of them) + static void enable_audio1() { g_ldp->enable_audio1(); } + static void enable_audio2() { g_ldp->enable_audio2(); } + static void disable_audio1() { g_ldp->disable_audio1(); } + static void disable_audio2() { g_ldp->disable_audio2(); } + static void request_screenshot() { g_ldp->request_screenshot(); } + static void set_search_blanking(bool enabled) { g_ldp->set_search_blanking(enabled); } + static void set_skip_blanking(bool enabled) { g_ldp->set_skip_blanking(enabled); } + static bool pre_change_speed(unsigned int uNumerator, unsigned int uDenominator) + { + return g_ldp->pre_change_speed(uNumerator, uDenominator); + } + static unsigned int get_current_frame() { return g_ldp->get_current_frame(); } + static void pre_play() { g_ldp->pre_play(); } + static void pre_pause() { g_ldp->pre_pause(); } + static void pre_stop() { g_ldp->pre_stop(); } + static bool pre_search(const char *cpszFrame, bool block_until_search_finished) + { + return g_ldp->pre_search(cpszFrame, block_until_search_finished); + } + static void framenum_to_frame(Uint32 u16Frame, char *pszFrame) { g_ldp->framenum_to_frame(u16Frame, pszFrame); } + static bool pre_skip_forward(Uint32 u16Frames) { return g_ldp->pre_skip_forward(u16Frames); } + static bool pre_skip_backward(Uint32 u16Frames) { return g_ldp->pre_skip_backward(u16Frames); } + static void pre_step_forward() { g_ldp->pre_step_forward(); } + static void pre_step_backward() { g_ldp->pre_step_backward(); } + + // by RDG2010 + // Sometimes it's useful to know the status of the vldp. + // Lets give Singe the ability to query for this. + static int get_vldp_status() { return g_ldp->get_status(); } + static double get_singe_version(); // Returns version of the Singe engine + // Controls VLDP message displays on daphne_log.txt + static void set_ldp_verbose(bool thisBol) { g_ldp->setVerbose(thisBol); } + + // These wrapper functions make the functions set_keyboard_mode and get_keyboard_mode + // available for the DLL/so library side of SINGE. + // Take a look at the comments in singe::init on singe.cpp for more info. + // + static void daphne_side_set_keyboard_mode(void *pInstance, int thisVal) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->set_keyboard_mode(thisVal); + } + + static int daphne_side_get_keyboard_mode(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + return pSingeInstance->get_keyboard_mode(); + } + + static void daphne_side_get_script_path(void *pInstance, char *thisVal) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->get_script_path(thisVal); + } + + static void daphne_side_mouse_enable(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->m_bMouseEnabled = true; + } + static void daphne_side_mouse_disable(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->m_bMouseEnabled = false; + } + static int daphne_side_mouse_get_how_many(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + return pSingeInstance->get_mice_detected(); + } + static bool daphne_side_set_mouse_mode(int thisVal) + { + //singe *pSingeInstance = (singe *) pInstance; + return set_mouse_mode(thisVal); + } + + static void daphne_side_pause_enable(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->m_bPauseKeyEnabled = true; + } + static void daphne_side_pause_disable(void *pInstance) + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->m_bPauseKeyEnabled = false; + + } + + void set_keyboard_mode(int); // Sets value of private member i_keyboard_mode + int get_keyboard_mode(); // Retrieves the value of i_keyboard_mode + + // By RDG2010 + // Copying expanded keyboard handling technique from Thayer's driver. + void process_keydown(SDLKey, int [][2]); + void process_keyup (SDLKey, int [][2]); + + void set_game_name(char *); // Changes the value of private member m_strName; + void change_caption(char *thisName); // Adds the name of the singe game to the window's title bar. + static void daphne_side_set_caption(void *pInstance, char *thisName) // Sets value of m_strName + { + singe *pSingeInstance = (singe *) pInstance; + pSingeInstance->change_caption(thisName); + + } + + void set_script_path(const char *); + void get_script_path(char *); + +private: + // callback function for singe to pass error messages to us + static void set_last_error(const char *cpszErrMsg); + + string m_strName; // name of the game + string m_strGameScript; // script name for the game + string m_strScriptPath; // script name for the game + + DLL_INSTANCE m_dll_instance; // pointer to DLL we load (if we aren't statically linked) + + // by RDG2010 + + int i_keyboard_mode; // Stores the keyboard access mode. Valid values are: + // KEYBD_NORMAL - Tells SINGE to use daphne.ini keys. + // KEYBD_FULL - Tells SINGE to scan the full keyboard (a la Thayers). + static const int i_full_keybd_defs[]; // Array with discrete SDLKey values. Used in process_keyup/keydown. + +}; diff --git a/game/singe/Makefile b/game/singe/Makefile new file mode 100644 index 000000000..efc11450c --- /dev/null +++ b/game/singe/Makefile @@ -0,0 +1,42 @@ +# Makefile for SINGE +# Written by RDG2010 + +# TODO: Add dependencies + +CC = gcc +# Uncomment for debugging purposes +#DFLAGS = -pg +#DFLAGS = -ggdb -DSINGE_DEBUG -DDEBUG + +# Benchmarking version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops + +CFLAGS = ${DFLAGS} `sdl-config --cflags` -I./include +LIBS = `sdl-config --libs` -lSDL_image -lSDL_ttf + +OBJS = singeproxy.o lbaselib.o ldblib.o ldump.o lapi.o lauxlib.o lcode.o ldebug.o ldo.o \ + lfunc.o lgc.o linit.o liolib.o llex.o lmathlib.o lmem.o \ + loadlib.o lobject.o lopcodes.o loslib.o lparser.o lstate.o lstrlib.o \ + lstring.o ltable.o ltablib.o ltm.o \ + lundump.o lvm.o lzio.o lrandom.o random.o + +LIBNAME = libsinge.so + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: singe + +singe: ${OBJS} + ${CC} -shared -o ${LIBNAME} ${OBJS} ${LIBS} + cp ${LIBNAME} ../../../. + +clean: + rm -f ${LIBNAME} ${OBJS} + rm -f ../../../${LIBNAME} + diff --git a/game/singe/lapi.c b/game/singe/lapi.c new file mode 100644 index 000000000..d58cf79f9 --- /dev/null +++ b/game/singe/lapi.c @@ -0,0 +1,1087 @@ +/* +** $Id: lapi.c 3225 2010-08-18 03:26:19Z rdg $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $\n" + "$URL: www.lua.org $\n"; + + + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + +static TValue *index2adr (lua_State *L, int idx) { + if (idx > 0) { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) return cast(TValue *, luaO_nilobject); + else return o; + } + else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_ENVIRONINDEX: { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func->c.env); + return &L->env; + } + case LUA_GLOBALSINDEX: return gt(L); + default: { + Closure *func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) + ? &func->c.upvalue[idx-1] + : cast(TValue *, luaO_nilobject); + } + } +} + + +static Table *getcurrenv (lua_State *L) { + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else { + Closure *func = curr_func(L); + return func->c.env; + } +} + + +void luaA_pushobject (lua_State *L, const TValue *o) { + setobj2s(L, L->top, o); + api_incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res = 1; + lua_lock(L); + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else if (size > 0) { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; + } + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2adr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_objlen (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top+n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + luaC_barriert(L, hvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); + luaC_barriert(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define adjustresults(L,nres) \ + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->GCthreshold = MAX_LUMEM; + break; + } + case LUA_GCRESTART: { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: { + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) { + luaC_step(L); + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val) { + Closure *f; + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; +} + diff --git a/game/singe/lapi.h b/game/singe/lapi.h new file mode 100644 index 000000000..ebf2f525f --- /dev/null +++ b/game/singe/lapi.h @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h 2308 2006-11-14 21:16:54Z matt $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); + +#endif diff --git a/game/singe/lauxlib.c b/game/singe/lauxlib.c new file mode 100644 index 000000000..394f702f8 --- /dev/null +++ b/game/singe/lauxlib.c @@ -0,0 +1,652 @@ +/* +** $Id: lauxlib.c 3225 2010-08-18 03:26:19Z rdg $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +#define FREELIST_REF 0 /* free list of references */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l) { + luaI_openlib(L, libname, l, 0); +} + + +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l->name; l++) size++; + return size; +} + + +LUALIB_API void luaI_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + if (libname) { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + for (i=0; ifunc, nup); + lua_setfield(L, -(nup+2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +#if defined(LUA_COMPAT_GETN) + +static int checkint (lua_State *L, int topop) { + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } +} + + +LUALIB_API void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +LUALIB_API int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + return (int)lua_objlen(L, t); +} + +#endif + +/* }====================================================== */ + + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_addchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int extraline; + FILE *f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + c = getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; + } + ungetc(c, lf.f); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + + +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + + + +/* }====================================================== */ + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + (void)osize; + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + (void)L; /* to avoid warnings */ + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + diff --git a/game/singe/lauxlib.h b/game/singe/lauxlib.h new file mode 100644 index 000000000..956c9d9f5 --- /dev/null +++ b/game/singe/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h 2308 2006-11-14 21:16:54Z matt $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/game/singe/lbaselib.c b/game/singe/lbaselib.c new file mode 100644 index 000000000..1ea73025e --- /dev/null +++ b/game/singe/lbaselib.c @@ -0,0 +1,653 @@ +/* +** $Id: lbaselib.c 3225 2010-08-18 03:26:19Z rdg $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L, int opt) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushinteger(L, lua_getgccount(L)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)ud; /* to avoid warnings */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"loadstring", luaB_loadstring}, + {"next", luaB_next}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"unpack", luaB_unpack}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_corunning (lua_State *L) { + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + +/* }====================================================== */ + + +static void auxopen (lua_State *L, const char *name, + lua_CFunction f, lua_CFunction u) { + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); +} + + +static void base_open (lua_State *L) { + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; +} + diff --git a/game/singe/lcode.c b/game/singe/lcode.c new file mode 100644 index 000000000..a88305fdc --- /dev/null +++ b/game/singe/lcode.c @@ -0,0 +1,845 @@ +/* +** $Id: lcode.c 3225 2010-08-18 03:26:19Z rdg $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else { + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); +} + + +static int addk (FuncState *fs, TValue *k, TValue *v) { + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) ? nilK(fs) : + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : + boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else break; + } + case VK: { + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + case VFALSE: { + if (!hasjumps(e)) { + pc = luaK_jump(fs); /* always jump */ + break; + } + /* else go through */ + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VJMP: { + pc = e->u.s.info; + break; + } + case VTRUE: { + if (!hasjumps(e)) { + pc = luaK_jump(fs); /* always jump */ + break; + } + /* else go through */ + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) { + case OP_ADD: r = luai_numadd(v1, v2); break; + case OP_SUB: r = luai_numsub(v1, v2); break; + case OP_MUL: r = luai_nummul(v1, v2); break; + case OP_DIV: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); break; + case OP_MOD: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); break; + case OP_POW: r = luai_numpow(v1, v2); break; + case OP_UNM: r = luai_numunm(v1); break; + case OP_LEN: return 0; /* no constant folding for 'len' */ + default: lua_assert(0); r = 0; break; + } + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; + case OPR_POW: codearith(fs, OP_POW, e1, e2); break; + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +static int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/game/singe/lcode.h b/game/singe/lcode.h new file mode 100644 index 000000000..25e54b293 --- /dev/null +++ b/game/singe/lcode.h @@ -0,0 +1,76 @@ +/* +** $Id: lcode.h 2308 2006-11-14 21:16:54Z matt $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/game/singe/ldblib.c b/game/singe/ldblib.c new file mode 100644 index 000000000..9b80fb351 --- /dev/null +++ b/game/singe/ldblib.c @@ -0,0 +1,398 @@ +/* +** $Id: ldblib.c 3225 2010-08-18 03:26:19Z rdg $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; +} + + +static int db_getfenv (lua_State *L) { + luaL_checkany(L, 1); + lua_getfenv(L, 1); + return 1; +} + + +static int db_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) { + fputs(lua_tostring(L, -1), stderr); + fputs("\n", stderr); + } + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getfenv", db_getfenv}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"setfenv", db_setfenv}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} + diff --git a/game/singe/ldebug.c b/game/singe/ldebug.c new file mode 100644 index 000000000..61fa08066 --- /dev/null +++ b/game/singe/ldebug.c @@ -0,0 +1,638 @@ +/* +** $Id: ldebug.c 3225 2010-08-18 03:26:19Z rdg $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (lua_State *L, CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + + +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else { + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void info_tailcall (lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; il.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + if (f == NULL) { + info_tailcall(ar); + return status; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': { + ar->nups = f->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + lua_lock(L); + if (*what == '>') { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || + (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) + +int luaG_checkopenop (Instruction i) { + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: { + check(GETARG_B(i) == 0); + return 1; + } + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { + switch (mode) { + case OpArgN: check(r == 0); break; + case OpArgU: break; + case OpArgR: checkreg(pt, r); break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; + } + return 1; +} + + +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); + } + } + break; + } + } + if (testAMode(op)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testTMode(op)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+2+c); /* space for results */ + if (reg >= a+2) last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a+3); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + if (b > 0) checkreg(pt, a + b); + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } + break; + } + case OP_CLOSURE: { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: { + check((pt->is_vararg & VARARG_ISVARARG) && + !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); + checkreg(pt, a+b-1); + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return (symbexec(pt, pt->sizecode, NO_REG) != 0); +} + + +static const char *kname (Proto *p, int c) { + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + + +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L, L->ci, cast_int(o - L->base), &name) : + NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/game/singe/ldebug.h b/game/singe/ldebug.h new file mode 100644 index 000000000..88a1e5725 --- /dev/null +++ b/game/singe/ldebug.h @@ -0,0 +1,33 @@ +/* +** $Id: ldebug.h 2308 2006-11-14 21:16:54Z matt $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); + +#endif diff --git a/game/singe/ldo.c b/game/singe/ldo.c new file mode 100644 index 000000000..c0fce2209 --- /dev/null +++ b/game/singe/ldo.c @@ -0,0 +1,518 @@ +/* +** $Id: ldo.c 3225 2010-08-18 03:26:19Z rdg $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +static void restore_stack_limit (lua_State *L) { + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + + +static void resetstack (lua_State *L, int status) { + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else { + L->status = cast_byte(errcode); + if (G(L)->panic) { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack+newsize; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); +} + + +static CallInfo *growCI (lua_State *L) { + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + Table *htab = NULL; + StkId base, fixed; + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); +#if defined(LUA_COMPAT_VARARG) + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + for (i=0; itop - nvar + i); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + } +#endif + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed+i); + setnilvalue(fixed+i); + } + /* add `arg' parameter */ + if (htab) { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define inc_ci(L) \ + ((L->ci == L->end_ci) ? growCI(L) : \ + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + + +int luaD_precall (lua_State *L, StkId func, int nresults) { + LClosure *cl; + ptrdiff_t funcr; + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) + setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else { + luaD_poscall(L, L->top - n); + return PCRC; + } + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; + } + luaV_execute(L, cast_int(L->ci - L->base_ci)); +} + + +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; +}; + +static void f_parser (lua_State *L, void *ud) { + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { + struct SParser p; + int status; + p.z = z; p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; +} + + diff --git a/game/singe/ldo.h b/game/singe/ldo.h new file mode 100644 index 000000000..cc656754d --- /dev/null +++ b/game/singe/ldo.h @@ -0,0 +1,57 @@ +/* +** $Id: ldo.h 2308 2006-11-14 21:16:54Z matt $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* results from luaD_precall */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); + +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); + +#endif + diff --git a/game/singe/ldump.c b/game/singe/ldump.c new file mode 100644 index 000000000..ddc365088 --- /dev/null +++ b/game/singe/ldump.c @@ -0,0 +1,164 @@ +/* +** $Id: ldump.c 2308 2006-11-14 21:16:54Z matt $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size,D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p || D->strip) ? NULL : f->source,D); + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->nups,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + char h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,NULL,&D); + return D.status; +} diff --git a/game/singe/lfunc.c b/game/singe/lfunc.c new file mode 100644 index 000000000..81749c061 --- /dev/null +++ b/game/singe/lfunc.c @@ -0,0 +1,174 @@ +/* +** $Id: lfunc.c 3225 2010-08-18 03:26:19Z rdg $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + lua_assert(p->v != &p->u.value); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; + } + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->marked = luaC_white(g); + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/game/singe/lfunc.h b/game/singe/lfunc.h new file mode 100644 index 000000000..af1ac57bd --- /dev/null +++ b/game/singe/lfunc.h @@ -0,0 +1,34 @@ +/* +** $Id: lfunc.h 2308 2006-11-14 21:16:54Z matt $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/game/singe/lgc.c b/game/singe/lgc.c new file mode 100644 index 000000000..2f1e56f75 --- /dev/null +++ b/game/singe/lgc.c @@ -0,0 +1,711 @@ +/* +** $Id: lgc.c 2308 2006-11-14 21:16:54Z matt $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 + + +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) + +#define makewhite(g,x) \ + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) + + +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) + + +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) + + + +#define markvalue(g,o) { checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + + +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) + + +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + + +static void reallymarkobject (global_State *g, GCObject *o) { + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) { + case LUA_TSTRING: { + return; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt) markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: lua_assert(0); + } +} + + +static void marktmu (global_State *g) { + GCObject *u = g->tmudata; + if (u) { + do { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +size_t luaC_separateudata (lua_State *L, int all) { + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } + } + return deadmem; +} + + +static int traversetable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } + } + if (weakkey && weakvalue) return 1; + if (!weakvalue) { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) markvalue(g, gkey(n)); + if (!weakvalue) markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto (global_State *g, Proto *f) { + int i; + if (f->source) stringmark(f->source); + for (i=0; isizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i=0; isizeupvalues; i++) { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i=0; isizep; i++) { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i=0; isizelocvars; i++) { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + + + +static void traverseclosure (global_State *g, Closure *cl) { + markobject(g, cl->c.env); + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i=0; il.nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->l.upvals[i]); + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4*s_used < L->stacksize && + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + + +static void traversestack (global_State *g, lua_State *l) { + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + for (ci = l->base_ci; ci <= l->ci; ci++) { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) lim = ci->top; + } + for (o = l->stack; o < l->top; o++) + markvalue(g, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(l, lim); +} + + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static l_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) { + case LUA_TTABLE: { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : + sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + + sizeof(Proto *) * p->sizep + + sizeof(TValue) * p->sizek + + sizeof(int) * p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + + sizeof(TString *) * p->sizeupvalues; + } + default: lua_assert(0); return 0; + } +} + + +static size_t propagateall (global_State *g) { + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; +} + + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for userdata +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (const TValue *o, int iskey) { + if (!iscollectable(o)) return 0; + if (ttisstring(o)) { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +} + + +/* +** clear collected entries from weaktables +*/ +static void cleartable (GCObject *l) { + while (l) { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || + testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) { + while (i--) { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2h(o)); break; + case LUA_TTHREAD: { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: lua_assert(0); + } +} + + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) + + +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + if (curr == g->rootgc) /* is the first element of the list? */ + g->rootgc = curr->gch.next; /* adjust first */ + freeobj(L, curr); + } + } + return p; +} + + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && + g->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, g->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); + } +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} + + +/* +** Call all GC tag methods +*/ +void luaC_callGCTM (lua_State *L) { + while (G(L)->tmudata) + GCTM(L); +} + + +void luaC_freeall (lua_State *L) { + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); +} + + +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + +/* mark root set */ +static void markroot (lua_State *L) { + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + + +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +static void atomic (lua_State *L) { + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + + +static l_mem singlestep (lua_State *L) { + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) { + case GCSpause: { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: { + if (g->gray) + return propagatemark(g); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: { + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPCOST; + } + case GCSsweep: { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX*GCSWEEPCOST; + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM-1)/2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + do { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } + else { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); + } +} + + +void luaC_fullgc (lua_State *L) { + global_State *g = G(L); + if (g->gcstate <= GCSpropagate) { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; + } + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { + singlestep(L); + } + setthreshold(g); +} + + +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + + +void luaC_barrierback (lua_State *L, Table *t) { + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + + +void luaC_linkupval (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) { + if (g->gcstate == GCSpropagate) { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } + } +} + diff --git a/game/singe/lgc.h b/game/singe/lgc.h new file mode 100644 index 000000000..7ad6f02f1 --- /dev/null +++ b/game/singe/lgc.h @@ -0,0 +1,110 @@ +/* +** $Id: lgc.h 2308 2006-11-14 21:16:54Z matt $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 + + +/* +** some userful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) + + + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - for userdata: has been finalized +** bit 3 - for tables: has weak keys +** bit 4 - for tables: has weak values +** bit 5 - object is fixed (should not be collected) +** bit 6 - object is "super" fixed (only the main thread) +*/ + + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!isblack(x) && !iswhite(x)) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_checkGC(L) { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ + if (G(L)->totalbytes >= G(L)->GCthreshold) \ + luaC_step(L); } + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ + luaC_barrierback(L,t); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarriert(L,t,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } + +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_fullgc (lua_State *L); +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); + + +#endif diff --git a/game/singe/linit.c b/game/singe/linit.c new file mode 100644 index 000000000..73835701d --- /dev/null +++ b/game/singe/linit.c @@ -0,0 +1,39 @@ +/* +** $Id: linit.c 3225 2010-08-18 03:26:19Z rdg $ +** Initialization of libraries for lua.c +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {LUA_RNDLIBNAME, luaopen_random}, // by RDG2010 + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + diff --git a/game/singe/liolib.c b/game/singe/liolib.c new file mode 100644 index 000000000..897f7a8e5 --- /dev/null +++ b/game/singe/liolib.c @@ -0,0 +1,556 @@ +/* +** $Id: liolib.c 3225 2010-08-18 03:26:19Z rdg $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + + +static const char *const fnames[] = {"input", "output"}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L) { + FILE **f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = lua_pclose(L, *p); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + FILE *f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = lua_popen(L, filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, int findex) { + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else { + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + lua_getfield(L, -1, "popen"); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ + lua_pop(L, 1); /* pop 'popen' */ + return 1; +} + diff --git a/game/singe/llex.c b/game/singe/llex.c new file mode 100644 index 000000000..0950c8667 --- /dev/null +++ b/game/singe/llex.c @@ -0,0 +1,463 @@ +/* +** $Id: llex.c 3225 2010-08-18 03:26:19Z rdg $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "", "", "", "", + NULL +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : + luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token-FIRST_RESERVED]; +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } +} + + +void luaX_lexerror (LexState *ls, const char *msg, int token) { + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + luaX_lexerror(ls, msg, ls->t.token); +} + + +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) { + setbvalue(o, 1); /* make sure `str' will not be collected */ + luaC_checkGC(L); + } + return ts; +} + + +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + /* format error: try to update decimal point separator */ + struct lconv *cv = localeconv(); + char old = ls->decpoint; + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + lua_assert(isdigit(ls->current)); + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') + save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ +#if defined(LUA_COMPAT_LSTR) + case '[': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `[' */ + cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif + } + break; + } +#endif + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; + } + break; + } + case '\n': + case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); + while (ls->current != del) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\n': /* go through */ + case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case EOZ: continue; /* will raise an error next loop */ + default: { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10*c + (ls->current-'0'); + next(ls); + } while (++i<3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); + next(ls); + continue; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': + case '\r': { + inclinenumber(ls); + continue; + } + case '-': { + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); + continue; + } + case '[': { + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case '"': + case '\'': { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) return '.'; + else { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(ls->current)) { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') { + /* identifier or reserved word */ + TString *ts; + do { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + else { + seminfo->ts = ts; + return TK_NAME; + } + } + else { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +void luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +} + diff --git a/game/singe/llex.h b/game/singe/llex.h new file mode 100644 index 000000000..138ff97d8 --- /dev/null +++ b/game/singe/llex.h @@ -0,0 +1,81 @@ +/* +** $Id: llex.h 2308 2006-11-14 21:16:54Z matt $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +/* array with token `names' */ +LUAI_DATA const char *const luaX_tokens []; + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC void luaX_lookahead (LexState *ls); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/game/singe/llimits.h b/game/singe/llimits.h new file mode 100644 index 000000000..3e338c7ba --- /dev/null +++ b/game/singe/llimits.h @@ -0,0 +1,128 @@ +/* +** $Id: llimits.h 2308 2006-11-14 21:16:54Z matt $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +typedef LUAI_UINT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#ifdef lua_assert + +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) + +#else + +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck + +#endif + + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#ifndef MINSTRTABSIZE +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#ifndef luai_threadyield +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) ((void)0) +#else +#define condhardstacktests(x) x +#endif + +#endif diff --git a/game/singe/lmathlib.c b/game/singe/lmathlib.c new file mode 100644 index 000000000..c491ea3e6 --- /dev/null +++ b/game/singe/lmathlib.c @@ -0,0 +1,263 @@ +/* +** $Id: lmathlib.c 2308 2006-11-14 21:16:54Z matt $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_register(L, LUA_MATHLIBNAME, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif + return 1; +} + diff --git a/game/singe/lmem.c b/game/singe/lmem.c new file mode 100644 index 000000000..a6d5b5f1d --- /dev/null +++ b/game/singe/lmem.c @@ -0,0 +1,86 @@ +/* +** $Id: lmem.c 2308 2006-11-14 21:16:54Z matt $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** Lua ensures that (ptr == NULL) iff (osize == 0). +** +** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL). +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; +} + diff --git a/game/singe/lmem.h b/game/singe/lmem.h new file mode 100644 index 000000000..a9c0aed13 --- /dev/null +++ b/game/singe/lmem.h @@ -0,0 +1,49 @@ +/* +** $Id: lmem.h 2308 2006-11-14 21:16:54Z matt $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +#define luaM_reallocv(L,b,on,n,e) \ + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + + +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + +#endif + diff --git a/game/singe/loadlib.c b/game/singe/loadlib.c new file mode 100644 index 000000000..e07e03736 --- /dev/null +++ b/game/singe/loadlib.c @@ -0,0 +1,666 @@ +/* +** $Id: loadlib.c 3225 2010-08-18 03:26:19Z rdg $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. +*/ + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +#define LIBPREFIX "LOADLIB: " + +#define POF LUA_POF +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +#undef setprogdir + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HINSTANCE)lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DYLD) +/* +** {====================================================================== +** Native Mac OS X / Darwin Implementation +** ======================================================================= +*/ + +#include + + +/* Mac appends a `_' before C function names */ +#undef POF +#define POF "_" LUA_POF + + +static void pusherror (lua_State *L) { + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + + +static const char *errorfromcode (NSObjectFileImageReturnCode ret) { + switch (ret) { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + + +static void ll_unloadlib (void *lib) { + NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +} + + +static void *ll_load (lua_State *L, const char *path) { + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); +} + +/* }====================================================== */ + + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)lib; /* to avoid warnings */ +} + + +static void *ll_load (lua_State *L, const char *path) { + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)lib; (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + + +static void **ll_register (lua_State *L, const char *path) { + void **plib; + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; +} + + +/* +** __gc tag method: calls library's `ll_unloadlib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void **reg = ll_register(L, path); + if (*reg == NULL) *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname) { + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + + +static void loaderror (lua_State *L, const char *filename) { + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int loader_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF"%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + + +static int loader_C (lua_State *L) { + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static int loader_Croot (lua_State *L) { + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { + if (stat != ERRFUNC) loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; /* function not found */ + } + return 1; +} + + +static int loader_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ + + +static void setfenv (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + setfenv(L); + dooptions(L, loaded - 1); + return 0; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + + +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + +static void setpath (lua_State *L, const char *fieldname, const char *envname, + const char *def) { + const char *path = getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, + LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"seeall", ll_seeall}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"module", ll_module}, + {"require", ll_require}, + {NULL, NULL} +}; + + +static const lua_CFunction loaders[] = + {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; + + +LUALIB_API int luaopen_package (lua_State *L) { + int i; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); + /* fill it with pre-defined loaders */ + for (i=0; loaders[i] != NULL; i++) { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" + LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ +} + diff --git a/game/singe/lobject.c b/game/singe/lobject.c new file mode 100644 index 000000000..fbf881bbf --- /dev/null +++ b/game/singe/lobject.c @@ -0,0 +1,214 @@ +/* +** $Id: lobject.c 2308 2006-11-14 21:16:54Z matt $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + +} + + +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); + break; + } + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { + pushstr(L, "%"); + break; + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} diff --git a/game/singe/lobject.h b/game/singe/lobject.h new file mode 100644 index 000000000..70e510bee --- /dev/null +++ b/game/singe/lobject.h @@ -0,0 +1,381 @@ +/* +** $Id: lobject.h 3225 2010-08-18 03:26:19Z rdg $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define LAST_TAG LUA_TTHREAD + +#define NUM_TAGS (LAST_TAG+1) + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Tagged Values +*/ + +#define TValuefields Value value; int tt + +typedef struct lua_TValue { + TValuefields; +} TValue; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g,obj) \ + lua_assert(!iscollectable(obj) || \ + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + + +/* Macros to set values */ +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + +#define setnvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + +#define setpvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + +#define setbvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + +#define setsvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + checkliveness(G(L),i_o); } + +#define setuvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + checkliveness(G(L),i_o); } + +#define setthvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + checkliveness(G(L),i_o); } + +#define setclvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + checkliveness(G(L),i_o); } + +#define sethvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + checkliveness(G(L),i_o); } + +#define setptvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + checkliveness(G(L),i_o); } + + + + +#define setobj(L,obj1,obj2) \ + { const TValue *o2=(obj2); TValue *o1=(obj1); \ + o1->value = o2->value; o1->tt=o2->tt; \ + checkliveness(G(L),o1); } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TValue *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + unsigned int hash; + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(rawtsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +/* masks for new-style vararg */ +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/game/singe/lopcodes.c b/game/singe/lopcodes.c new file mode 100644 index 000000000..25f47f303 --- /dev/null +++ b/game/singe/lopcodes.c @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c 2308 2006-11-14 21:16:54Z matt $ +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETGLOBAL", + "GETTABLE", + "SETGLOBAL", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORLOOP", + "SETLIST", + "CLOSE", + "CLOSURE", + "VARARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +}; + diff --git a/game/singe/lopcodes.h b/game/singe/lopcodes.h new file mode 100644 index 000000000..ab71d1982 --- /dev/null +++ b/game/singe/lopcodes.h @@ -0,0 +1,268 @@ +/* +** $Id: lopcodes.h 2308 2006-11-14 21:16:54Z matt $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) =) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +} OpCode; + + +#define NUM_OPCODES (cast(int, OP_VARARG) + 1) + + + +/*=========================================================================== + Notes: + (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets `top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to `top' + + (*) In OP_SETLIST, if (B == 0) then B = `top'; + if (C == 0) then next `instruction' is real C + + (*) For comparisons, A specifies what condition the test should accept + (true or false). + + (*) All `skips' (pc++) assume that next instruction is a jump +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-1: op mode +** bits 2-3: C arg mode +** bits 4-5: B arg mode +** bit 6: instruction set register A +** bit 7: operator is a test +*/ + +enum OpArgMask { + OpArgN, /* argument is not used */ + OpArgU, /* argument is used */ + OpArgR, /* argument is a register or a jump offset */ + OpArgK /* argument is a constant or register/constant */ +}; + +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/game/singe/loslib.c b/game/singe/loslib.c new file mode 100644 index 000000000..119273197 --- /dev/null +++ b/game/singe/loslib.c @@ -0,0 +1,243 @@ +/* +** $Id: loslib.c 3225 2010-08-18 03:26:19Z rdg $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static int os_execute (lua_State *L) { + lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); + return 1; +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return os_pushresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} + diff --git a/game/singe/lparser.c b/game/singe/lparser.c new file mode 100644 index 000000000..03f4b2a29 --- /dev/null +++ b/game/singe/lparser.c @@ -0,0 +1,1339 @@ +/* +** $Id: lparser.c 3225 2010-08-18 03:26:19Z rdg $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +} + + +static void errorlimit (FuncState *fs, int limit, const char *what) { + const char *msg = (fs->f->linedefined == 0) ? + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : + luaO_pushfstring(fs->L, "function at line %d has more than %d %s", + fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +#define new_localvarliteral(ls,v,n) \ + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { + lua_assert(f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, + TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + return VGLOBAL; + } + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L, 0, 0); + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + L->top -= 2; /* remove table and prototype from the stack */ + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) anchor_token(ls); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, luaS_new(L, name)); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); +#if defined(LUA_COMPAT_VARARG) + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; +#endif + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + primaryexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to a local variable, the local variable +** is needed in a previous assignment (to a table). If so, save original +** local value in a safe place and use this safe copy in the previous +** assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void breakstat (LexState *ls) { + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ + } + else { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ + } + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static int test_then_block (LexState *ls) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') + field(ls, v); + if (ls->t.token == ':') { + needself = 1; + field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ diff --git a/game/singe/lparser.h b/game/singe/lparser.h new file mode 100644 index 000000000..0cc9bcf77 --- /dev/null +++ b/game/singe/lparser.h @@ -0,0 +1,82 @@ +/* +** $Id: lparser.h 2308 2006-11-14 21:16:54Z matt $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + +typedef struct expdesc { + expkind k; + union { + struct { int info, aux; } s; + lua_Number nval; + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +typedef struct upvaldesc { + lu_byte k; + lu_byte info; +} upvaldesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + short nlocvars; /* number of elements in `locvars' */ + lu_byte nactvar; /* number of active local variables */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +} FuncState; + + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); + + +#endif diff --git a/game/singe/lrandom.c b/game/singe/lrandom.c new file mode 100644 index 000000000..b05edab2f --- /dev/null +++ b/game/singe/lrandom.c @@ -0,0 +1,120 @@ +/* +* lrandom.c +* random-number library for Lua 5.1 based on the Mersenne Twister +* Luiz Henrique de Figueiredo +* 17 Mar 2010 12:31:47 +* This code is hereby placed in the public domain. +*/ + +#include +#include + +#include "lua.h" +#include "lauxlib.h" + +#define MYNAME "random" +#define MYVERSION MYNAME " library for " LUA_VERSION " / Mar 2010" +#define MYTYPE MYNAME " handle" + +#define SEED 2009UL + +#include "random.c" + +static MT *Pget(lua_State *L, int i) +{ + return luaL_checkudata(L,i,MYTYPE); +} + +static MT *Pnew(lua_State *L) +{ + MT *c=lua_newuserdata(L,sizeof(MT)); + luaL_getmetatable(L,MYTYPE); + lua_setmetatable(L,-2); + return c; +} + +static int Lnew(lua_State *L) /** new([seed]) */ +{ + lua_Number seed=luaL_optnumber(L,1,SEED); + MT *c=Pnew(L); + init_genrand(c,seed); + return 1; +} + +static int Lclone(lua_State *L) /** clone(c) */ +{ + MT *c=Pget(L,1); + MT *d=Pnew(L); + *d=*c; + return 1; +} + +static int Lseed(lua_State *L) /** seed(c,[seed]) */ +{ + MT *c=Pget(L,1); + init_genrand(c,luaL_optnumber(L,2,SEED)); + lua_settop(L,1); + return 1; +} + +static int Lvalue(lua_State *L) /** value(c,[a,b]) */ +{ + MT *c=Pget(L,1); + double a,b,r=genrand_res53(c); + switch (lua_gettop(L)) + { + case 1: + lua_pushnumber(L,r); + return 1; + case 2: + a=1; + b=luaL_checknumber(L,2); + break; + default: + a=luaL_checknumber(L,2); + b=luaL_checknumber(L,3); + break; + } + if (a>b) { double t=a; a=b; b=t; } + a=ceil(a); + b=floor(b); + if (a>b) return 0; + r=a+floor(r*(b-a+1)); + lua_pushnumber(L,r); + return 1; +} + +static int Ltostring(lua_State *L) +{ + MT *c=Pget(L,1); + lua_pushfstring(L,"%s %p",MYTYPE,(void*)c); + return 1; +} + +static const luaL_reg R[] = +{ + { "__tostring", Ltostring }, /** __tostring(c) */ + { "clone", Lclone }, + { "new", Lnew }, + { "seed", Lseed }, + { "value", Lvalue }, + { NULL, NULL } +}; + +LUALIB_API int luaopen_random(lua_State *L) +{ + luaL_newmetatable(L,MYTYPE); + lua_setglobal(L,MYNAME); + luaL_register(L,MYNAME,R); + lua_pushliteral(L,"version"); /** version */ + lua_pushliteral(L,MYVERSION); + lua_settable(L,-3); + lua_pushliteral(L,"__index"); + lua_pushvalue(L,-2); + lua_settable(L,-3); + lua_pushliteral(L,"__call"); /** __call(c) */ + lua_pushliteral(L,"value"); + lua_gettable(L,-3); + lua_settable(L,-3); + return 1; +} diff --git a/game/singe/lstate.c b/game/singe/lstate.c new file mode 100644 index 000000000..2deadd59e --- /dev/null +++ b/game/singe/lstate.c @@ -0,0 +1,214 @@ +/* +** $Id: lstate.c 3225 2010-08-18 03:26:19Z rdg $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + lua_State l; + global_State g; +} LG; + + + +static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*g->totalbytes; +} + + +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(iswhite(obj2gco(L1))); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; + for (i=0; imt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); +} + diff --git a/game/singe/lstate.h b/game/singe/lstate.h new file mode 100644 index 000000000..0a15fa4fe --- /dev/null +++ b/game/singe/lstate.h @@ -0,0 +1,169 @@ +/* +** $Id: lstate.h 3225 2010-08-18 03:26:19Z rdg $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* table of globals */ +#define gt(L) (&L->l_gt) + +/* registry */ +#define registry(L) (&G(L)->l_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for this function */ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + const Instruction *savedpc; + int nresults; /* expected number of results from this function */ + int tailcalls; /* number of tail calls lost under this entry */ +} CallInfo; + + + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *rootgc; /* list of all collectable objects */ + GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of weak tables (to be cleared) */ + GCObject *tmudata; /* last element of list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem totalbytes; /* number of bytes currently allocated */ + lu_mem estimate; /* an estimate of number of bytes actually in use */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + TValue l_registry; + struct lua_State *mainthread; + UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int stacksize; + int size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + TValue l_gt; /* table of globals */ + TValue env; /* temporary place for environments */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + diff --git a/game/singe/lstring.c b/game/singe/lstring.c new file mode 100644 index 000000000..6c29a0d90 --- /dev/null +++ b/game/singe/lstring.c @@ -0,0 +1,111 @@ +/* +** $Id: lstring.c 2308 2006-11-14 21:16:54Z matt $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash; + stringtable *tb; + int i; + if (G(L)->gcstate == GCSsweepstring) + return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + TString *ts; + stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + /* string may be dead */ + if (isdead(G(L), o)) changewhite(o); + return ts; + } + } + return newlstr(L, str, l, h); /* not found */ +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; +} + diff --git a/game/singe/lstring.h b/game/singe/lstring.h new file mode 100644 index 000000000..9d83e4ba9 --- /dev/null +++ b/game/singe/lstring.h @@ -0,0 +1,31 @@ +/* +** $Id: lstring.h 2308 2006-11-14 21:16:54Z matt $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif diff --git a/game/singe/lstrlib.c b/game/singe/lstrlib.c new file mode 100644 index 000000000..55b160e9b --- /dev/null +++ b/game/singe/lstrlib.c @@ -0,0 +1,871 @@ +/* +** $Id: lstrlib.c 3225 2010-08-18 03:26:19Z rdg $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, l); + return 1; +} + + +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { + /* relative string position: negative means back from end */ + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) posi = 1; + if ((size_t)pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case L_ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p+1))); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = ssrc_end && singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s+ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static int gfind_nodef (lua_State *L) { + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " + LUA_QL("string.gmatch")); +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + lua_State *L = ms->L; + switch (lua_type(L, 3)) { + case LUA_TNUMBER: + case LUA_TSTRING: { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +static void addintlen (char *form) { + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + + +static int str_format (lua_State *L) { + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': case 'i': { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } + case 'q': { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gfind", gfind_nodef}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_register(L, LUA_STRLIBNAME, strlib); +#if defined(LUA_COMPAT_GFIND) + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); +#endif + createmetatable(L); + return 1; +} + diff --git a/game/singe/ltable.c b/game/singe/ltable.c new file mode 100644 index 000000000..f4ad8917d --- /dev/null +++ b/game/singe/ltable.c @@ -0,0 +1,588 @@ +/* +** $Id: ltable.c 3225 2010-08-18 03:26:19Z rdg $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT > 26 +#define MAXBITS 26 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) + + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_TNIL}, /* value */ + {{{NULL}, LUA_TNIL, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(key2tval(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + } + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int nhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + setnodevector(L, t, nhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree-- > t->node) { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getnum (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNIL: return luaO_nilobject; + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + t->flags = 0; + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TValue *luaH_setnum (lua_State *L, Table *t, int key) { + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + + +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return n == dummynode; } + +#endif diff --git a/game/singe/ltable.h b/game/singe/ltable.h new file mode 100644 index 000000000..caaf04d51 --- /dev/null +++ b/game/singe/ltable.h @@ -0,0 +1,40 @@ +/* +** $Id: ltable.h 2308 2006-11-14 21:16:54Z matt $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define key2tval(n) (&(n)->i_key.tvk) + + +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/game/singe/ltablib.c b/game/singe/ltablib.c new file mode 100644 index 000000000..16a3b8f11 --- /dev/null +++ b/game/singe/ltablib.c @@ -0,0 +1,287 @@ +/* +** $Id: ltablib.c 3225 2010-08-18 03:26:19Z rdg $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i <= n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} + + +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); + return 1; +} + + +static int setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn + luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; +} + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread", + "proto", "upval" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__len", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/game/singe/ltm.h b/game/singe/ltm.h new file mode 100644 index 000000000..18eed785c --- /dev/null +++ b/game/singe/ltm.h @@ -0,0 +1,54 @@ +/* +** $Id: ltm.h 2308 2006-11-14 21:16:54Z matt $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LEN, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +LUAI_DATA const char *const luaT_typenames[]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/game/singe/lua.h b/game/singe/lua.h new file mode 100644 index 000000000..558a21d0c --- /dev/null +++ b/game/singe/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h 3225 2010-08-18 03:26:19Z rdg $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.4" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/game/singe/luaconf.h b/game/singe/luaconf.h new file mode 100644 index 000000000..935689979 --- /dev/null +++ b/game/singe/luaconf.h @@ -0,0 +1,763 @@ +/* +** $Id: luaconf.h 3225 2010-08-18 03:26:19Z rdg $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/game/singe/lualib.h b/game/singe/lualib.h new file mode 100644 index 000000000..00dab5fb8 --- /dev/null +++ b/game/singe/lualib.h @@ -0,0 +1,57 @@ +/* +** $Id: lualib.h 3225 2010-08-18 03:26:19Z rdg $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + +// by RDG2010 +#define LUA_RNDLIBNAME "random" +LUALIB_API int (luaopen_random) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/game/singe/lundump.c b/game/singe/lundump.c new file mode 100644 index 000000000..584f42699 --- /dev/null +++ b/game/singe/lundump.c @@ -0,0 +1,227 @@ +/* +** $Id: lundump.c 3225 2010-08-18 03:26:19Z rdg $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) +#define error(S,s) +#else +#define IF(c,s) if (c) error(S,s) + +static void error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} +#endif + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + size_t r=luaZ_read(S->Z,b,size); + IF (r!=0, "unexpected end"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + IF (x<0, "bad integer"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static Proto* LoadFunction(LoadState* S, TString* p); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)!=0); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: + error(S,"bad constant"); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=NULL; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction(LoadState* S, TString* p) +{ + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); + setptvalue2s(S->L,S->L->top,f); incr_top(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); + IF (!luaG_checkcode(f), "bad code"); + S->L->top--; + S->L->nCcalls--; + return f; +} + +static void LoadHeader(LoadState* S) +{ + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + luaU_header(h); + LoadBlock(S,s,LUAC_HEADERSIZE); + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + return LoadFunction(&S,luaS_newliteral(L,"=?")); +} + +/* +* make header +*/ +void luaU_header (char* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); + h+=sizeof(LUA_SIGNATURE)-1; + *h++=(char)LUAC_VERSION; + *h++=(char)LUAC_FORMAT; + *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)sizeof(int); + *h++=(char)sizeof(size_t); + *h++=(char)sizeof(Instruction); + *h++=(char)sizeof(lua_Number); + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ +} diff --git a/game/singe/lundump.h b/game/singe/lundump.h new file mode 100644 index 000000000..3853a8a27 --- /dev/null +++ b/game/singe/lundump.h @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h 2308 2006-11-14 21:16:54Z matt $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (char* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +#ifdef luac_c +/* print one chunk; from print.c */ +LUAI_FUNC void luaU_print (const Proto* f, int full); +#endif + +/* for header of binary files -- this is Lua 5.1 */ +#define LUAC_VERSION 0x51 + +/* for header of binary files -- this is the official format */ +#define LUAC_FORMAT 0 + +/* size of header of binary files */ +#define LUAC_HEADERSIZE 12 + +#endif diff --git a/game/singe/lvm.c b/game/singe/lvm.c new file mode 100644 index 000000000..40e37d216 --- /dev/null +++ b/game/singe/lvm.c @@ -0,0 +1,766 @@ +/* +** $Id: lvm.c 3225 2010-08-18 03:26:19Z rdg $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L, const Instruction *pc) { + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } +} + + +static void callTMres (lua_State *L, StkId res, const TValue *f, + const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); +} + + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, val, tm, t, key); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + TValue temp; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + /* else repeat with `tm' */ + setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ + t = &temp; + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + + +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + else { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { + size_t l = tsvalue(top-n-1)->len; + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) { + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) break; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) + + +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ + } + + + +void luaV_execute (lua_State *L, int nexeccalls) { + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; + reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L, pc); + if (L->status == LUA_YIELD) { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } + base = L->base; + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: { + TValue *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + int c = GETARG_C(i); + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: { + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: { + arith_op(luai_numdiv, TM_DIV); + continue; + } + case OP_MOD: { + arith_op(luai_nummod, TM_MOD); + continue; + } + case OP_POW: { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: { + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: { + const TValue *rb = RB(i); + switch (ttype(rb)) { + case LUA_TTABLE: { + setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); + break; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: { /* try metamethod */ + Protect( + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, rb, "get length of"); + ) + } + } + continue; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base+b); + continue; + } + case OP_JMP: { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (equalobj(L, rb, rc) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LT: { + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LE: { + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_TEST: { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_TAILCALL: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_RETURN: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (L->openupval) luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else { /* yes: continue its execution */ + if (b) L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: { + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: { + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb+3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) { /* continue loop? */ + setobjs2s(L, cb-1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) { + n = cast_int(L->top - ra) - 1; + L->top = L->ci->top; + } + if (c == 0) c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + continue; + } + case OP_CLOSE: { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, cl->env); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(L, ra, ncl); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, ci->base - n + j); + } + else { + setnilvalue(ra + j); + } + } + continue; + } + } + } +} + diff --git a/game/singe/lvm.h b/game/singe/lvm.h new file mode 100644 index 000000000..11705bc4c --- /dev/null +++ b/game/singe/lvm.h @@ -0,0 +1,36 @@ +/* +** $Id: lvm.h 2308 2006-11-14 21:16:54Z matt $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); + +#endif diff --git a/game/singe/lzio.c b/game/singe/lzio.c new file mode 100644 index 000000000..a7cd612bb --- /dev/null +++ b/game/singe/lzio.c @@ -0,0 +1,82 @@ +/* +** $Id: lzio.c 2308 2006-11-14 21:16:54Z matt $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return EOZ; + else { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } + } + return char2int(*z->p); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/game/singe/lzio.h b/game/singe/lzio.h new file mode 100644 index 000000000..57262a8b8 --- /dev/null +++ b/game/singe/lzio.h @@ -0,0 +1,67 @@ +/* +** $Id: lzio.h 2308 2006-11-14 21:16:54Z matt $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/game/singe/print.c b/game/singe/print.c new file mode 100644 index 000000000..b268e0f9b --- /dev/null +++ b/game/singe/print.c @@ -0,0 +1,227 @@ +/* +** $Id: print.c 3225 2010-08-18 03:26:19Z rdg $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} diff --git a/game/singe/random.c b/game/singe/random.c new file mode 100644 index 000000000..39beedf83 --- /dev/null +++ b/game/singe/random.c @@ -0,0 +1,128 @@ +/* +* random.c +* Mersenne Twister random number generator +* Luiz Henrique de Figueiredo +* 23 Sep 2008 22:57:32 +* slightly modified from mt19937ar.c available at +* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html +*/ + +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +typedef struct { + unsigned long v[N]; /* the array for the state vector */ + int i; +} MT; + +#define mt (o->v) +#define mti (o->i) + +/* initializes mt[N] with a seed */ +static void init_genrand(MT *o, unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* generates a random number on [0,0xffffffff]-interval */ +static unsigned long genrand_int32(MT *o) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(o,5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +static double genrand_res53(MT *o) +{ + unsigned long a=genrand_int32(o)>>5, b=genrand_int32(o)>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ diff --git a/game/singe/singe_interface.h b/game/singe/singe_interface.h new file mode 100644 index 000000000..e903c8b0c --- /dev/null +++ b/game/singe/singe_interface.h @@ -0,0 +1,117 @@ +#ifndef SINGE_INTERFACE_H +#define SINGE_INTERFACE_H + +// increase this number every time you change something in this file!!! +#define SINGE_INTERFACE_API_VERSION 7 +#define MAX_TITLE_LENGTH 40 //27 + +// info provided to Daphne to Singe +struct singe_in_info +{ + // the API version (THIS MUST COME FIRST!) + unsigned int uVersion; + + // FUNCTIONS: + + // shuts down daphne + void (*set_quitflag)(); + + // print a line to the debug console, and the log file (and to stdout on some platforms) + void (*printline)(const char *); + + // notifies daphne of the last error that singe got (so daphne can display it) + void (*set_last_error)(const char *); + + // From video/video.h + Uint16 (*get_video_width)(); + Uint16 (*get_video_height)(); + void (*draw_string)(const char*, int, int, SDL_Surface*); + + // From sound/samples.h + int (*samples_play_sample)(Uint8 *pu8Buf, unsigned int uLength, unsigned int uChannels, int iSlot, void (*finishedCallback)(Uint8 *pu8Buf, unsigned int uSlot)); + bool (*samples_set_state) (unsigned int, bool); // by rdg -- give Singe the ability to pause/resume samples + bool (*samples_is_sample_playing) (unsigned int); // Find out is a sample is still in the stream queue + bool (*samples_end_early) (unsigned int); // Terminate a sample from playing + void (*set_soundchip_nonvldp_volume)(unsigned int); // Control sound sample volume + void (*samples_flush_queue)(); + unsigned int (*get_soundchip_nonvldp_volume)(); + + // Laserdisc Control Functions + void (*enable_audio1)(); + void (*enable_audio2)(); + void (*disable_audio1)(); + void (*disable_audio2)(); + void (*request_screenshot)(); + void (*set_search_blanking)(bool enabled); + void (*set_skip_blanking)(bool enabled); + bool (*pre_change_speed)(unsigned int uNumerator, unsigned int uDenominator); + unsigned int (*get_current_frame)(); + void (*pre_play)(); + void (*pre_pause)(); + void (*pre_stop)(); + bool (*pre_search)(const char *, bool block_until_search_finished); + void (*framenum_to_frame)(Uint32, char *); + bool (*pre_skip_forward)(Uint32); + bool (*pre_skip_backward)(Uint32); + void (*pre_step_forward)(); + void (*pre_step_backward)(); + + //by RDG2010 + void *pSingeInstance; + void (*dll_side_set_keyboard_mode)(void *, int); + int (*dll_side_get_keyboard_mode)(void *); + int (*get_vldp_status)(); + double (*get_singe_version)(void); + void (*set_ldp_verbose)(bool); + void (*dll_side_set_caption)(void *, char *); + void (*dll_side_get_script_path)(void *, char *); + void (*dll_side_mouse_enable)(void *); + void (*dll_side_mouse_disable)(void *); + bool (*dll_side_set_mouse_mode)(int); + int (*dll_side_mouse_get_how_many)(void *); + void (*dll_side_pause_enable)(void *); + void (*dll_side_pause_disable)(void *); + + // VARIABLES: + + // VLDP Interface + struct vldp_in_info *g_local_info; + const struct vldp_out_info *g_vldp_info; + //SDL_Surface *g_screen_blitter; + +}; + +// info provided from Singe to Daphne +struct singe_out_info +{ + // the API version (THIS MUST COME FIRST!) + unsigned int uVersion; + + // FUNCTIONS: + void (*sep_call_lua)(const char *func, const char *sig, ...); + void (*sep_do_blit)(SDL_Surface *srfDest); + void (*sep_do_mouse_move)(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID); + void (*sep_error)(const char *fmt, ...); + void (*sep_print)(const char *fmt, ...); + void (*sep_set_static_pointers)(double *m_disc_fps, unsigned int *m_uDiscFPKS); + void (*sep_set_surface)(int width, int height); + void (*sep_shutdown)(void); + void (*sep_startup)(const char *script); + + //////////////////////////////////////////////////////////// +}; + +// if you want to build singe as a DLL, then define SINGE_DLL in your DLL project's preprocessor defs +#ifdef SINGE_DLL +#define SINGE_EXPORT __declspec(dllexport) +#else +// otherwise SINGE_EXPORT is blank +#define SINGE_EXPORT +#endif + +extern "C" +{ +SINGE_EXPORT const struct singe_out_info *singeproxy_init(const struct singe_in_info *in_info); +} + +#endif // SINGE_INTERFACE_H diff --git a/game/singe/singe_vs2008.vcproj b/game/singe/singe_vs2008.vcproj new file mode 100644 index 000000000..f16f650f3 --- /dev/null +++ b/game/singe/singe_vs2008.vcproj @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/game/singe/singe_vs2008.vcproj.WIN-TD3QRASCBBC.Scott Duensing.user b/game/singe/singe_vs2008.vcproj.WIN-TD3QRASCBBC.Scott Duensing.user new file mode 100644 index 000000000..55344b3b1 --- /dev/null +++ b/game/singe/singe_vs2008.vcproj.WIN-TD3QRASCBBC.Scott Duensing.user @@ -0,0 +1,65 @@ + + + + + + + + + + + diff --git a/game/singe/singeproxy.cpp b/game/singe/singeproxy.cpp new file mode 100644 index 000000000..5e6876913 --- /dev/null +++ b/game/singe/singeproxy.cpp @@ -0,0 +1,1814 @@ +/* + * singeproxy.cpp + * + * Copyright (C) 2006 Scott C. Duensing + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include "singeproxy.h" +#include "singe_interface.h" +#include + +using namespace std; + +//////////////////////////////////////////////////////////////////////////////// + +// Structures used by Singe to track various internal data +typedef struct g_soundType { + SDL_AudioSpec audioSpec; + Uint32 length; + Uint8 *buffer; +} g_soundT; + +// These are pointers and values needed by the script engine to interact with Daphne +lua_State *g_se_lua_context; +SDL_Surface *g_se_surface = NULL; +int g_se_overlay_width; +int g_se_overlay_height; +double *g_se_disc_fps; +unsigned int *g_se_uDiscFPKS; + +// used to know whether try to shutdown lua would crash +bool g_bLuaInitialized = false; + +// Communications from the DLL to and from Daphne +struct singe_out_info g_SingeOut; +const struct singe_in_info *g_pSingeIn = NULL; + +// Internal data to keep track of things +SDL_Color g_colorForeground = {255, 255, 255, 0}; +SDL_Color g_colorBackground = {0, 0, 0, 0}; +vector g_fontList; +vector g_soundList; +vector g_spriteList; +struct yuv_buf g_sep_yuv_buf; +int g_fontCurrent = -1; +int g_fontQuality = 1; +double g_sep_overlay_scale_x = 1; +double g_sep_overlay_scale_y = 1; +bool g_pause_state = false; // by RDG2010 + +int (*g_original_prepare_frame)(struct yuv_buf *buf); + +//////////////////////////////////////////////////////////////////////////////// + +extern "C" +{ +SINGE_EXPORT const struct singe_out_info *singeproxy_init(const struct singe_in_info *in_info) +{ + const struct singe_out_info *result = NULL; + + g_pSingeIn = in_info; + + g_SingeOut.uVersion = SINGE_INTERFACE_API_VERSION; + + g_SingeOut.sep_call_lua = sep_call_lua; + g_SingeOut.sep_do_blit = sep_do_blit; + g_SingeOut.sep_do_mouse_move = sep_do_mouse_move; + g_SingeOut.sep_error = sep_error; + g_SingeOut.sep_print = sep_print; + g_SingeOut.sep_set_static_pointers = sep_set_static_pointers; + g_SingeOut.sep_set_surface = sep_set_surface; + g_SingeOut.sep_shutdown = sep_shutdown; + g_SingeOut.sep_startup = sep_startup; + + result = &g_SingeOut; + + return result; +} +} + +//////////////////////////////////////////////////////////////////////////////// + +unsigned char sep_byte_clip(int value) +{ + int result; + + result = value; + if (result < 0) result = 0; + if (result > 255) result = 255; + + return (unsigned char)result; +} + +void sep_call_lua(const char *func, const char *sig, ...) +{ + va_list vl; + int narg, nres; /* number of arguments and results */ + int popCount; + const int top = lua_gettop(g_se_lua_context); + + va_start(vl, sig); + + /* get function */ + lua_getglobal(g_se_lua_context, func); + if (!lua_isfunction(g_se_lua_context, -1)) { + // Function does not exist. Bail. + lua_settop(g_se_lua_context, top); + return; + } + + /* push arguments */ + narg = 0; + while (*sig) { /* push arguments */ + switch (*sig++) { + + case 'd': /* double argument */ + lua_pushnumber(g_se_lua_context, va_arg(vl, double)); + break; + + case 'i': /* int argument */ + lua_pushnumber(g_se_lua_context, va_arg(vl, int)); + break; + + case 's': /* string argument */ + lua_pushstring(g_se_lua_context, va_arg(vl, char *)); + break; + + case '>': + goto endwhile; + + default: + sep_error("invalid option (%c)", *(sig - 1)); + } + narg++; + luaL_checkstack(g_se_lua_context, 1, "too many arguments"); + } endwhile: + + /* do the call */ + popCount = nres = strlen(sig); /* number of expected results */ + if (lua_pcall(g_se_lua_context, narg, nres, 0) != 0) /* do the call */ + sep_error("error running function '%s': %s", func, lua_tostring(g_se_lua_context, -1)); + + /* retrieve results */ + nres = -nres; /* stack index of first result */ + while (*sig) { /* get results */ + switch (*sig++) { + + case 'd': /* double result */ + if (!lua_isnumber(g_se_lua_context, nres)) + sep_error("wrong result type"); + *va_arg(vl, double *) = lua_tonumber(g_se_lua_context, nres); + break; + + case 'i': /* int result */ + if (!lua_isnumber(g_se_lua_context, nres)) + sep_error("wrong result type"); + *va_arg(vl, int *) = (int)lua_tonumber(g_se_lua_context, nres); + break; + + case 's': /* string result */ + if (!lua_isstring(g_se_lua_context, nres)) + sep_error("wrong result type"); + *va_arg(vl, const char **) = lua_tostring(g_se_lua_context, nres); + break; + + default: + sep_error("invalid option (%c)", *(sig - 1)); + } + nres++; + } + va_end(vl); + + if (popCount > 0) + lua_pop(g_se_lua_context, popCount); +} + +void sep_capture_vldp() +{ + // Intercept VLDP callback + g_original_prepare_frame = g_pSingeIn->g_local_info->prepare_frame; + g_pSingeIn->g_local_info->prepare_frame = sep_prepare_frame_callback; +} + +void sep_die(const char *fmt, ...) +{ + char message[2048]; + char temp[2048]; + + strcpy(message, "SINGE: "); + + va_list argp; + va_start(argp, fmt); + vsprintf(temp, fmt, argp); + + strcat(message, temp); + + // tell daphne what our last error was ... + g_pSingeIn->set_last_error(message); + + // force (clean) shutdown + g_pSingeIn->set_quitflag(); +} + +void sep_do_mouse_move(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID) +{ + static bool debounced = false; + int x1 = (int)x; + int y1 = (int)y; + int xr = (int)xrel; + int yr = (int)yrel; + int mID = (int) mouseID; + + // Not sure what's wrong here. I think things are getting started before Singe is ready. + if (!debounced) { + debounced = true; + return; + } + + x1 *= g_sep_overlay_scale_x; + y1 *= g_sep_overlay_scale_y; + xr *= g_sep_overlay_scale_x; + yr *= g_sep_overlay_scale_y; + + sep_call_lua("onMouseMoved", "iiiii", x1, y1, xr, yr, mID); +} + +void sep_error(const char *fmt, ...) +{ + char message[2048]; + sep_print("Script Error!"); + va_list argp; + va_start(argp, fmt); + vsprintf(message, fmt, argp); + lua_close(g_se_lua_context); + sep_die(message); +} + +int sep_lua_error(lua_State *L) +{ + lua_Debug ar; + int level = 0; + + sep_print("Singe has panicked! Very bad!"); + sep_print("Error: %s", lua_tostring(L, -1)); + + sep_print("Stack trace:"); + while (lua_getstack(L, level, &ar) != 0) + { + lua_getinfo(L, "nSl", &ar); + sep_print(" %d: function `%s' at line %d %s", level, ar.name, ar.currentline, ar.short_src); + level++; + } + sep_print("Trace complete."); + + return 0; +} + +int sep_prepare_frame_callback(struct yuv_buf *src) +{ + // Is our buffer the correct size? + if ((g_sep_yuv_buf.Y_size != src->Y_size) || (g_sep_yuv_buf.UV_size != src->UV_size)) { + if (g_sep_yuv_buf.Y != NULL) free(g_sep_yuv_buf.Y); + if (g_sep_yuv_buf.U != NULL) free(g_sep_yuv_buf.U); + if (g_sep_yuv_buf.V != NULL) free(g_sep_yuv_buf.V); + g_sep_yuv_buf.Y_size = 0; + g_sep_yuv_buf.UV_size = 0; + } + + // Is our buffer allocated? + if ((g_sep_yuv_buf.Y_size == 0) || (g_sep_yuv_buf.UV_size == 0)) { + g_sep_yuv_buf.Y = (unsigned char *)malloc(src->Y_size * sizeof(unsigned char)); + g_sep_yuv_buf.U = (unsigned char *)malloc(src->UV_size * sizeof(unsigned char)); + g_sep_yuv_buf.V = (unsigned char *)malloc(src->UV_size * sizeof(unsigned char)); + g_sep_yuv_buf.Y_size = src->Y_size; + g_sep_yuv_buf.UV_size = src->UV_size; + } + + // Make a copy of the passed YUV buffer for our own use later + memcpy(g_sep_yuv_buf.Y, src->Y, src->Y_size * sizeof(unsigned char)); + memcpy(g_sep_yuv_buf.U, src->U, src->UV_size * sizeof(unsigned char)); + memcpy(g_sep_yuv_buf.V, src->V, src->UV_size * sizeof(unsigned char)); + + // Pass callback along + return g_original_prepare_frame(src); +} + +void sep_print(const char *fmt, ...) +{ + char message[2048]; + char temp[2048]; + + strcpy(message, "SINGE: "); + + va_list argp; + va_start(argp, fmt); + vsprintf(temp, fmt, argp); + + strcat(message, temp); + + // Send all our output through Matt's code. + g_pSingeIn->printline(message); +} + +void sep_release_vldp() +{ + g_pSingeIn->g_local_info->prepare_frame = g_original_prepare_frame; +} + +void sep_set_static_pointers(double *m_disc_fps, unsigned int *m_uDiscFPKS) +{ + g_se_disc_fps = m_disc_fps; + g_se_uDiscFPKS = m_uDiscFPKS; +} + +void sep_set_surface(int width, int height) +{ + bool createSurface = false; + + g_se_overlay_height = height; + g_se_overlay_width = width; + + if (g_se_surface == NULL) { + createSurface = true; + } else { + if ((g_se_surface->w != g_se_overlay_width) || (g_se_surface->h != g_se_overlay_height)) + { + SDL_FreeSurface(g_se_surface); + createSurface = true; + } + } + + if (createSurface) { + g_se_surface = SDL_CreateRGBSurface(SDL_SRCALPHA|SDL_SWSURFACE, g_se_overlay_width, g_se_overlay_height, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000); + g_sep_overlay_scale_x = (double)g_se_overlay_width / (double)g_pSingeIn->get_video_width(); + g_sep_overlay_scale_y = (double)g_se_overlay_height / (double)g_pSingeIn->get_video_height(); + } +} + +void sep_shutdown(void) +{ + sep_release_vldp(); + + sep_unload_fonts(); + sep_unload_sounds(); + sep_unload_sprites(); + + if (g_sep_yuv_buf.Y != NULL) free(g_sep_yuv_buf.Y); + if (g_sep_yuv_buf.U != NULL) free(g_sep_yuv_buf.U); + if (g_sep_yuv_buf.V != NULL) free(g_sep_yuv_buf.V); + + g_sep_yuv_buf.Y_size = 0; + g_sep_yuv_buf.UV_size = 0; + + TTF_Quit(); + + if (g_bLuaInitialized) + { + lua_close(g_se_lua_context); + g_bLuaInitialized = false; + } +} + +void sep_sound_ended(Uint8 *buffer, unsigned int slot) +{ + /* + * by RDG2010 + * This function is triggered by a callback when a sound finishes playing + + // Following lines are for debug purposes: + + char s[100]; + sprintf(s, "sep_sound_ended: slot numer is %u", slot); + sep_print(s); + + /////////////////////////// + */ + + sep_call_lua("onSoundCompleted", "i", slot); + +} + +void sep_do_blit(SDL_Surface *srfDest) +{ + sep_srf32_to_srf8(g_se_surface, srfDest); + //sep_blit_g_screen(g_se_surface, srfDest); +} + +bool sep_blit_g_screen(SDL_Surface *src, SDL_Surface *dst) +{ + bool bResult = false; + int result = 0; + + // convert a 32-bit surface to an 8-bit surface (where the palette is one we've defined) + + + { + //SDL_LockSurface(dst); + //SDL_LockSurface(src); + + //SDL_BlitSurface(g_spriteList[sprite], NULL, g_se_surface, &dest); + result = SDL_BlitSurface(src, NULL, dst, NULL); + + //SDL_UnlockSurface(src); + //SDL_UnlockSurface(dst); + + bResult = true; + } + + return bResult; +} + +bool sep_srf32_to_srf8(SDL_Surface *src, SDL_Surface *dst) +{ + bool bResult = false; + + // convert a 32-bit surface to an 8-bit surface (where the palette is one we've defined) + + // safety check + if ( + // if source and destination surfaces are the same dimensions + ((dst->w == src->w) && (dst->h == src->h)) && + // and destination is 8-bit + (dst->format->BitsPerPixel == 8) && + // and source is 32-bit + (src->format->BitsPerPixel == 32) + ) + { + SDL_LockSurface(dst); + SDL_LockSurface(src); + + void *pSrcLine = src->pixels; + void *pDstLine = dst->pixels; + for (unsigned int uRowIdx = 0; uRowIdx < (unsigned int) src->h; ++uRowIdx) + { + Uint32 *p32SrcPix = (Uint32 *) pSrcLine; + Uint8 *p8DstPix = (Uint8 *) pDstLine; + + // do one line + for (unsigned int uColIdx = 0; uColIdx < (unsigned int) src->w; ++uColIdx) + { + // get source pixel ... + Uint32 u32SrcPix = *p32SrcPix; + + Uint8 u8B = (u32SrcPix & src->format->Bmask) >> src->format->Bshift; + Uint8 u8G = (u32SrcPix & src->format->Gmask) >> src->format->Gshift; + Uint8 u8R = (u32SrcPix & src->format->Rmask) >> src->format->Rshift; + Uint8 u8A = (u32SrcPix & src->format->Amask) >> src->format->Ashift; + + u8B &= 0xE0; // blue has 3 bits (8 shades) + u8G &= 0xC0; // green has 2 bits + u8R &= 0xE0; // red has 3 bits + + // compute 8-bit index + Uint8 u8Idx = u8R | (u8G >> 3) | (u8B >> 5); + + // if alpha channel is more opaque, then make it fully opaque + if (u8A > 0x7F) + { + // if resulting index is 0, we have to change it because 0 is reserved for transparent + if (u8Idx == 0) + { + // 1 becomes the replacement (and will be black) + u8Idx = 1; + } + // else leave it alone + } + // else make it fully transparent + else + { + u8Idx = 0; + } + + // store computed value + *p8DstPix = u8Idx; + + ++p8DstPix; // go to the next one ... + ++p32SrcPix; // go to the next one ... + } // end doing current line + + pSrcLine = ((Uint8 *) pSrcLine) + src->pitch; // go to the next line + pDstLine = ((Uint8 *) pDstLine) + dst->pitch; // " " " + } // end doing all rows + + SDL_UnlockSurface(src); + SDL_UnlockSurface(dst); + + bResult = true; + } + + return bResult; +} + +void sep_startup(const char *script) +{ + g_se_lua_context = lua_open(); + luaL_openlibs(g_se_lua_context); + lua_atpanic(g_se_lua_context, sep_lua_error); + + lua_register(g_se_lua_context, "colorBackground", sep_color_set_backcolor); + lua_register(g_se_lua_context, "colorForeground", sep_color_set_forecolor); + + lua_register(g_se_lua_context, "daphneGetHeight", sep_daphne_get_height); + lua_register(g_se_lua_context, "daphneGetWidth", sep_daphne_get_width); + lua_register(g_se_lua_context, "daphneScreenshot", sep_screenshot); + + lua_register(g_se_lua_context, "debugPrint", sep_debug_say); + + lua_register(g_se_lua_context, "discAudio", sep_audio_control); + lua_register(g_se_lua_context, "discChangeSpeed", sep_change_speed); + lua_register(g_se_lua_context, "discGetFrame", sep_get_current_frame); + lua_register(g_se_lua_context, "discPause", sep_pause); + lua_register(g_se_lua_context, "discPauseAtFrame", sep_skip_and_pause); + lua_register(g_se_lua_context, "discPlay", sep_play); + lua_register(g_se_lua_context, "discSearch", sep_search); + lua_register(g_se_lua_context, "discSearchBlanking", sep_search_blanking); + lua_register(g_se_lua_context, "discSetFPS", sep_set_disc_fps); + lua_register(g_se_lua_context, "discSkipBackward", sep_skip_backward); + lua_register(g_se_lua_context, "discSkipBlanking", sep_skip_blanking); + lua_register(g_se_lua_context, "discSkipForward", sep_skip_forward); + lua_register(g_se_lua_context, "discSkipToFrame", sep_skip_to_frame); + lua_register(g_se_lua_context, "discStepBackward", sep_step_backward); + lua_register(g_se_lua_context, "discStepForward", sep_step_forward); + lua_register(g_se_lua_context, "discStop", sep_stop); + + lua_register(g_se_lua_context, "fontLoad", sep_font_load); + lua_register(g_se_lua_context, "fontPrint", sep_say_font); + lua_register(g_se_lua_context, "fontQuality", sep_font_quality); + lua_register(g_se_lua_context, "fontSelect", sep_font_select); + lua_register(g_se_lua_context, "fontToSprite", sep_font_sprite); + + lua_register(g_se_lua_context, "overlayClear", sep_overlay_clear); + lua_register(g_se_lua_context, "overlayGetHeight", sep_get_overlay_height); + lua_register(g_se_lua_context, "overlayGetWidth", sep_get_overlay_width); + lua_register(g_se_lua_context, "overlayPrint", sep_say); + + lua_register(g_se_lua_context, "soundLoad", sep_sound_load); + lua_register(g_se_lua_context, "soundPlay", sep_sound_play); + lua_register(g_se_lua_context, "soundPause", sep_sound_pause); // rdg + lua_register(g_se_lua_context, "soundResume", sep_sound_resume); // + lua_register(g_se_lua_context, "soundIsPlaying", sep_sound_get_flag); // + lua_register(g_se_lua_context, "soundStop", sep_sound_stop); // + lua_register(g_se_lua_context, "soundSetVolume", sep_sound_set_volume); + lua_register(g_se_lua_context, "soundGetVolume", sep_sound_get_volume); + lua_register(g_se_lua_context, "soundFullStop", sep_sound_flush_queue); + + lua_register(g_se_lua_context, "spriteDraw", sep_sprite_draw); + lua_register(g_se_lua_context, "spriteGetHeight", sep_sprite_height); + lua_register(g_se_lua_context, "spriteGetWidth", sep_sprite_width); + lua_register(g_se_lua_context, "spriteLoad", sep_sprite_load); + + lua_register(g_se_lua_context, "vldpGetHeight", sep_mpeg_get_height); + lua_register(g_se_lua_context, "vldpGetPixel", sep_mpeg_get_pixel); + lua_register(g_se_lua_context, "vldpGetWidth", sep_mpeg_get_width); + lua_register(g_se_lua_context, "vldpSetVerbose", sep_ldp_verbose); + + // by RDG2010 + lua_register(g_se_lua_context, "keyboardGetMode", sep_keyboard_get_mode); + lua_register(g_se_lua_context, "keyboardSetMode", sep_keyboard_set_mode); + lua_register(g_se_lua_context, "mouseEnable", sep_mouse_enable); + lua_register(g_se_lua_context, "mouseDisable", sep_mouse_disable); + lua_register(g_se_lua_context, "mouseSetMode", sep_mouse_set_mode); + lua_register(g_se_lua_context, "mouseHowMany", sep_mouse_get_how_many); + lua_register(g_se_lua_context, "discGetState", sep_get_vldp_state); + lua_register(g_se_lua_context, "singeGetPauseFlag", sep_get_pause_flag); + lua_register(g_se_lua_context, "singeSetPauseFlag", sep_set_pause_flag); + lua_register(g_se_lua_context, "singeEnablePauseKey", sep_pause_enable); + lua_register(g_se_lua_context, "singeDisablePauseKey", sep_pause_disable); + lua_register(g_se_lua_context, "singeQuit", sep_singe_quit); + lua_register(g_se_lua_context, "singeVersion", sep_singe_version); + lua_register(g_se_lua_context, "singeSetGameName", sep_set_game_name); + lua_register(g_se_lua_context, "singeGetScriptPath", sep_get_script_path); + + ////////////////// + + if (TTF_Init() < 0) + { + sep_die("Unable to initialize font library."); + } + + g_sep_yuv_buf.Y = NULL; + g_sep_yuv_buf.U = NULL; + g_sep_yuv_buf.V = NULL; + g_sep_yuv_buf.Y_size = 0; + g_sep_yuv_buf.UV_size = 0; + + sep_capture_vldp(); + + g_bLuaInitialized = true; + + if (luaL_dofile(g_se_lua_context, script) != 0) + { + sep_error("error compiling script: %s", lua_tostring(g_se_lua_context, -1)); + g_bLuaInitialized = false; + } +} + + +void sep_unload_fonts(void) +{ + int x; + + if (g_fontList.size() > 0) + { + for (x=0; x<(int)g_fontList.size(); x++) + TTF_CloseFont(g_fontList[x]); + g_fontList.clear(); + } +} + +void sep_unload_sounds(void) +{ + int x; + // Singe will crash if waves are unloaded from memory before clearing the audio queue. + // Lets fix that. --RDG + + g_pSingeIn->samples_flush_queue(); // stop all sounds from SDL's audio queue -rdg + + if (g_soundList.size() > 0) // unload wave files from memory -- rdg + { + for (x=0; x<(int)g_soundList.size(); x++) + SDL_FreeWAV(g_soundList[x].buffer); + g_soundList.clear(); + } +} + +void sep_unload_sprites(void) +{ + int x; + + if (g_spriteList.size() > 0) + { + for (x=0; x<(int)g_spriteList.size(); x++) + SDL_FreeSurface(g_spriteList[x]); + g_spriteList.clear(); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Singe API Calls + +static int sep_audio_control(lua_State *L) +{ + int n = lua_gettop(L); + int channel = 0; + bool onOff = false; + + if (n == 2) + if (lua_isnumber(L, 1)) + if (lua_isboolean(L, 2)) + { + channel = lua_tonumber(L, 1); + onOff = lua_toboolean(L, 2); + if (onOff) + if (channel == 1) + { + g_pSingeIn->enable_audio1(); + } + else + { + g_pSingeIn->enable_audio2(); + } + else + if (channel == 1) + { + g_pSingeIn->disable_audio1(); + } + else + { + g_pSingeIn->disable_audio2(); + } + } + + return 0; +} + +static int sep_change_speed(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 2) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + { + g_pSingeIn->pre_change_speed(lua_tonumber(L, 1), lua_tonumber(L, 2)); + } + + return 0; +} + +static int sep_color_set_backcolor(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 3) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + if (lua_isnumber(L, 3)) + { + g_colorBackground.r = (char)lua_tonumber(L, 1); + g_colorBackground.g = (char)lua_tonumber(L, 2); + g_colorBackground.b = (char)lua_tonumber(L, 3); + g_colorBackground.unused = (char)0; + } + + return 0; +} + +static int sep_color_set_forecolor(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 3) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + if (lua_isnumber(L, 3)) + { + g_colorForeground.r = (char)lua_tonumber(L, 1); + g_colorForeground.g = (char)lua_tonumber(L, 2); + g_colorForeground.b = (char)lua_tonumber(L, 3); + g_colorForeground.unused = (char)0; + } + + return 0; +} + +static int sep_daphne_get_height(lua_State *L) +{ + lua_pushnumber(L, g_pSingeIn->get_video_height()); + return 1; +} + +static int sep_daphne_get_width(lua_State *L) +{ + lua_pushnumber(L, g_pSingeIn->get_video_width()); + return 1; +} + +static int sep_debug_say(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isstring(L, 1)) + sep_print("%s", lua_tostring(L, 1)); + + return 0; +} + +static int sep_font_load(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + const char *font = NULL; + int points = 0; + + if (n == 2) + if (lua_isstring(L, 1)) + if (lua_isnumber(L, 2)) + { + font = lua_tostring(L, 1); + points = lua_tonumber(L, 2); + TTF_Font *temp = NULL; + // Load this font. + temp = TTF_OpenFont(font, points); + if (temp == NULL) + sep_die("Unable to load font."); + // Make it the current font and mark it as loaded. + g_fontList.push_back(temp); + g_fontCurrent = g_fontList.size() - 1; + result = g_fontCurrent; + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_font_quality(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + g_fontQuality = lua_tonumber(L, 1); + + return 0; +} + +static int sep_font_select(lua_State *L) +{ + int n = lua_gettop(L); + int fontIndex = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + fontIndex = lua_tonumber(L, 1); + if (fontIndex < (int)g_fontList.size()) + g_fontCurrent = fontIndex; + } + + return 0; +} + +static int sep_font_sprite(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isstring(L, 1)) + if (g_fontCurrent >= 0) { + SDL_Surface *textsurface = NULL; + const char *message = lua_tostring(L, 1); + TTF_Font *font = g_fontList[g_fontCurrent]; + + switch (g_fontQuality) { + case 1: + textsurface = TTF_RenderText_Solid(font, message, g_colorForeground); + break; + + case 2: + textsurface = TTF_RenderText_Shaded(font, message, g_colorForeground, g_colorBackground); + break; + + case 3: + textsurface = TTF_RenderText_Blended(font, message, g_colorForeground); + break; + } + + if (!(textsurface)) { + sep_die("Font surface is null!"); + } else { + + // the colorkey is only 0 when using Solid (quick n' dirty) mode. + // In shaded mode, color 0 refers to the background color. + if (g_fontQuality == 1) + { + SDL_SetAlpha(textsurface, SDL_RLEACCEL, 0); + + // by definition, the transparent index is 0 + SDL_SetColorKey(textsurface, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0); + } + // alpha must be set for 32-bit surface when blitting or else alpha channel will be ignored + else if (g_fontQuality == 3) + { + SDL_SetAlpha(textsurface, SDL_SRCALPHA | SDL_RLEACCEL, 0); + } + + g_spriteList.push_back(textsurface); + result = g_spriteList.size() - 1; + } + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_get_current_frame(lua_State *L) +{ + lua_pushnumber(L, g_pSingeIn->get_current_frame()); + return 1; +} + +static int sep_get_overlay_height(lua_State *L) +{ + lua_pushnumber(L, g_se_overlay_height); + return 1; +} + +static int sep_get_overlay_width(lua_State *L) +{ + lua_pushnumber(L, g_se_overlay_width); + return 1; +} + +static int sep_mpeg_get_height(lua_State *L) +{ + lua_pushnumber(L, g_pSingeIn->g_vldp_info->h); + return 1; +} + +static int sep_mpeg_get_pixel(lua_State *L) +{ + int n = lua_gettop(L); + bool result = false; + int xpos; + int ypos; + unsigned int Y_index; + unsigned int UV_index; + unsigned char Y; + unsigned char U; + unsigned char V; + unsigned char R; + unsigned char G; + unsigned char B; + int C; + int D; + int E; + + if (n == 2) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) { + xpos = (int)((double)lua_tonumber(L, 1) * ((double)g_pSingeIn->g_vldp_info->w / (double)g_se_overlay_width)); + ypos = (int)((double)lua_tonumber(L, 2) * ((double)g_pSingeIn->g_vldp_info->h / (double)g_se_overlay_height)); + Y_index = (g_pSingeIn->g_vldp_info->w * ypos) + xpos; + UV_index = (g_pSingeIn->g_vldp_info->w * ypos / 4) + (xpos / 2); + Y = g_sep_yuv_buf.Y[Y_index]; + U = g_sep_yuv_buf.U[UV_index]; + V = g_sep_yuv_buf.V[UV_index]; + C = Y - 16; + D = U - 128; + E = V - 128; + R = sep_byte_clip(( 298 * C + 409 * E + 128) >> 8); + G = sep_byte_clip(( 298 * C - 100 * D - 208 * E + 128) >> 8); + B = sep_byte_clip(( 298 * C + 516 * D + 128) >> 8); + result = true; + } + + if (result) { + lua_pushnumber(L, (int)R); + lua_pushnumber(L, (int)G); + lua_pushnumber(L, (int)B); + } else { + lua_pushnumber(L, -1); + lua_pushnumber(L, -1); + lua_pushnumber(L, -1); + } + return 3; +} + +static int sep_mpeg_get_width(lua_State *L) +{ + lua_pushnumber(L, g_pSingeIn->g_vldp_info->w); + return 1; +} + +static int sep_overlay_clear(lua_State *L) +{ + SDL_FillRect(g_se_surface, NULL, 0); + return 0; +} + +static int sep_pause(lua_State *L) +{ + g_pSingeIn->pre_pause(); + g_pause_state = true; // by RDG2010 + + return 0; +} + +static int sep_play(lua_State *L) +{ + g_pSingeIn->pre_play(); + g_pause_state = false; // by RDG2010 + + return 0; +} + +static int sep_say(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 3) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + if (lua_isstring(L, 3)) + g_pSingeIn->draw_string((char *)lua_tostring(L, 3), lua_tonumber(L, 1), lua_tonumber(L, 2), g_se_surface); + + return 0; +} + +static int sep_say_font(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 3) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + if (lua_isstring(L, 3)) + if (g_fontCurrent >= 0) { + SDL_Surface *textsurface = NULL; + const char *message = lua_tostring(L, 3); + TTF_Font *font = g_fontList[g_fontCurrent]; + + switch (g_fontQuality) { + case 1: + textsurface = TTF_RenderText_Solid(font, message, g_colorForeground); + break; + + case 2: + textsurface = TTF_RenderText_Shaded(font, message, g_colorForeground, g_colorBackground); + break; + + case 3: + textsurface = TTF_RenderText_Blended(font, message, g_colorForeground); + break; + } + + if (!(textsurface)) { + sep_die("Font surface is null!"); + } else { + SDL_Rect dest; + dest.x = lua_tonumber(L, 1); + dest.y = lua_tonumber(L, 2); + dest.w = textsurface->w; + dest.h = textsurface->h; + + // the colorkey is only 0 when using Solid (quick n' dirty) mode. + // In shaded mode, color 0 refers to the background color. + if (g_fontQuality == 1) + { + SDL_SetAlpha(textsurface, SDL_RLEACCEL, 0); + + // by definition, the transparent index is 0 + SDL_SetColorKey(textsurface, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0); + } + // alpha must be set for 32-bit surface when blitting or else alpha channel will be ignored + else if (g_fontQuality == 3) + { + SDL_SetAlpha(textsurface, SDL_SRCALPHA | SDL_RLEACCEL, 0); + } + +// SDL_SaveBMP(textsurface, "nukeme.bmp"); + + SDL_BlitSurface(textsurface, NULL, g_se_surface, &dest); + +// SDL_SaveBMP(g_se_surface, "nukeme2.bmp"); + + SDL_FreeSurface(textsurface); + } + } + + return 0; +} + +static int sep_screenshot(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 0) + { + g_pSingeIn->request_screenshot(); + } + + //SDL_SaveBMP(g_se_surface, "/Users/scott/source/daphne/singe/g_se_surface.bmp"); + + return 0; +} + +static int sep_search(lua_State *L) +{ + char s[6] = { 0 }; + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + { + g_pSingeIn->framenum_to_frame(lua_tonumber(L, 1), s); + g_pSingeIn->pre_search(s, true); + } + + return 0; +} + +static int sep_search_blanking(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isboolean(L, 1)) + { + g_pSingeIn->set_search_blanking(lua_toboolean(L, 1)); + } + + return 0; +} + +static int sep_set_disc_fps(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + { + *g_se_disc_fps = lua_tonumber(L, 1); + if (*g_se_disc_fps != 0.0) + *g_se_uDiscFPKS = (unsigned int) ((*g_se_disc_fps * 1000.0) + 0.5); // frames per kilosecond (same precision, but an int instead of a float) + } + + return 0; +} + +static int sep_skip_backward(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + { + g_pSingeIn->pre_skip_backward(lua_tonumber(L, 1)); + } + + return 0; +} + +static int sep_skip_blanking(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isboolean(L, 1)) + { + g_pSingeIn->set_skip_blanking(lua_toboolean(L, 1)); + } + + return 0; +} + +static int sep_skip_forward(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + { + g_pSingeIn->pre_skip_forward(lua_tonumber(L, 1)); + } + + return 0; +} + +/* +static int sep_search(lua_State *L) +{ + char s[6] = { 0 }; + int n = lua_gettop(L); + + if (n == 1) + if (lua_isnumber(L, 1)) + { + g_pSingeIn->framenum_to_frame(lua_tonumber(L, 1), s); + g_pSingeIn->pre_search(s, true); + } + + return 0; +} +*/ + +static int sep_skip_to_frame(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 1) + { + if (lua_isnumber(L, 1)) + { + + // TODO : implement this for real on the daphne side of things instead of having to do a search/play hack + char s[7] = { 0 }; + g_pSingeIn->framenum_to_frame(lua_tonumber(L, 1), s); + g_pSingeIn->pre_search(s, true); + g_pSingeIn->pre_play(); + g_pause_state = false; // BY RDG2010 + } + } + + return 0; +} + +static int sep_skip_and_pause(lua_State *L) +{ + + int n = lua_gettop(L); + + if (n == 1) + { + if (lua_isnumber(L, 1)) + { + + // TODO : implement this for real on the daphne side of things instead of having to do a search/play hack + char s[10] = { 0 }; // i am not sure what's the max frame value can be is at the time of this writing.... --- rdg + g_pSingeIn->framenum_to_frame(lua_tonumber(L, 1), s); + g_pSingeIn->pre_search(s, true); + g_pSingeIn->pre_play(); + g_pSingeIn->pre_pause(); + g_pause_state = true; // by RDG2010 + } + } + + return 0; + +} + +static int sep_sound_load(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isstring(L, 1)) + { + const char *file = lua_tostring(L, 1); + g_soundT temp; + if (SDL_LoadWAV(file, &temp.audioSpec, &temp.buffer, &temp.length) == NULL) + { + sep_die("Could not open %s: %s", file, SDL_GetError()); + } else { + g_soundList.push_back(temp); + result = g_soundList.size() - 1; + } + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_sound_play(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sound = lua_tonumber(L, 1); + if (sound < (int)g_soundList.size()) + result = g_pSingeIn->samples_play_sample(g_soundList[sound].buffer, g_soundList[sound].length, g_soundList[sound].audioSpec.channels, -1, sep_sound_ended); + } + + lua_pushnumber(L, result); + return 1; +} + + + +static int sep_sprite_draw(lua_State *L) +{ + int n = lua_gettop(L); + + if (n == 3) + if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) + if (lua_isnumber(L, 3)) + { + int sprite = lua_tonumber(L, 3); + if (sprite < (int)g_spriteList.size()) + { + SDL_Rect dest; + dest.x = lua_tonumber(L, 1); + dest.y = lua_tonumber(L, 2); + dest.w = g_spriteList[sprite]->w; + dest.h = g_spriteList[sprite]->h; + SDL_BlitSurface(g_spriteList[sprite], NULL, g_se_surface, &dest); + + } + } + + return 0; +} + +static int sep_sprite_height(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sprite = lua_tonumber(L, 1); + if ((sprite < (int)g_spriteList.size()) && (sprite >= 0)) + { + result = g_spriteList[sprite]->h; + } + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_sprite_load(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isstring(L, 1)) + { + const char *sprite = lua_tostring(L, 1); + SDL_Surface *temp = IMG_Load(sprite); + + if (temp != NULL) + { + // by RDG: If the PNG has transparent areas then set + // the appropriate alpha channel implementation. + if (temp->format->Amask != 0) + SDL_SetAlpha(temp, SDL_SRCALPHA|SDL_RLEACCEL, SDL_ALPHA_TRANSPARENT); + else + SDL_SetAlpha(temp, SDL_RLEACCEL, 0); + + g_spriteList.push_back(temp); + result = g_spriteList.size() - 1; + + } else + sep_die("Unable to load sprite %s!", sprite); + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_sprite_width(lua_State *L) +{ + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sprite = lua_tonumber(L, 1); + if ((sprite < (int)g_spriteList.size()) && (sprite >= 0)) + { + result = g_spriteList[sprite]->w; + } + } + + lua_pushnumber(L, result); + return 1; +} + +static int sep_step_backward(lua_State *L) +{ + g_pSingeIn->pre_step_backward(); + return 0; +} + +static int sep_step_forward(lua_State *L) +{ + g_pSingeIn->pre_step_forward(); + return 0; +} + +static int sep_stop(lua_State *L) +{ + g_pSingeIn->pre_stop(); + + return 0; +} + +// by RDG2010 +static int sep_keyboard_set_mode(lua_State *L) +{ + + /* + * Singe can scan keyboard input in two ways: + * + * MODE_NORMAL - Singe will only check for keys defined + * in daphne.ini. This is the default behavior. + * + * MODE_FULL - Singe will scan the keyboard for most keypresses. + * + * This function allows the mode to be set through a lua scrip command. + * Take a look at singe::set_keyboard_mode on singe.cpp for more info. + * + */ + + int n = lua_gettop(L); + int q = 0; + + if (n == 1) + { + if (lua_isnumber(L, 1)) + { + q = lua_tonumber(L, 1); + g_pSingeIn->dll_side_set_keyboard_mode(g_pSingeIn->pSingeInstance, q); + + } + } + return 0; +} + +// by RDG2010 +static int sep_keyboard_get_mode(lua_State *L) +{ + /* + * Singe can scan keyboard input in two ways: + * + * MODE_NORMAL - Singe will only check for keys defined + * in daphne.ini. This is the default behavior. + * + * MODE_FULL - Singe will scan the keyboard for most keypresses. + * + * This function returns the current scan mode for + * programming code on the lua script. + * + * Take a look at singe::get_keyboard_mode on singe.cpp for more info. + * + */ + + lua_pushnumber(L, g_pSingeIn->dll_side_get_keyboard_mode(g_pSingeIn->pSingeInstance)); + return 1; +} + +// by RDG2010 +static int sep_singe_quit(lua_State *L) +{ + /* + * This function allows a programmer to end program execution + * through a simple command in the lua script. + * + * Useful for cases where the game design calls for + * an 'Exit' option in a user menu. + * + */ + + sep_die("User decided to quit early."); + return 0; +} +// by RDG2010 +static int sep_get_vldp_state(lua_State *L) +{ + + /* + * Returns the status of the vldp + * Values returned are + * based on the following enumeration (found in ldp.h). + * + * LDP_ERROR = 0 + * LDP_SEARCHING = 1 + * LDP_STOPPED = 2 + * LDP_PLAYING = 3 + * LDP_PAUSE = 4 + * + */ + + lua_pushnumber(L, g_pSingeIn->get_vldp_status()); + return 1; + +} + +// by RDG2010 +static int sep_get_pause_flag(lua_State *L) +{ + /* + * This function returns g_pause_state's value to the lua script. + * + * Sometimes game logic pauses the game (which implies pausing video playback). + * When implementing a pause state it is possible for the player + * to resume playblack at moments where the game is not intended to. + * Boolean g_pause state is an internal variable that keeps track + * of this. It's set to true whenever sep_pre_pause is called. + * It's set to false whenever sep_pre_play or sep_skip_to_frame is called. + * + * A lua programmer can use this to prevent resuming playback accidentally. + */ + lua_pushboolean(L, g_pause_state); + return 1; + +} +// by RDG2010 +static int sep_set_pause_flag(lua_State *L) +{ + int n = lua_gettop(L); + bool b1 = false; + + if (n == 1) + { + if (lua_isboolean(L, 1)) + { + b1 = lua_toboolean(L, 1); + g_pause_state = b1; + + } + } + return 0; +} +// by RDG2010 +static int sep_singe_version(lua_State *L) +{ + /* + * Returns Singe engine version to the lua script. + * For validation purposes. + * + */ + + lua_pushnumber(L, g_pSingeIn->get_singe_version()); + return 1; + +} +// by RDG2010 +static int sep_ldp_verbose(lua_State *L) +{ + /* + * Enables/Disables writing of VLDP playback activity to daphne_log.txt + * Enabled by default. + */ + + int n = lua_gettop(L); + bool b1 = false; + + if (n == 1) + { + if (lua_isboolean(L, 1)) + { + b1 = lua_toboolean(L, 1); + g_pSingeIn->set_ldp_verbose(b1); + + } + } + + return 0; +} +// by RDG2010 +static int sep_sound_pause(lua_State *L) +{ +// Instructs Daphne to pause a given sample from playing. +// User must feed the sound handle on the lua side. +// e.g. lua code, +// +// thisHandle = soundPlay(mySound) +// soundPause(thisHandle) +// +// Function returns true if sample was paused, false otherwise. +// +// --rdg + + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sound = lua_tonumber(L, 1); + result = g_pSingeIn->samples_set_state(sound, false); + } + + lua_pushboolean(L, result); + return 1; +} +// by RDG2010 +static int sep_sound_resume(lua_State *L) +{ +// Instructs Daphne to unpause a sound that was previously paused. +// User must feed the sound handle on the lua side. +// e.g. lua code, +// +// thisHandle = soundPlay(mySound) +// soundPause(thisHandle) +// soundResume(thisHandle) +// +// Function returns true if sample was unpaused, false otherwise. +// +// --rdg + + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sound = lua_tonumber(L, 1); + result = g_pSingeIn->samples_set_state(sound, true); + } + + lua_pushboolean(L, result); + return 1; +} +// by RDG2010 +static int sep_sound_stop(lua_State *L) +{ +// Instructs Daphne to end a sound early. +// User must feed the sound handle on the lua side. +// e.g. lua code, +// +// thisHandle = soundPlay(mySound) +// soundStop(thisHandle) +// +// Function returns true if sample was stopped, false otherwise. +// NOTE: thisHandle will be invalidated as a result of this function. +// Lua doesn't do variables by reference, so it is +// up to the user to keep track of sound handles on the lua script. +// +// --rdg + + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sound = lua_tonumber(L, 1); + result = g_pSingeIn->samples_end_early(sound); + } + + lua_pushboolean(L, result); + return 1; +} +// by RDG2010 +static int sep_sound_flush_queue(lua_State *L) +{ +// Clears the audio queue of any samples actively playing. +// No parameters needed. Function returns nothing. +// e.g. lua code, +// +// soundFullStop() +// + + g_pSingeIn->samples_flush_queue(); + return 0; +} +// by RDG2010 +static int sep_sound_get_flag(lua_State *L) +{ +// Checks to see if a certain sound has finished playing. +// User must feed the sound handle on the lua side. +// e.g. lua code, +// +// thisHandle = soundPlay(mySound) +// if (soundIsPlaying(thisSound)) then do something ... end +// +// Function returns true if sample is still playing, false otherwise. +// +// --rdg + + int n = lua_gettop(L); + bool result = false; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + int sound = lua_tonumber(L, 1); + result = g_pSingeIn->samples_is_sample_playing(sound); + } + + lua_pushboolean(L, result); + return 1; +} +// by RDG2010 +static int sep_sound_set_volume(lua_State *L) +{ +// Allows manipulation of sample volume. +// Valid values range from 0 to 63 +// e.g. lua code, +// +// soundSetVolume(32) +// +// Function returns nothing. +// +// --rdg + + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + unsigned int thisValue = (unsigned int) lua_tonumber(L, 1); + if (thisValue >= 0 && thisValue < AUDIO_MAX_VOLUME) + g_pSingeIn->set_soundchip_nonvldp_volume(thisValue); + else + sep_print("Script Error! Invalid sound volume value."); + } + + lua_pushboolean(L, result); + return 0; +} +// by RDG2010 +static int sep_sound_get_volume(lua_State *L) +{ +// Returns the current sample volume value. +// e.g. lua code, +// +// local iVolume = soundGetVolume() +// +// Function returns an integer value ranging from 0 to 63. +// +// --rdg + + int vol = g_pSingeIn->get_soundchip_nonvldp_volume(); + if (vol > 0) vol--; // why this line? AUDIO_MAX_VOLUME starts counting at zero. + lua_pushnumber(L, vol); + return 1; +} +// by RDG2010 +static int sep_set_game_name(lua_State *L) +{ +// Adds the name of the singe game to the window's title bar. +// Valid value is a string no longer than 25 characters. +// e.g. lua code, +// +// singeSetGameName("My FMV game") +// +// Function returns nothing. +// +// --rdg + + int n = lua_gettop(L); + int result = -1; + + if (n == 1) + if (lua_isstring(L, 1)) + { + char thisName[MAX_TITLE_LENGTH]; + //sprintf(thisName,"%.27s",lua_tostring(L, 1)); // Need a better way to do this... + sprintf(thisName,"%.40s",lua_tostring(L, 1)); // Need a better way to do this... + g_pSingeIn->dll_side_set_caption(g_pSingeIn->pSingeInstance, thisName); + } + + lua_pushboolean(L, result); + return 0; +} + +static int sep_get_script_path(lua_State *L) +{ +// Returns the path to the singe script. +// e.g. lua code, +// +// sGameDirectory = singeGetScriptPath() +// + + + char s1[255]; + g_pSingeIn->dll_side_get_script_path(g_pSingeIn->pSingeInstance, s1); + lua_pushstring(L, s1); + + return 1; + +} + +static int sep_mouse_enable(lua_State *L) +{ +// Disables mouse monitoring + g_pSingeIn->dll_side_mouse_enable(g_pSingeIn->pSingeInstance); + return 0; +} + +static int sep_mouse_disable(lua_State *L) +{ + g_pSingeIn->dll_side_mouse_disable(g_pSingeIn->pSingeInstance); + return 0; +} + +static int sep_mouse_get_how_many(lua_State *L) +{ + int mouse_total = g_pSingeIn->dll_side_mouse_get_how_many(g_pSingeIn->pSingeInstance); + lua_pushnumber(L, mouse_total); + return 1; +} + +static int sep_pause_enable(lua_State *L) +{ +// Disables mouse monitoring + g_pSingeIn->dll_side_pause_enable(g_pSingeIn->pSingeInstance); + return 0; +} + +static int sep_pause_disable(lua_State *L) +{ + g_pSingeIn->dll_side_pause_disable(g_pSingeIn->pSingeInstance); + return 0; +} + +static int sep_mouse_set_mode(lua_State *L) +{ +// Sets the scanning mode for mouse input. +// Can be one of two values: +// +// SINGLE_MOUSE = 100 +// MANY_MOUSE = 200 +// +// Be sure to add these constant declarations to your framework.singe +// By default Singe starts in single mouse mode. +// Use this command if you need to scan multiple mice. +// e.g. lua code, +// +// mouseSetMode(MANY_MOUSE) +// +// Function returns TRUE is mode set was successful, FALSE otherwise. +// +// --rdg + + int n = lua_gettop(L); + int thisValue = 0; + bool result = false; + + if (n == 1) + if (lua_isnumber(L, 1)) + { + thisValue = lua_tonumber(L, 1); + result = g_pSingeIn->dll_side_set_mouse_mode(thisValue); + if (!result) sep_print("mouseSetMode failed. Is mouse enabled?"); + + } + lua_pushboolean(L, result); + return 1; + +} + + \ No newline at end of file diff --git a/game/singe/singeproxy.h b/game/singe/singeproxy.h new file mode 100644 index 000000000..3e6943f3c --- /dev/null +++ b/game/singe/singeproxy.h @@ -0,0 +1,139 @@ +/* + * singeproxy.h + * + * Copyright (C) 2006 Scott C. Duensing + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include +#include +#include + +#include "../../vldp2/vldp/vldp.h" // to get the vldp structs +#include "../../sound/sound.h" // to get the sound structs - rdg + +// by RDG2010 +// Ubuntu Linux complains if SDL includes are used with quotes. +#ifdef WIN32 +#include "SDL_image.h" +#include "SDL_ttf.h" +#else +#include +#include +#endif + +// since lua is written in C, we need to specify that all functions are C-styled +extern "C" +{ +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} + +//////////////////////////////////////////////////////////////////////////////// + +unsigned char sep_byte_clip(int value); +void sep_call_lua(const char *func, const char *sig, ...); +void sep_capture_vldp(); +void sep_die(const char *fmt, ...); +void sep_do_blit(SDL_Surface *srfDest); +void sep_do_mouse_move(Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel, Uint16 mouseID); +void sep_error(const char *fmt, ...); +int sep_lua_error(lua_State *L); +int sep_prepare_frame_callback(struct yuv_buf *src); +void sep_print(const char *fmt, ...); +void sep_release_vldp(); +void sep_set_static_pointers(double *m_disc_fps, unsigned int *m_uDiscFPKS); +void sep_set_surface(int width, int height); +void sep_shutdown(void); +void sep_sound_ended(Uint8 *buffer, unsigned int slot); +bool sep_srf32_to_srf8(SDL_Surface *src, SDL_Surface *dst); +bool sep_blit_g_screen(SDL_Surface *src, SDL_Surface *dst);//rdg +void sep_startup(const char *script); +void sep_unload_fonts(void); +void sep_unload_sounds(void); +void sep_unload_sprites(void); + +//////////////////////////////////////////////////////////////////////////////// + +// Singe API Calls + +static int sep_audio_control(lua_State *L); +static int sep_change_speed(lua_State *L); +static int sep_color_set_backcolor(lua_State *L); +static int sep_color_set_forecolor(lua_State *L); +static int sep_daphne_get_height(lua_State *L); +static int sep_daphne_get_width(lua_State *L); +static int sep_debug_say(lua_State *L); +static int sep_font_load(lua_State *L); +static int sep_font_quality(lua_State *L); +static int sep_font_select(lua_State *L); +static int sep_font_sprite(lua_State *L); +static int sep_get_current_frame(lua_State *L); +static int sep_get_overlay_height(lua_State *L); +static int sep_get_overlay_width(lua_State *L); +static int sep_mpeg_get_height(lua_State *L); +static int sep_mpeg_get_pixel(lua_State *L); +static int sep_mpeg_get_width(lua_State *L); +static int sep_overlay_clear(lua_State *L); +static int sep_pause(lua_State *L); +static int sep_play(lua_State *L); +static int sep_say(lua_State *L); +static int sep_say_font(lua_State *L); +static int sep_screenshot(lua_State *L); +static int sep_search(lua_State *L); +static int sep_search_blanking(lua_State *L); +static int sep_set_disc_fps(lua_State *L); +static int sep_skip_backward(lua_State *L); +static int sep_skip_blanking(lua_State *L); +static int sep_sound_load(lua_State *L); +static int sep_sound_play(lua_State *L); +static int sep_sprite_draw(lua_State *L); +static int sep_sprite_height(lua_State *L); +static int sep_sprite_load(lua_State *L); +static int sep_sprite_width(lua_State *L); +static int sep_skip_forward(lua_State *L); +static int sep_skip_to_frame(lua_State *L); +static int sep_step_backward(lua_State *L); +static int sep_step_forward(lua_State *L); +static int sep_stop(lua_State *L); +// by RDG2010 +static int sep_keyboard_set_mode(lua_State *L); +static int sep_keyboard_get_mode(lua_State *L); +static int sep_singe_quit(lua_State *L); +static int sep_get_vldp_state(lua_State *L); +static int sep_get_pause_flag(lua_State *L); +static int sep_set_pause_flag(lua_State *L); +static int sep_singe_version(lua_State *L); +static int sep_ldp_verbose(lua_State *L); +static int sep_sound_pause(lua_State *L); +static int sep_sound_resume(lua_State *L); +static int sep_sound_get_flag(lua_State *L); +static int sep_sound_stop(lua_State *L); +static int sep_sound_set_volume(lua_State *L); +static int sep_sound_get_volume(lua_State *L); +static int sep_sound_flush_queue(lua_State *L); +static int sep_set_game_name(lua_State *L); +static int sep_get_script_path(lua_State *L); +static int sep_mouse_enable(lua_State *L); +static int sep_mouse_disable(lua_State *L); +static int sep_mouse_get_how_many(lua_State *L); +static int sep_skip_and_pause(lua_State *L); +static int sep_pause_enable(lua_State *L); +static int sep_pause_disable(lua_State *L); +static int sep_mouse_set_mode(lua_State *L); diff --git a/globals.h b/globals.h new file mode 100644 index 000000000..993a03824 --- /dev/null +++ b/globals.h @@ -0,0 +1,55 @@ +/* + * globals.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GLOBALS_H +#define GLOBALS_H + +// Some global data is stored here +// *** Try to avoid using globals if possible!!!!! *** + +game *g_game = NULL; // pointer to the game class that emulator will use + +ldp *g_ldp = NULL; // pointer to the ldp class that emulator will use + +Uint8 quitflag = 0; // 1 = we are ready to quit the program + +Uint8 serial_port = 0; // which serial port to use to control LDP +int baud_rate = 9600; // which baud rate they want the serial port to function at +int search_offset = 0; // Value to add to every frame we search for (0 unless we have a PAL Dragon's Lair disc and the NTSC roms) + // PAL disc starts at frame 1, NTSC disc starts at frame 153. So the search_offset for PAL would + // be -152 + +Uint8 frame_modifier = 0; // what type of frame modifications to be used + // the types of modifications possible are enumerated, and they + // includ Space Ace 91 and PAL + +Uint8 joystick_detected = 0; // 0 = no joystick, 1 = joystick present + +Uint8 realscoreboard = 0; // 1 = external scoreboard is attached +unsigned int rsb_port = 0; // 0 = LPT1, 1 = LPT2 or address of real scoreboard + +unsigned int idleexit; // added by JFA for -idleexit +unsigned char startsilent = 0; + + + +#endif diff --git a/io/Makefile b/io/Makefile new file mode 100644 index 000000000..9f92e3989 --- /dev/null +++ b/io/Makefile @@ -0,0 +1,23 @@ +# sub Makefile for IO folder + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = input.o conout.o cmdline.o conin.o error.o \ + network.o fileparse.o unzip.o mpo_fileio.o numstr.o homedir.o \ + logger.o logger_console.o logger_factory.o + +.SUFFIXES: .cpp + +all: ${OBJS} + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +clean: + rm -f ${OBJS} *.d + diff --git a/io/cmdline.cpp b/io/cmdline.cpp new file mode 100644 index 000000000..294de183d --- /dev/null +++ b/io/cmdline.cpp @@ -0,0 +1,792 @@ +/* + * cmdline.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// Parses our command line and sets our variables accordingly +// by Matt Ownby + +#include +#include +#include +#include "cmdline.h" +#include "conout.h" +//#include "network.h" +#include "numstr.h" +#include "homedir.h" +#include "input.h" // to disable joystick use +#include "../io/numstr.h" +#include "../video/video.h" +//#include "../video/led.h" +#include "../daphne.h" +//#include "../cpu/cpu-debug.h" // for set_cpu_trace +//#include "../game/lair.h" +//#include "../game/cliff.h" +#include "../game/game.h" +//#include "../game/superd.h" +//#include "../game/thayers.h" +//#include "../game/speedtest.h" +//#include "../game/seektest.h" +//#include "../game/releasetest.h" +//#include "../game/cputest.h" +//#include "../game/multicputest.h" +//#include "../game/firefox.h" +//#include "../game/ffr.h" +//#include "../game/astron.h" +//#include "../game/esh.h" +//#include "../game/laireuro.h" +//#include "../game/badlands.h" +//#include "../game/starrider.h" +//#include "../game/bega.h" +//#include "../game/cobraconv.h" +//#include "../game/gpworld.h" +//#include "../game/interstellar.h" +//#include "../game/benchmark.h" +//#include "../game/lair2.h" +//#include "../game/mach3.h" +//#include "../game/lgp.h" +//#include "../game/timetrav.h" + +#include "../game/singe.h" + +//#include "../game/test_sb.h" +#include "../ldp-out/ldp.h" +//#include "../ldp-out/sony.h" +//#include "../ldp-out/pioneer.h" +//#include "../ldp-out/ld-v6000.h" +//#include "../ldp-out/hitachi.h" +//#include "../ldp-out/philips.h" +//#include "../ldp-out/ldp-combo.h" +#include "../ldp-out/ldp-vldp.h" +#include "../ldp-out/framemod.h" + +#ifdef UNIX +#include // for unlink +#endif + +int g_argc = 0; +char **g_argv = NULL; +int g_arg_index = 0; + +// Win32 doesn't use strcasecmp, it uses stricmp (lame) +#ifdef WIN32 +#define strcasecmp stricmp +#endif + + +// parses the command line looking for the -homedir switch, returns true if found and valid (or not found) +// (this must be done first because the the game and ldp classes may rely on the homedir being set to its proper place) +bool parse_homedir() +{ + bool result = true; + char s[81] = { 0 }; + bool bHomeDirSet = false; // whether set_homedir was called + + for (;;) + { + get_next_word(s, sizeof(s)); + // if there is nothing left for us to parse, break out of the while loop + if (s[0] == 0) + { + break; + } + + // if they are defining an alternate 'home' directory. + // Primary used for OSX/linux to keep roms, framefiles and saverams in the user-writable space. + else if (strcasecmp(s, "-homedir")==0) + { + //Ignore this one, already handled + get_next_word(s, sizeof(s)); + if (s[0] == 0) + { + printline("Homedir switch used but no homedir specified!"); + result = false; + break; + } + else + { + g_homedir.set_homedir(s); + bHomeDirSet = true; + printline("Setting alternate home dir:"); + printline(s); + break; + } + } + } + + // if user didn't specify a homedir, then we have a default one. + // (the reason this isn't in the homedir constructor is that we don't want to create + // default directories in a default location if the user specifies his/her own homedir) + if (!bHomeDirSet) + { + +#ifdef UNIX +#ifndef MAC_OSX // Zaph doesn't seem to like this behavior and he is maintaining the Mac build, so... + // on unix, if the user doesn't specify a homedir, then we want to default to ~/.daphne + // to follow standard unix convention. +#ifndef GP2X // gp2x has no homedir as far as I can tell, easier to put everything in current dir + const char *homeenv = getenv("HOME"); + + // this is always expected to be non-NULL + if (homeenv != NULL) + { + string strHomeDir = homeenv; + strHomeDir += "/.daphne"; + g_homedir.set_homedir(strHomeDir); + } + // else we couldn't set the homedir, so just leave it as default +#endif // not GP2X +#endif // not MAC_OSX +#else // WIN32 + g_homedir.set_homedir("."); // for win32 set it to the current directory + // "." is already the default, + // so the the main purpose for this is to ensure that the ram and + // framefile directories are created + +#endif + } // end if homedir was not set + + //Reset arg index and return + g_arg_index = 1; + return result; +} + +// parses the game type from the command line and allocates g_game +// returns true if successful or false of failed +bool parse_game_type() +{ + bool result = true; + int iLen,k; + char s[81] = { 0 }; + + // first thing we need to get from the command line is the game type + get_next_word(s, sizeof(s)); + + iLen = strlen(s); + + if (iLen < 6) + { + result = false; + printline("Command line error: first parameter is too short to be a script."); + printline("Make sure your script file is the first parameter in your command line."); + } + + if (result) + { + for(k=0;k(g_game); + result = cur_singe->handle_cmdline_arg(s1.c_str()); + if (result) cur_singe->set_script_path(s1.c_str()); + } + + } + + return(result); +} + +bool get_framefile_from_name(const char *s) +{ + bool result = true; + string s1(s); + string sFilename; + + size_t found; + found=s1.find_last_of("/\\"); + sFilename = s1; + found=sFilename.find_last_of("."); + sFilename.erase(found+1,5); + sFilename.append("txt"); + + ldp_vldp *cur_ldp = dynamic_cast(g_ldp); // see if the currently selected LDP is VLDP + // if it is a vldp, then this option has meaning and we can use it + if (cur_ldp) + { + cur_ldp->set_framefile(sFilename.c_str()); + } + + return(result); + +} + +// parses the LDP type from the command line and allocates g_ldp +// returns true if successful or false if failed +bool parse_ldp_type() +{ + bool result = true; + char s[81] = { 0 }; + + get_next_word(s, sizeof(s)); + +// net_set_ldpname(s); // report to server which ldp we are using + + if (strcasecmp(s, "fast_noldp")==0) + { + g_ldp = new fast_noldp(); // 'no seek-delay' version of noldp + } + else if (strcasecmp(s, "noldp")==0) + { + g_ldp = new ldp(); // generic interface + } + else if (strcasecmp(s, "vldp")==0) + { + g_ldp = new ldp_vldp(); + } + else + { + printline("ERROR: Unknown laserdisc player type specified"); + result = false; + } + + // safety check + if (!g_ldp) + { + result = false; + } + + return(result); +} + +// parses command line +// Returns 1 on success or 0 on failure +bool parse_cmd_line(int argc, char **argv) +{ + bool result = true; + char s[320] = { 0 }; // in case they pass in a huge directory as part of the framefile + int i = 0; + bool log_was_disabled = false; // if we actually get "-nolog" while going through arguments + + ////////////////////////////////////////////////////////////////////////////////////// + + g_argc = argc; + g_argv = argv; + g_arg_index = 1; // skip name of executable from command line + g_game = new singe(); + g_ldp = new ldp_vldp(); + + // if game and ldp types are correct + //if (parse_homedir() && parse_game_type() && parse_ldp_type()) + if (parse_homedir() && parse_game_type()) + { + // while we have stuff left in the command line to parse + for (;;) + { + get_next_word(s, sizeof(s)); + + // if there is nothing left for us to parse, break out of the while loop + if (s[0] == 0) + { + break; + } + + // if they are defining an alternate 'home' directory. + // Primary used for OSX/linux to keep roms, framefiles and saverams in the user-writable space. + else if (strcasecmp(s, "-homedir")==0) + { + //Ignore this one, already handled + get_next_word(s, sizeof(s)); + } + + // If they are defining an alternate 'data' directory, where all other files aside from the executable live. + // Primary used for linux to separate binary file (eg. daphne.bin) and other datafiles . + else if (strcasecmp(s, "-datadir")==0) + { + get_next_word(s, sizeof(s)); + change_dir(s); + } + + // if user wants laserdisc player to blank video while searching (VLDP only) + /* + else if (strcasecmp(s, "-blank_searches")==0) + { + g_ldp->set_search_blanking(true); + } + */ + // if user wants to laserdisc player to blank video while skipping (VLDP only) + else if (strcasecmp(s, "-blank_skips")==0) + { + g_ldp->set_skip_blanking(true); + } + + // if they are pointing to a framefile to be used by VLDP + else if (strcasecmp(s, "-framefile")==0) + { + ldp_vldp *cur_ldp = dynamic_cast(g_ldp); // see if the currently selected LDP is VLDP + get_next_word(s, sizeof(s)); + // if it is a vldp, then this option has meaning and we can use it + if (cur_ldp) + { + cur_ldp->set_framefile(s); + } + else + { + printline("You can only set a framefile using VLDP as your laserdisc player!"); + result = false; + } + } + + // if they are defining an alternate soundtrack to be used by VLDP + else if (strcasecmp(s, "-altaudio")==0) + { + ldp_vldp *cur_ldp = dynamic_cast(g_ldp); // see if the currently selected LDP is VLDP + get_next_word(s, sizeof(s)); + // if it is a vldp, then this option has meaning and we can use it + if (cur_ldp) + { + cur_ldp->set_altaudio(s); + } + else + { + printline("You can only set an alternate soundtrack when using VLDP as your laserdisc player!"); + result = false; + } + } + + // The # of frames that we can seek per millisecond (to simulate seek delay) + // Typical values for real laserdisc players are about 30.0 for 29.97fps discs + // and 20.0 for 23.976fps discs (dragon's lair and space ace) + // FLOATING POINT VALUES ARE ALLOWED HERE + // Minimum value is 12.0 (5 seconds for 60,000 frames), maximum value is + // 600.0 (100 milliseconds for 60,000 frames). If you want a value higher than + // the max, you should just use 0 (as fast as possible). + // 0 = disabled (seek as fast as possible) + // + // Not for SINGE use + /* + else if (strcasecmp(s, "-seek_frames_per_ms")==0) + { + get_next_word(s, sizeof(s)); + double d = numstr::ToDouble(s); + + // WARNING : VLDP will timeout if it hasn't received a response after + // a certain period of time (7.5 seconds at this moment) so you will + // cause problems by reducing the minimum value much below 12.0 + if ((d > 12.0) && (d < 600.0)) g_ldp->set_seek_frames_per_ms(d); + else printline("NOTE : Max seek delay disabled"); + } + */ + // the minimum amount of milliseconds to force a seek to take (artificial delay) + // 0 = disabled + // Not for SINGE use + /* + else if (strcasecmp(s, "-min_seek_delay")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + + if ((i > 0) && (i < 5000)) g_ldp->set_min_seek_delay((unsigned int) i); + else printline("NOTE : Min seek delay disabled"); + } + */ + // if the user wants the searching to be the old blocking style instead of non-blocking + else if (strcasecmp(s, "-blocking")==0) + { + g_ldp->set_use_nonblocking_searching(false); + } + + // to disable any existing joysticks that may be plugged in that may interfere with input + else if ((strcasecmp(s, "-nojoystick")==0) || (strcasecmp(s, "-nojoy")==0)) + { + set_use_joystick(false); + } + else if ((strcasecmp(s,"-nomouse")==0) || (strcasecmp(s,"-disablemouse")==0)) + { + g_game->set_mouse_enabled(false); + printline("Not tracking mouse input for this game session."); + } + + // if they are paranoid and don't want data sent to the server + // (don't be paranoid, read the source code, nothing bad is going on) + /* + else if (strcasecmp(s, "-noserversend")==0) + { + //net_no_server_send(); + } + */ + else if ((strcasecmp(s, "-nosound")==0) || (strcasecmp(s, "-mutesound")==0)) + { + set_sound_enabled_status(false); + printline("Disabling sound..."); + } + else if (strcasecmp(s, "-sound_buffer")==0) + { + get_next_word(s, sizeof(s)); + Uint16 sbsize = (Uint16) atoi(s); + set_soundbuf_size(sbsize); + sprintf(s, "Setting sound buffer size to %d", sbsize); + printline(s); + } + else if (strcasecmp(s, "-volume_vldp")==0) + { + get_next_word(s, sizeof(s)); + unsigned int uVolume = atoi(s); + set_soundchip_vldp_volume(uVolume); + } + else if (strcasecmp(s, "-volume_nonvldp")==0) + { + get_next_word(s, sizeof(s)); + unsigned int uVolume = atoi(s); + set_soundchip_nonvldp_volume(uVolume); + } + else if (strcasecmp(s, "-nocrc")==0) + { + g_game->disable_crc(); + printline("Disabling ROM CRC check..."); + } + // Not for SINGE use + /* + else if (strcasecmp(s, "-scoreboard")==0) + { + set_scoreboard(1); + printline("Enabling external scoreboard..."); + } + else if (strcasecmp(s, "-scoreport")==0) + { + get_next_word(s, sizeof(s)); + set_scoreboard_port((unsigned int)numstr::ToUint32(s, 16)); + sprintf(s, "Setting scoreboard port to %d", i); + printline(s); + } + else if (strcasecmp(s, "-port")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + set_serial_port((unsigned char) i); + sprintf(s, "Setting serial port to %d", i); + printline(s); + } + else if (strcasecmp(s, "-baud")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + set_baud_rate(i); + sprintf(s, "Setting baud rate to %d", i); + printline(s); + } + + // used to modify the dip switch settings of the game in question + else if (strcasecmp(s, "-bank")==0) + { + get_next_word(s, sizeof(s)); + i = s[0] - '0'; // bank to modify. We convert to a number this way to catch more errors + + get_next_word(s, sizeof(s)); + unsigned char value = (unsigned char) (strtol(s, NULL, 2)); // value to be set is in base 2 (binary) + + result = g_game->set_bank((unsigned char) i, (unsigned char) value); + } + + else if (strcasecmp(s, "-latency")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + + // safety check + if (i >= 0) + { + g_ldp->set_search_latency(i); + sprintf(s, "Setting Search Latency to %d milliseconds", i); + printline(s); + } + else + { + printline("Search Latency value cannot be negative!"); + result = false; + } + } + else if (strcasecmp(s, "-cheat")==0) + { + g_game->enable_cheat(); // enable any cheat we have available :) + } + + // enable keyboard LEDs for use with games such as Space Ace + else if (strcasecmp(s, "-enable_leds")==0) + { + enable_leds(true); + } + // hacks roms for certain games such as DL, SA, and CH to bypass slow boot process + else if (strcasecmp(s, "-fastboot")==0) + { + g_game->set_fastboot(true); + } + */ + // stretch video vertically by x amount (a value of 24 removes letterboxing effect in Cliffhanger) + else if (strcasecmp(s, "-vertical_stretch")==0) + { + ldp_vldp *the_ldp = dynamic_cast(g_ldp); + + get_next_word(s, sizeof(s)); + i = atoi(s); + if (the_ldp != NULL) + { + the_ldp->set_vertical_stretch(i); + } + else + { + printline("Vertical stretch only works with VLDP."); + result = false; + } + } + + // don't force 4:3 aspect ratio regardless of window size + else if (strcasecmp(s, "-ignore_aspect_ratio")==0) + { + set_force_aspect_ratio(false); + } + + // run daphne in fullscreen mode + else if (strcasecmp(s, "-fullscreen")==0) + { + set_fullscreen(true); + } + + // disable log file + else if (strcasecmp(s, "-nolog")==0) + { + log_was_disabled = true; + } + + // disable YUV hardware acceleration + else if (strcasecmp(s, "-nohwaccel")==0) + { + set_yuv_hwaccel(false); + } + + // by RDG2010 + // Preliminary light gun support. + // Creates a borderless, no title bar window the size of the desktop + // and positions it accordingly so that it covers the whole screen. + else if (strcasecmp(s, "-fullscreen_window")==0) + { + set_fakefullscreen(true); + + } + + // by RDG2010 + // Scales video image to something smaller than the window size. + // Helpful for users with overscan issues on arcade monitors or CRT TVs. + // Valid values are 50-100, where 50 means half the size of the + // window, 100 means the same size. + else if (strcasecmp(s, "-scalefactor")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + sprintf(s, "Scaling image by %d%%", i); + printline(s); + set_scalefactor((Uint16)i); + } + +#ifdef USE_OPENGL + else if (strcasecmp(s, "-opengl")==0) + { + set_use_opengl(true); + + } +#endif // USE_OPENGL + + else if (strcasecmp(s, "-preset")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + g_game->set_preset(i); + } + else if (strcasecmp(s, "-rotate")==0) + { + get_next_word(s, sizeof(s)); + float f = (float) numstr::ToDouble(s); + set_rotate_degrees(f); + } + + // continuously updates SRAM (after every seek) + // ensures sram is saved even if Daphne is terminated improperly + // Not for SINGE use + /* + else if (strcasecmp(s, "-sram_continuous_update")==0) + { + g_ldp->set_sram_continuous_update(true); + } + + else if (strcasecmp(s, "-version")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + g_game->set_version(i); + } + */ + else if (strcasecmp(s, "-x")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + set_video_width((Uint16)i); + sprintf(s, "Setting screen width to %d", i); + printline(s); + } + else if (strcasecmp(s, "-y")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + set_video_height((Uint16)i); + sprintf(s, "Setting screen height to %d", i); + printline(s); + } + // Not for SINGE use + /* + else if (strcasecmp(s, "-trace")==0) + { +#ifdef CPU_DEBUG +// printline("CPU tracing enabled"); +// set_cpu_trace(1); +#else + printline("DAPHNE needs to be compiled in debug mode for this to work"); + result = false; +#endif + } + */ + // added by JFA for -idleexit + else if (strcasecmp(s, "-idleexit")==0) + { + get_next_word(s, sizeof(s)); + i = atoi(s); + set_idleexit(i*1000); + sprintf(s, "Setting idleexit to %d ", i); + printline(s); + } + // end edit + + // added by JFA for -startsilent + else if (strcasecmp(s, "-startsilent")==0) + { + set_startsilent(1); + printline("Starting silent..."); + } + // end edit + + // if they are requesting to stop the laserdisc when the program exits + else if (strcasecmp(s, "-stoponquit")==0) + { + g_ldp->set_stop_on_quit(true); + } + else if (strcasecmp(s, "-prefer_samples")==0) + { + // If a game doesn't support "prefer samples" then it is not an error. + // That's why it is _prefer_ samples instead of _require_ samples :) + g_game->set_prefer_samples(true); + } + + else if (strcasecmp(s, "-noissues")==0) + { + g_game->set_issues(NULL); + } + + // Scale the game overlay graphics to the virtual screen dimension + // this is needed when Daphne is used for overlaying game graphics over the real + // laserdisc movie (using a video genlock), and the screen dimension is different + // from the dimensions of the game. + else if (strcasecmp(s, "-fullscale")==0) + { + ldp_vldp *cur_ldp = dynamic_cast(g_ldp); // see if the currently selected LDP is VLDP + // if it is a vldp, then this option is not supported + if (cur_ldp) + { + printline("Full Scale mode only works with NOLDP."); + result = false; + } + else + { + g_game->SetFullScale(true); + } + } + + // check for any game-specific arguments ... + else if (g_game->handle_cmdline_arg(s)) + { + // don't do anything in here, it has already been handled by the game class ... + } + // check for any ldp-specific arguments ... + else if (g_ldp->handle_cmdline_arg(s)) + { + // don't do anything in here, it has already been handled by the ldp class ... + } + else + { + printline("Unknown command line parameter or parameter value:"); + printline(s); + result = false; + } + } // end for + } // end if we know our game type + + // if game or ldp was unknown + else + { + result = false; + } + + // if we didn't receive "-nolog" while parsing, then it's ok to enable the log file now. + if (!log_was_disabled) + { + // first we need to delete the old logfile so we can start fresh + // (this is the best place to do it since up until this point we don't know where our homedir is) + string logfile = g_homedir.get_homedir(); + logfile += "/"; + logfile += LOGNAME; + unlink(logfile.c_str()); // delete logfile if possible, because we're starting over + + set_log_enabled(true); + } + + return(result); +} + + +// copies a single word from the command line into result (a word is any group of characters separate on both sides by whitespace) +// if there are no more words to be copied, result will contain a null string +void get_next_word(char *result, int result_size) +{ + // make sure we still have command line left to parse + if (g_arg_index < g_argc) + { + strncpy(result, g_argv[g_arg_index], result_size); + result[result_size-1] = 0; // terminate end of string just in case we hit the limit + g_arg_index++; + + + } + + // if we have no command line left to parse ... + else + { + result[0] = 0; // return a null string + } +} diff --git a/io/cmdline.h b/io/cmdline.h new file mode 100644 index 000000000..797a35c1a --- /dev/null +++ b/io/cmdline.h @@ -0,0 +1,32 @@ +/* + * cmdline.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +// cmdline.h by Matt Ownby + +bool parse_game_type(); +bool parse_ldp_type(); +bool parse_cmd_line(int argc, char **argv); +void get_next_word(char *result, int result_size); +bool get_framefile_from_name(const char *); +bool switch_search(char *thisValue); + diff --git a/io/conin.cpp b/io/conin.cpp new file mode 100644 index 000000000..0d8bd191c --- /dev/null +++ b/io/conin.cpp @@ -0,0 +1,189 @@ +/* + * conin.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +// Routines to replace stdin routines such as 'gets' +// Purpose: So we can use the Z80 debugger with our GUI + +#include +#include "conout.h" +#include "conin.h" +#include "../daphne.h" +#include "input.h" + +#ifdef UNIX +#include +#endif + +// returns an ASCII character from the keyboard; will wait here forever until a key is pressed +// not all characters are supported +char con_getkey() +{ + + unsigned char result = 0; + SDL_Event event; + +#ifdef CPU_DEBUG + con_flush(); // print current line +#endif + + SDL_EnableUNICODE(1); + while (!result && !get_quitflag()) + { + if (SDL_PollEvent (&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_BACKSPACE: + result = 8; + break; + case SDLK_RETURN: + result = 13; + break; + case SDLK_ESCAPE: + result = 27; + break; + case SDLK_BACKQUOTE: +#ifdef CPU_DEBUG + toggle_console(); +#endif + result = 0; + break; + default: + result = (unsigned char) event.key.keysym.unicode; + break; + } + break; + //WO: make any joystick button = enter, + // so lazy folks (like me) can pass the issues screen + // without going to the keyboard :) + case SDL_JOYBUTTONDOWN: +#ifndef GP2X + result = 13; +#else + // one of the buttons needs to exit the emulator + switch(event.jbutton.button) + { + // L is #10, and it will map to escape for now ... + case 10: + result = 27; + break; + case 15: // Y (hide console) +#ifdef CPU_DEBUG + toggle_console(); +#endif + result = 0; + break; + default: + result = 13; + break; + } + break; +#endif + break; + case SDL_QUIT: + set_quitflag(); + break; + default: + break; + } + } // end if + + check_console_refresh(); + SDL_Delay(1); // sleep to be CPU friendly + +#ifdef UNIX + // NOTE : non-blocking I/O should be enabled, so we will get EOF if there is nothing waiting for us ... + int iRes = getchar(); + if (iRes != EOF) + { + result = (unsigned char) iRes; + } +#endif + + + } // end while + SDL_EnableUNICODE(0); + + + return(result); +} + + +// returns a null-terminated string from "stdin"; if there was an error, an empty string will be returned +// NOTE: the string is echoed to the screen as the user types it in +// 'length' is the maximum size of 'buf' + +void con_getline(char *buf, int length) + +{ + + int index = 0; + char ch = 0; + + // loop until we encounter a linefeed or carriage return, or until we run out of space + while (!get_quitflag()) + { + ch = con_getkey(); + + // if we get a linefeed or carriage return, we're done ... + if ((ch == 10) || (ch == 13)) + { + break; + } + + // backspace, it works but it doesn't look pretty on the screen + else if (ch == 8) + { + if (index >0) + { + index = index - 1; + outstr("[BACK]"); + } + } + + // if we've run out of space, terminate the string prematurely to avoid crashing + + else if (index >= (length - 1)) + { + break; + } + + // otherwise if we get a printable character, add it to the string + else if (ch >= ' ') + { + + outchr(ch); // echo it to the screen + buf[index] = ch; + index = index + 1; + } + + // else it was a non-printable character, so we ignore it + } + + buf[index] = 0; // terminate the string + newline(); // go to the next line + +} diff --git a/io/conin.h b/io/conin.h new file mode 100644 index 000000000..380dc7d32 --- /dev/null +++ b/io/conin.h @@ -0,0 +1,26 @@ +/* + * conin.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// header file for conin.cpp + +char con_getkey(); +void con_getline(char *buf, int length); diff --git a/io/conout.cpp b/io/conout.cpp new file mode 100644 index 000000000..159bfc2d5 --- /dev/null +++ b/io/conout.cpp @@ -0,0 +1,230 @@ +/* + * conout.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// CONOUT +// Provides console functionality in a window (replacement for printf, cout, etc) + +#include +#include +#include +#include +#include +#include "conout.h" +#include "../daphne.h" +#include "../video/video.h" +#include "../video/SDL_Console.h" +#include "../timer/timer.h" +#include "input.h" +#include "mpo_fileio.h" +#include "homedir.h" + +using namespace std; + +char G_curline[CHARS_PER_LINE] = { 0 }; // current line of output + +// false = write log entries to g_lsPendingLog, true = write to daphne_log.txt +// This should be false until the command line has finished parsing. +bool g_log_enabled = false; + +// used so log can store text until we've been given the green light to write to the log file +// (using a list because it is faster than a vector) +list g_lsPendingLog; + +// Prints a "c string" to the screen +// Returns 1 on success, 0 on failure +void outstr(const char *s) +{ +// the console consumes quite a bit of cpu, so we don't want to have +// it enabled by default +#ifdef CPU_DEBUG + if (get_console_initialized()) + { + if (strlen(s) + strlen(G_curline) < CHARS_PER_LINE) + { + strcat(G_curline,s); + } + } +#endif +#ifdef UNIX + fputs(s, stdout); +#endif + + addlog(s); // add to our logfile +} + +// Prints a single character to the screen +// Returns 1 on success, 0 on failure +void outchr(const char ch) +{ + char s[2] = { 0 }; + + // the SDL_console output library uses vsprintf so % signs mess it up + if (ch != '%') + { + s[0] = ch; + s[1] = 0; + } + + outstr(s); +} + +// prints a null-terminated string to the screen +// and adds a line feed +// 1 = success +void printline(const char *s) +{ + outstr(s); + newline(); +} + +// moves to the next line without printing anything +void newline() +{ + + // Carriage return followed by line feed + // So we can read the blasted thing in notepad + static char newline_str[3] = { 13, 10, 0 }; + +#ifdef CPU_DEBUG + if (get_console_initialized()) + { + ConOut(G_curline); + G_curline[0] = 0; // erase line + } +#endif +#ifdef UNIX + printf("\n"); +#endif + + addlog(newline_str); + +} + +#ifdef CPU_DEBUG +// prints the current line even if we haven't hit a linefeed yet +void con_flush() +{ + ConOutstr(G_curline); +} +#endif + + +// flood-safe printline +// it only prints every second and anything else is thrown out +void noflood_printline(char *s) +{ + static unsigned int old_timer = 0; + + if (elapsed_ms_time(old_timer) > 1000) + { + printline(s); + old_timer = refresh_ms_time(); + } +} + +// This is a safe version of ITOA in that prevents buffer overflow, but if your buffer size is too small, +// you will get an incorrect result. +void safe_itoa(int num, char *a, int sizeof_a) +{ + int i = 0,j = 0, n = 0; + char c = 0; + + // safety check : size needs to be at least 3 to accomodate one number, a minus sign and a null character + if (sizeof_a > 2) + { + n = num; + + // if number is negative, reverse its sign to make the math consistent with positive numbers + if (num < 0) + { + n = -n; + } + + do + { + a[i++]=n % 10 + '0'; + n = n / 10; + } while ((n > 0) && (i < (sizeof_a - 2))); + // sizeof_a - 2 to leave room for a null terminating character and a possible minus sign + + // if number was negative, then add a minus sign + if (num < 0) a[i++]='-'; + + a[i] = 0; // terminate string + + // reverse string (we had to go in reverse order to do the calculation) + for (i=0,j=strlen(a)-1; i::iterator i = g_lsPendingLog.begin(); + i != g_lsPendingLog.end(); i++) + { + mpo_write((*i).c_str(), (*i).size(), NULL, io); + } + g_lsPendingLog.clear(); + } + mpo_write(s, strlen(s), NULL, io); + mpo_close(io); + } + // else directory is read-only so we will just ignore for now + else + { +#ifdef UNIX + printf("Cannot write to '%s', do you have write permissions?\n", logname.c_str()); +#endif + } + } + // else logging is disabled, so we have to store log entries to memory + else + { + g_lsPendingLog.push_back(s); // store to RAM for now ... + } +} diff --git a/io/conout.h b/io/conout.h new file mode 100644 index 000000000..7a54b1b7b --- /dev/null +++ b/io/conout.h @@ -0,0 +1,44 @@ +/* + * conout.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// Conout.h header +// By Matt Ownby + +#ifndef CONOUT_H +#define CONOUT_H + +#define LOGNAME "daphne_log.txt" // name of our logfile if we are using one + +void outstr(const char *s); +void outchr(const char ch); +void printline(const char *s); +void newline(); +void con_flush(); +void noflood_printline(char *s); +void safe_itoa(int num, char *a, int sizeof_a); + +// enables/disables log from being written to disk +void set_log_enabled(bool val); + +void addlog(const char *s); + +#endif diff --git a/io/dll.h b/io/dll.h new file mode 100644 index 000000000..19caebca8 --- /dev/null +++ b/io/dll.h @@ -0,0 +1,50 @@ +/* + * dll.h + * + * Copyright (C) 2002 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// dll.h +// by Matt Ownby + +// just has some macros to make DLL loading uniform across different OS's + +#ifdef WIN32 +#include // for DLL loading +#else +#include // for .so loading +// Mac OSX can get this from http://www.opendarwin.org/projects/dlcompat/ +#endif + +// macros for making the dynamic library code look cleaner +#ifdef WIN32 +#define M_LOAD_LIB(libname) LoadLibrary(#libname) +#define M_GET_SYM GetProcAddress +#define M_FREE_LIB FreeLibrary +#else +#define M_LOAD_LIB(libname) dlopen("lib" #libname ".so", RTLD_NOW) +#define M_GET_SYM dlsym +#define M_FREE_LIB dlclose +#endif + +#ifdef WIN32 +#define DLL_INSTANCE HINSTANCE +#else +#define DLL_INSTANCE void * +#endif diff --git a/io/error.cpp b/io/error.cpp new file mode 100644 index 000000000..f38c013ce --- /dev/null +++ b/io/error.cpp @@ -0,0 +1,154 @@ +/* + * error.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +// error.cpp +// daphne error handling + +#ifdef WIN32 +#include +#endif + +#include +#include +#include "../daphne.h" +#include "conout.h" +#include "conin.h" +#include "input.h" +#include "../game/game.h" +#include "../sound/sound.h" +#include "../video/video.h" +#include "../video/SDL_DrawText.h" + +#ifndef GP2X +//const char *instr = "Please read the daphne_log.txt file for more information"; +const char *instr = "Read daphne_log.txt for help"; +#else +const char *instr = "Read daphne_log.txt for help"; +#endif + +const char CRLF[3] = { 13, 10, 0 }; // carriage return / linefeed combo, for the addlog statements in this file + +// notifies the user of an error that has occurred +void printerror(const char *s) +{ +// SDL_Rect region = { 0, 180, get_video_width(), (Uint16)(get_video_height() >> 1) }; + + addlog(s); + addlog(CRLF); + + // if video has been initialized + // FIXME: if bmp hasn't been loaded this might blow up + if (get_console_initialized()) + { + SDL_Surface *srfScreen = get_screen_blitter(); + unsigned int uXOffset = 0; + + vid_blank(); // needed for opengl + + // only draw this graphic if our width is at least 640 (it can be smaller on handheld) + if (srfScreen->w >= 640) + { + uXOffset = 80; // shift to the right to compensate for graphic + draw_othergfx(B_DAPHNE_SAVEME, 0, 180); + } + + // make sure text is centered + SDLDrawText(s, srfScreen, FONT_SMALL, ((srfScreen->w >> 1) + uXOffset -((strlen(s) >> 1)*6)), (srfScreen->h >> 1)-13); + SDLDrawText(instr, srfScreen, FONT_SMALL, ((srfScreen->w >> 1) + uXOffset -((strlen(instr) >> 1)*6)), (srfScreen->h >> 1)); + + vid_blit(srfScreen, 0, 0); + vid_flip(); + + // play a 'save me' sound if we've got sound + //if (get_sound_initialized()) + //{ + // sound_play_saveme(); + //} + + con_getkey(); // wait for keypress + + vid_blank(); + vid_flip(); + + // MATT : we can't call video_repaint because the video might not have been initialized + // yet. We can either comment this out, or add safety checks in video_repaint (which + // is kind of a hassle right now since we have a bunch of redundant copies everywhere) + + } // end if video has been initialized + + // if video has not been initialized, print an error any way that we can + else + { +#ifdef WIN32 + MessageBox(NULL, s, "DAPHNE Singe encountered an error", MB_OK | MB_ICONERROR); +#else + printf("%s\n",s); +#endif + } +} + +// notifies user that the game does not work correctly and gives a reason +// this should be called after video has successfully been initialized +void printnowookin(const char *s) +{ + if (get_console_initialized()) + { + SDL_Surface *srfScreen = get_screen_blitter(); + + vid_blank(); + // don't draw 'no wookin' graphic if display is too small (can happen on handheld) + if (srfScreen->w >= 640) draw_othergfx(B_GAMENOWOOK, 0, 180); + SDLDrawText(s, srfScreen, FONT_SMALL, ((srfScreen->w >> 1) -((strlen(s) >> 1)*6)), (srfScreen->h >> 1)); + vid_blit(srfScreen, 0, 0); + vid_flip(); + con_getkey(); // wait for keypress + + // repaint the disrupted overlay (ie Dragon's Lair Scoreboard when using a real LDP) + display_repaint(); + } +} + +// prints a notice to the screen +void printnotice(const char *s) +{ + if (get_console_initialized()) + { + char ch = 0; + SDL_Surface *srfScreen = get_screen_blitter(); + + SDL_FillRect(srfScreen, NULL, 0); // draw black background first + SDLDrawText(s, srfScreen, FONT_SMALL, ((srfScreen->w >> 1)-((strlen(s) >> 1)*6)), (srfScreen->h >> 1)); + + vid_blank(); // needed by opengl + vid_blit(srfScreen, 0, 0); + vid_flip(); + + ch = con_getkey(); // wait for keypress + + // if they pressed escape, quit + if (ch == 27) + { + set_quitflag(); + } + } +} diff --git a/io/error.h b/io/error.h new file mode 100644 index 000000000..4a6de5f27 --- /dev/null +++ b/io/error.h @@ -0,0 +1,26 @@ +/* + * error.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +void printerror (const char *); +void printnowookin(const char *s); +void printnotice(const char *s); diff --git a/io/fileparse.cpp b/io/fileparse.cpp new file mode 100644 index 000000000..a05cb3bf6 --- /dev/null +++ b/io/fileparse.cpp @@ -0,0 +1,345 @@ +/* + * fileparse.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// fileparse.cpp +// by Matt Ownby + +// some basic file-parsing functions which should be safe enough to prevent daphne from ever +// segfaulting, even if the file is totally corrupt + +#include "fileparse.h" +#include "conout.h" + +// copies into buf everything from the current position in the file until the end of a +// line and positions the file stream at the beginning of the next line. +// returns how many bytes were copied +int read_line(mpo_io *io, string &buf) +{ + unsigned char ch = 0; + MPO_BYTES_READ bytes_read = 0; + + buf = ""; // initalize it with an empty string + + // go until we reach EOF (or we reach the end of the line) + while (!io->eof) + { + if (mpo_read(&ch, 1, &bytes_read, io)) + { + if (bytes_read == 0) break; // if we hit EOF, then break + + // if we have hit the end of the line + if ((ch == 10) || (ch == 13)) + { + // keep reading until we get passed the end of line chars + while (((ch == 10) || (ch == 13)) && (bytes_read != 0)) + { + mpo_read(&ch, 1, &bytes_read, io); + } + + // if we still have more of the file to read in, then move back one character + // so that we are at the beginning of the next line + if (bytes_read != 0) + { + // if seek was successful + if (mpo_seek(-1, MPO_SEEK_CUR, io) == true) + { + } + else + { + printline("fileparse.cpp : mpo_seek function failed when it shouldn't have"); + } + } + + break; // we're done + } + + // if the character is part of the current line then add it + else + { + buf = buf + (char) ch; + } + } + else + { + printline("fileparse.cpp ERROR : mpo_read function failed"); + break; + } + } + + return buf.length(); +} + + +// copies into buf everything from the current position in the file until the end of a +// line and positions the file stream at the beginning of the next line. Contents are also +// null-terminated. +// Returns the # of bytes copied into the buf. +// buf_size is the total size of the buf to prevent buffer overflow +int read_line(mpo_io *io, char *buf, int buf_size) +{ + int index = 0; + unsigned char ch = 0; + MPO_BYTES_READ bytes_read = 0; + + // while we haven't overflowed the buffer + // (we do -1 to leave space for null character at the end) + while (index < (buf_size - 1)) + { + if (mpo_read(&ch, 1, &bytes_read, io)) + { + if (bytes_read == 0) break; // if we hit EOF, then break + + // if we have hit the end of the line + if ((ch == 10) || (ch == 13)) + { + // keep reading until we get passed the end of line chars + while (((ch == 10) || (ch == 13)) && (bytes_read != 0)) + { + mpo_read(&ch, 1, &bytes_read, io); + } + + // if we still have more of the file to read in, then move back one character + // so that we are at the beginning of the next line + if (bytes_read != 0) + { + // if seek was successful + if (mpo_seek(-1, MPO_SEEK_CUR, io) == true) + { + } + else + { + printline("fileparse.cpp : mpo_seek function failed when it shouldn't have"); + } + } + + break; // we're done + } + + // if the character is part of the current line + else + { + buf[index++] = (unsigned char) ch; + } + } + else + { + printline("fileparse.cpp ERROR : mpo_read function failed"); + break; + } + } + buf[index] = 0; + + return (index + 1); // + 1 to indicate # of bytes actually copied +} + +int read_line(FILE *F, char *buf, int buf_size) +{ + int index = 0; + int ch = 0; + + // while we haven't overflowed the buffer + // (we do -1 to leave space for null character at the end) + while (index < (buf_size - 1)) + { + ch = fgetc(F); + + if (ch == EOF) break; // if we hit the end of file, then break + + // if we have hit the end of the line + if ((ch == 10) || (ch == 13)) + { + // keep reading until we get passed the end of line chars + while (((ch == 10) || (ch == 13)) && (ch != EOF)) + { + ch = getc(F); + } + + // if we still have more of the file to read in, then move back one character + // so that we are at the beginning of the next line + if (ch != EOF) + { + fseek(F, -1, SEEK_CUR); + } + + break; + } + + // if the character is part of the current line + else + { + buf[index++] = (unsigned char) ch; + } + } + buf[index] = 0; + + return (index + 1); // + 1 to indicate # of bytes actually copied +} + + +const char *read_line(const char *pszInBuf, string &line) +{ + const char *result = NULL; + unsigned char ch = 0; + int idx = 0; + + line = ""; // initalize it with an empty string + + // go until we reach end of the buffer (or end of line) + while (pszInBuf[idx] != 0) + { + ch = pszInBuf[idx]; + + // if we have hit the end of the line + if ((ch == 10) || (ch == 13)) + { + // keep reading until we get passed the end of line chars + while (((ch == 10) || (ch == 13)) && (ch != 0)) + { + ++idx; + ch = pszInBuf[idx]; + } + + break; // we got our line + } + + // if the character is part of the current line then add it + else + { + line = line + (char) ch; + } + ++idx; + } + + // if we aren't at the end of the buffer, return pointer to first character of next line + if (pszInBuf[idx] != 0) result = pszInBuf + idx; + + return result; +} + + +// takes a pathname (relative or absolute) + a filename and removes the filename itself +// therefore it returns just the path (stored in 'path') +// returns false if there is an error (such as the file having no path) +bool get_path_of_file(string file_with_path, string &path) +{ + bool success = false; + int index = file_with_path.length() - 1; // start on last character + + // make sure the file_with_path is at least 2 characters long + // because otherwise our proceeding calculations could cause a segfault + if (index > 0) + { + // locate the preceeding / or \ character + while ((index >= 0) && (file_with_path[index] != '/') && (file_with_path[index] != '\\')) + { + index--; + } + + // if we found a leading / or \ character + if (index >= 0) + { + path = file_with_path.substr(0, index+1); + success = true; + } + } + + return success; +} + +// Isolates a word within an arbitrary string (src_buf) +// 'word' will contain the word it found, 'remaining_line' will contain the rest of the line that has yet to be examined +// !!!NOTE : 'src_buf' is assumed to be a single line with no linefeed/carriage return characters!!! +// Returns 'true' if a word was found, or 'false' if a word could not be found (ie if the string was empty) +bool find_word(const char *src_buf, string &word, string &remaining_line) +{ + bool result = false; + int index = 0; + int start_index = 0; + + // find beginning of word, skip spaces or tabs + while (my_is_whitespace(src_buf[index])) + { + index++; + } + + // make sure we aren't at the end of the string already + if (src_buf[index] != 0) + { + start_index = index; + + // now go to the end of the current word + while ((!my_is_whitespace(src_buf[index])) && (src_buf[index] != 0)) + { + index++; + } + + // this section is a little tricky, so verify that it actually works :) + word = src_buf; + remaining_line = word.substr(index, word.length() - index); + word = word.substr(start_index, index-start_index); + result = true; + } + + return result; +} + +// Isolates a word within an arbitrary string (src_buf) +// 'word_begin' will point to the beginning of the word, and 'word_length' will be how long the word is +// !!!NOTE : 'src_buf' is assumed to be a single line with no linefeed/carriage return characters!!! +// Returns 'true' if a word was found, or 'false' if a word could not be found (ie if the string was empty) +bool find_word(const char *src_buf, const char **word_begin, int *word_length) +{ + bool result = false; + int index = 0; + + *word_length = 0; + *word_begin = NULL; + + // find beginning of word, skip spaces or tabs + while (my_is_whitespace(src_buf[index])) + { + index++; + } + + // make sure we aren't at the end of the string already + if (src_buf[index] != 0) + { + *word_begin = &src_buf[index]; // point to beginning of word occurance + + // now go to the end of the current word + while ((!my_is_whitespace(src_buf[index])) && (src_buf[index] != 0)) + { + (*word_length)++; + index++; + } + result = true; + } + + return result; +} + +// miniature version of isspace() because we don't want to consider linefeeds/carriage returns to be whitespace +bool my_is_whitespace(char ch) +{ + if ((ch == ' ') || (ch == '\t')) return true; + else return false; +} diff --git a/io/fileparse.h b/io/fileparse.h new file mode 100644 index 000000000..336357529 --- /dev/null +++ b/io/fileparse.h @@ -0,0 +1,40 @@ +/* + * fileparse.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include +#include "my_stdio.h" +#include + +using namespace std; + +int read_line(mpo_io *io, string &buf); +int read_line(FILE *F, char *buf, int buf_size); +int read_line(mpo_io *io, char *buf, int buf_size); + +// reads line from a buffer (in_buf), returns the line in 'line' +// Returns a pointer to the first character in the next line, or NULL if there is no next line +const char *read_line(const char *in_buf, string &line); + +bool get_path_of_file(string file_with_path, string &path); +bool find_word(const char *src_buf, string &word, string &remaining_line); +bool find_word(const char *src_buf, const char **word_begin, int *word_length); +bool my_is_whitespace(char ch); diff --git a/io/homedir.cpp b/io/homedir.cpp new file mode 100644 index 000000000..3f26f1094 --- /dev/null +++ b/io/homedir.cpp @@ -0,0 +1,107 @@ +/* + * homedir.cpp + */ + +#include "homedir.h" +#include "mpo_fileio.h" +#include "conout.h" + +#ifdef WIN32 +// for CreateDirectory +#include +#endif + +#ifdef UNIX +// for mkdir +#include +#include +#endif + +using namespace std; + +homedir g_homedir; // our main homedir class (statically allocated to minimize risk of memory leak) + +// no arguments because this is statically allocated +homedir::homedir() +{ + m_appdir = "."; // our current directory must be our app directory, so a '.' here is sufficient + m_homedir = "."; // using curdir is a sensible default for the constructor +} + +string homedir::get_homedir() +{ + return m_homedir; +} + +// helper function +void homedir::make_dir(const string &dir) +{ +#ifdef WIN32 + CreateDirectory(dir.c_str(), NULL); // create directory if it does not already exist +#else + unsigned int oldumask = umask(022); + mkdir(dir.c_str(), 0777); // create directory if it does not already exist + umask(oldumask); +#endif +} + +void homedir::set_homedir(const string &s) +{ + m_homedir = s; + + // create writable directories if they don't exist + make_dir(m_homedir); + //make_dir(m_homedir + "/ram"); + //make_dir(m_homedir + "/roms"); + //make_dir(m_homedir + "/framefile"); + make_dir(m_homedir + "/games"); + make_dir(m_homedir + "/screenshots"); +} + +string homedir::get_screenshot_dir() +{ + string s1; + s1 = m_homedir + "/screenshots/"; + return s1.c_str(); +} + +string homedir::get_romfile(const string &s) +{ + return find_file("roms/" + s, true); +} + +string homedir::get_ramfile(const string &s) +{ + return find_file("ram/" + s, false); +} + +string homedir::get_framefile(const string &s) +{ + //Framefiles may be passed as a fully-qualified path. If so, see if it exists first before trying the directories. + if (mpo_file_exists(s.c_str())) + { + return s; + } + else + { + return find_file("framefile/" + s, true); + } +} + +string homedir::find_file(string fileName, bool bFallback) +{ + string strFile = fileName; + string result = ""; + + // try homedir first + result = m_homedir + "/" + strFile; + + // if file does not exist in home directory and we are allowed to fallback to app dir + if (bFallback && !mpo_file_exists(result.c_str())) + { + result = m_appdir + "/" + strFile; + } + // else file either exists or we cannot fall back + + return result; +} diff --git a/io/homedir.h b/io/homedir.h new file mode 100644 index 000000000..38c58131c --- /dev/null +++ b/io/homedir.h @@ -0,0 +1,45 @@ +/* + * homedir.h + */ + +#ifndef HOMEDIR_H +#define HOMEDIR_H + +#include +#include // STL strings, useful to prevent buffer overrun +//#include "homedir.h" //???? +#include "mpo_fileio.h" + +using namespace std; // for STL string to compile without problems ... + +class homedir +{ +public: + //Constructor/destructors + homedir(); + + //Properties + string get_homedir(); + void set_homedir(const string &s); + string get_romfile(const string &s); + string get_ramfile(const string &s); + string get_framefile(const string &s); + string get_screenshot_dir(); + + // Searches homedir for a filename indicated by 'fileName' and if it doesn't find it, + // searches the application directory for the same filename (if 'bFallback' is true). + // Returns the found path, + // or an empty string if neither location yielded the file. + string find_file(string fileName, bool bFallback = true); + +private: + void make_dir(const string &dir); + + //Private members + string m_appdir; //Directory the app was launched from + string m_homedir; //"Home" directory to search first (defaults to appdir) +}; + +extern homedir g_homedir; // our global game class. Instead of having every .cpp file define this, we put it here. + +#endif diff --git a/io/input.cpp b/io/input.cpp new file mode 100644 index 000000000..d7f16b818 --- /dev/null +++ b/io/input.cpp @@ -0,0 +1,1150 @@ +/* + * input.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// Handles SDL input functions (low-level keyboard/joystick input) + +#ifdef WIN32 +#include // for ScreenToClient -- rdg +#endif +#include "SDL_syswm.h" +#include +#include "input.h" +#include "conout.h" +#include "homedir.h" +#include "../video/video.h" +#include "../video/SDL_Console.h" +#include "../daphne.h" +#include "../timer/timer.h" +#include "../game/game.h" +//#include "../game/thayers.h" +#include "../game/singe.h" // by RDG2010 +#include "../ldp-out/ldp.h" +#include "fileparse.h" +#include "../manymouse/manymouse.h" // by RDG + +#ifdef UNIX +#include // for non-blocking i/o +#endif + +#include // STL queue for coin queue + +using namespace std; + +// Win32 doesn't use strcasecmp, it uses stricmp (lame) +#ifdef WIN32 +#define strcasecmp stricmp +#endif + +const int JOY_AXIS_MID = (int) (32768 * (0.75)); // how far they have to move the joystick before it 'grabs' + +SDL_Joystick *G_joystick = NULL; // pointer to joystick object +bool g_use_joystick = true; // use a joystick by default +bool g_consoledown = false; // whether the console is down or not +bool g_alt_pressed = false; // whether the ALT key is presssed (for ALT-Enter combo) +unsigned int idle_timer; // added by JFA for -idleexit + +const double STICKY_COIN_SECONDS = 0.125; // how many seconds a coin acceptor is forced to be "depressed" and how many seconds it is forced to be "released" +Uint32 g_sticky_coin_cycles = 0; // STICKY_COIN_SECONDS * get_cpu_hz(0), cannot be calculated statically +queue g_coin_queue; // keeps track of coin input to guarantee that coins don't get missed if the cpu is busy (during seeks for example) +Uint64 g_last_coin_cycle_used = 0; // the cycle value that our last coin press used + +static int available_mice = 0; //rdg +static ManyMouseEvent mm_event; +static int bolGrab = false; + +#define SDL_MOUSE 100 +#define MANY_MOUSE 200 + +static int g_mouse_mode = SDL_MOUSE; + + +// the ASCII key words that the parser looks at for the key values +// NOTE : these are in a specific order, corresponding to the enum in daphne.h +const char *g_key_names[] = +{ + "KEY_UP", "KEY_LEFT", "KEY_DOWN", "KEY_RIGHT", "KEY_START1", "KEY_START2", "KEY_BUTTON1", + "KEY_BUTTON2", "KEY_BUTTON3", "KEY_COIN1", "KEY_COIN2", "KEY_SKILL1", "KEY_SKILL2", + "KEY_SKILL3", "KEY_SERVICE", "KEY_TEST", "KEY_RESET", "KEY_SCREENSHOT", "KEY_QUIT", "KEY_PAUSE", + "KEY_CONSOLE", "KEY_TILT" +}; + +// default key assignments, in case .ini file is missing +// Notice each switch can have two keys assigned to it +// NOTE : These are in a specific order, corresponding to the enum in daphne.h +int g_key_defs[SWITCH_COUNT][2] = +{ + { SDLK_UP, SDLK_KP8 }, // up + { SDLK_LEFT, SDLK_KP4 }, // left + { SDLK_DOWN, SDLK_KP2 }, // down + { SDLK_RIGHT, SDLK_KP6 }, // right + { SDLK_1, 0 }, // 1 player start + { SDLK_2, 0 }, // 2 player start + { SDLK_SPACE, SDLK_LCTRL }, // action button 1 + { SDLK_LALT, 0 }, // action button 2 + { SDLK_LSHIFT, 0 }, // action button 3 + { SDLK_5, SDLK_c }, // coin chute left + { SDLK_6, 0 }, // coin chute right + { SDLK_KP_DIVIDE, 0 }, // skill easy + { SDLK_KP_MULTIPLY, 0 }, // skill medium + { SDLK_KP_MINUS, 0 }, // skill hard + { SDLK_9, 0 }, // service coin + { SDLK_F2, 0 }, // test mode + { SDLK_F3, 0 }, // reset cpu + { SDLK_F12, SDLK_F11 }, // take screenshot + { SDLK_ESCAPE, SDLK_q }, // Quit DAPHNE + { SDLK_p, 0 }, // pause game + { SDLK_BACKQUOTE, 0 }, // toggle console + { SDLK_t, 0 }, // Tilt/Slam switch +}; + +//////////// + +#ifndef GP2X +// added by Russ +// global button mapping array. just hardcoded room for 10 buttons max +int joystick_buttons_map[10] = { + SWITCH_BUTTON1, // button 1 + SWITCH_BUTTON2, // button 2 + SWITCH_BUTTON3, // button 3 + SWITCH_BUTTON1, // button 4 + SWITCH_COIN1, // button 5 + SWITCH_START1, // button 6 + SWITCH_BUTTON1, // button 7 + SWITCH_BUTTON1, // button 8 + SWITCH_BUTTON1, // button 9 + SWITCH_BUTTON1, // button 10 +}; +#else +// button mapping for gp2x +int joystick_buttons_map[18] = +{ + SWITCH_UP, // 0 (up) + SWITCH_UP, // 1 (up-left) + SWITCH_LEFT, // 2 (left) + SWITCH_DOWN, // 3 (down-left) + SWITCH_DOWN, // 4 (down) + SWITCH_DOWN, // 5 (down-right) + SWITCH_RIGHT, // 6 (right) + SWITCH_UP, // 7 (up-right) + SWITCH_START1, // 8 (start) + SWITCH_COIN1, // 9 (select) + SWITCH_QUIT, // 10 (left) + SWITCH_PAUSE, // 11 (right) + SWITCH_BUTTON1, // 12 (A) + SWITCH_BUTTON2, // 13 (B) + SWITCH_BUTTON3, // 14 (X) + SWITCH_CONSOLE, // 15 (Y) + SWITCH_BUTTON1, // 16 is vol + + SWITCH_BUTTON1 // 17 is vol - +}; +#endif + +// Mouse button to key mappings +// Added by ScottD for Singe + +int mouse_buttons_map[6] = +{ + SWITCH_BUTTON1, // 0 (Left Button) + SWITCH_BUTTON3, // 1 (Middle Button) + SWITCH_BUTTON2, // 2 (Right Button) + SWITCH_BUTTON1, // 3 (Wheel Up) + SWITCH_BUTTON2, // 4 (Wheel Down) + SWITCH_MOUSE_DISCONNECT // this is a dummy value so SDL mouse array matches Many Mouse array +}; + +// ManyMouse button mapping to be backwards compatible with Scott's original. +/* +int mouse_buttons_map[6] = +{ + SWITCH_BUTTON3, // 0 (Left Button) + SWITCH_BUTTON1, // 1 (Right Button) + SWITCH_BUTTON2, // 2 (Middle Up) + SWITCH_MOUSE_SCROLL_UP, // 4 (Wheel UP) + SWITCH_MOUSE_SCROLL_DOWN, // 3 (Wheel Down) + SWITCH_MOUSE_DISCONNECT +}; +*/ +//////////// + +void CFG_Keys() +{ + struct mpo_io *io; + string cur_line = ""; + string key_name = "", sval1 = "", sval2 = "", sval3 = "", eq_sign = ""; + int val1 = 0, val2 = 0, val3 = 0; +// bool done = false; + + // find where the dapinput ini file is (if the file doesn't exist, this string will be empty) + string strDapInput = g_homedir.find_file("dapinput.ini", true); + + io = mpo_open(strDapInput.c_str(), MPO_OPEN_READONLY); + if (io) + { + printline("Remapping input ..."); + + cur_line = ""; + + // read lines until we find the keyboard header or we hit EOF + while (strcasecmp(cur_line.c_str(), "[KEYBOARD]") != 0) + { + read_line(io, cur_line); + if (io->eof) + { + printline("CFG_Keys() : never found [KEYBOARD] header, aborting"); + break; + } + } + + // go until we hit EOF, or we break inside this loop (which is the expected behavior) + while (!io->eof) + { + // if we read in something besides a blank line + if (read_line(io, cur_line) > 0) + { + bool corrupt_file = true; // we use this to avoid doing multiple if/else/break statements + + // if we are able to read in the key name + if (find_word(cur_line.c_str(), key_name, cur_line)) + { + if (strcasecmp(key_name.c_str(), "END") == 0) break; // if we hit the 'END' keyword, we're done + + // equals sign + if (find_word(cur_line.c_str(), eq_sign, cur_line) && (eq_sign == "=")) + { + if (find_word(cur_line.c_str(), sval1, cur_line)) + { + if (find_word(cur_line.c_str(), sval2, cur_line)) + { + if (find_word(cur_line.c_str(), sval3, cur_line)) + { + val1 = atoi(sval1.c_str()); + val2 = atoi(sval2.c_str()); + val3 = atoi(sval3.c_str()); + corrupt_file = false; // looks like we're good + + bool found_match = false; + for (int i = 0; i < SWITCH_COUNT; i++) + { + // if we can match up a key name (see list above) ... + if (strcasecmp(key_name.c_str(), g_key_names[i])==0) + { + g_key_defs[i][0] = val1; + g_key_defs[i][1] = val2; + + // if zero then no mapping necessary, just use default, if any + if (val3 > 0) joystick_buttons_map[val3 - 1] = i; + found_match = true; + break; + } + } + + // if the key line was unknown + if (!found_match) + { + cur_line = "CFG_Keys() : Unrecognized key name " + key_name; + printline(cur_line.c_str()); + corrupt_file = true; + } + + } + else printline("CFG_Keys() : Expected 3 integers, only found 2"); + } + else printline("CFG_Keys() : Expected 3 integers, only found 1"); + } + else printline("CFG_Keys() : Expected 3 integers, found none"); + } // end equals sign + else printline("CFG_Keys() : Expected an '=' sign, didn't find it"); + } // end if we found key_name + else printline("CFG_Keys() : Weird unexpected error happened"); // this really shouldn't ever happen + + if (corrupt_file) + { + printline("CFG_Keys() : input remapping file was not in proper format, so we are aborting"); + break; + } + } // end if we didn't find a blank line + // else it's a blank line so we just ignore it + } // end while not EOF + + mpo_close(io); + } // end if file was opened successfully +} + + +// By RDG == ManyMouse code follows + +static void ManyMouse_Init_Mice(void) +{ + + printline("Using ManyMouse for mice input."); + available_mice = ManyMouse_Init(); + g_game->set_mice_detected(available_mice); + + if (available_mice > MAX_MICE) + available_mice = MAX_MICE; + + if (available_mice <= 0) + printline("No mice detected!\n"); + else + { + + int i; + char s1[255]; + if (available_mice == 1) + printline("Only 1 mouse found."); + else + { + sprintf(s1,"Found %d mice devices:",available_mice); + printline(s1); + } + + for (i = 0; i < available_mice; i++) + { + const char *name = ManyMouse_DeviceName(i); + strncpy(mice[i].name, name, sizeof (mice[i].name)); + mice[i].name[sizeof (mice[i].name) - 1] = '\0'; + mice[i].connected = 1; + sprintf(s1,"#%d: %s", i, mice[i].name); + printline(s1); + } + SDL_WM_GrabInput(SDL_GRAB_ON); + } +} + +static void ManyMouse_Update_Mice() +{ + + while (ManyMouse_PollEvent(&mm_event)) + { + Mouse *mouse; + if (mm_event.device >= (unsigned int) available_mice) + continue; + + mouse = &mice[mm_event.device]; + + if (mm_event.type == MANYMOUSE_EVENT_RELMOTION) + { + if (mm_event.item == 0) + mouse->relx += mm_event.value; + else if (mm_event.item == 1) + mouse->rely += mm_event.value; + + if (mouse->relx < 0) mouse->relx = 0; + else if (mouse->relx >= get_video_width()) mouse->relx = get_video_width(); + if (mouse->rely < 0) mouse->rely = 0; + else if (mouse->rely >= get_video_height()) mouse->rely = get_video_height(); + + g_game->OnMouseMotion(mouse->x, mouse->y, mouse->relx, mouse->rely, mm_event.device); + + } + + else if (mm_event.type == MANYMOUSE_EVENT_ABSMOTION) + { + + + + float val = (float) (mm_event.value - mm_event.minval); + float maxval = (float) (mm_event.maxval - mm_event.minval); + + + if (mm_event.item == 0) + //mouse->x = (val / maxval) * screen_w; + mouse->x = mm_event.value; + else if (mm_event.item == 1) + //mouse->y = (val / maxval) * screen_h; + mouse->y = mm_event.value; + + g_game->OnMouseMotion(mouse->x, mouse->y, mouse->relx, mouse->rely, mm_event.device); + + + /* + LPPOINT absPoint = new POINT; + // Access to SDL's OS specific structure. + SDL_SysWMinfo windowInfo; + SDL_VERSION(&windowInfo.version); + if(SDL_GetWMInfo(&windowInfo)) + { + // Retrieve the Windows handle to the SDL window. + HWND handle = windowInfo.window; + + if (mm_event.item == 0) + { + absPoint->x = mm_event.value; + absPoint->y = 0; + //if (ClientToScreen(handle, absPoint) != 0) + MapWindowPoints(NULL, handle,absPoint,2); + mouse->x = absPoint->x; + + } + /* + else if (mm_event.item == 1) + { + absPoint.y = mm_event.value; + if (ScreenToClient(handle,LPPOINT) absPoint.y) == 0) + mouse->y = absPoint.y; + } + + + } + + */ + } + + else if (mm_event.type == MANYMOUSE_EVENT_BUTTON) + { + if (mm_event.item < 32) + { + + if (mm_event.value == 1) // 0 == release, 1 == pressed + { + input_enable((Uint8)mouse_buttons_map[mm_event.item], mm_event.device); + mouse->buttons |= (1 << mm_event.item); + + } + else + { + input_disable((Uint8)mouse_buttons_map[mm_event.item], mm_event.device); + mouse->buttons &= ~(1 << mm_event.item); + + } + } + } + + else if (mm_event.type == MANYMOUSE_EVENT_SCROLL) + { + if (mm_event.item == 0) // vertical scroll wheel + { + if (mm_event.value > 0) // scroll up + input_disable(SWITCH_MOUSE_SCROLL_UP, mm_event.device); + else // scroll down + input_disable(SWITCH_MOUSE_SCROLL_DOWN, mm_event.device); + } + + } + + else if (mm_event.type == MANYMOUSE_EVENT_DISCONNECT) + { + mice[mm_event.device].connected = 0; + input_disable(SWITCH_MOUSE_DISCONNECT, mm_event.device); + } + } + +} + + +////// end manymouse implementation + +int SDL_input_init() +// initializes the keyboard (and joystick if one is present) +// returns 1 if successful, 0 on error +// NOTE: Video has to be initialized BEFORE this is or else it won't work +{ + + int result = 0; + + // make sure the coin queue is empty (it should be, this is just a safety check) + while (!g_coin_queue.empty()) + { + g_coin_queue.pop(); + } + g_sticky_coin_cycles = 0;//(Uint32) (STICKY_COIN_SECONDS * get_cpu_hz(0)); // only needs to be calculated once + + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0) + { + // if joystick usage is enabled + if (g_use_joystick) + { + // if there is at least 1 joystick and we are authorized to use the joystick for input + if (SDL_NumJoysticks() > 0) + { + G_joystick = SDL_JoystickOpen(0); // FIXME: right now we automatically choose the first joystick + if (G_joystick != NULL) + { + printline("Joystick #0 was successfully opened"); + } + else + { + printline("Error opening joystick!"); + } + } + else + { + printline("No joysticks detected"); + } + } + // notify user that their attempt to disable the joystick is successful + else + { + printline("Joystick usage disabled"); + } + + CFG_Keys(); // NOTE : for some freak reason, this should not be done BEFORE the joystick is initialized, I don't know why! + + + result = 1; + } + else + { + printline("Input initialization failed!"); + } + + idle_timer = refresh_ms_time(); // added by JFA for -idleexit + +#ifdef UNIX + // enable non-blocking stdin (see conin.cpp UNIX stdin stuff) + /*int iRes =*/ fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); +#endif +/* + // if the mouse is disabled, then filter mouse events out ... + if (!g_game->get_mouse_enabled()) + { + FilterMouseEvents(true); + } +*/ + // Manymouse implementation by RDG + if (!g_game->get_mouse_enabled()) + { + FilterMouseEvents(true); + if (g_game->get_mouse_enabled()) ManyMouse_Init_Mice(); + } + else + FilterMouseEvents(false); + + return(result); + +} + +void FilterMouseEvents(bool bFilteredOut) +{ + int iState = SDL_ENABLE; + + if (bFilteredOut) + { + iState = SDL_IGNORE; + } + + SDL_EventState(SDL_MOUSEMOTION, iState); + SDL_EventState(SDL_MOUSEBUTTONDOWN, iState); + SDL_EventState(SDL_MOUSEBUTTONUP, iState); +} + +// does any shutting down necessary +// 1 = success, 0 = failure +int SDL_input_shutdown(void) +{ + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + if ((g_game->get_mouse_enabled()) && (g_mouse_mode == MANY_MOUSE)) ManyMouse_Quit(); + return(1); +} + +// checks to see if there is incoming input, and acts on it +void SDL_check_input() +{ + + SDL_Event event; + + while ((SDL_PollEvent (&event)) && (!get_quitflag())) + { + // if they press the tilda key to bring down the console + // this is somewhat of a hacked if statement but I can't see + // a better way based on the SDL_Console API ... + if ((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_BACKQUOTE)) + { + // we must not bring down the console if blitting is not allowed + if (g_ldp->is_blitting_allowed()) + { +#ifdef CPU_DEBUG + toggle_console(); +#endif + } + } + // if we've got the console down, process events + else if (g_consoledown) + { + ConsoleEvents(&event); + } + // else handle events normally + else + { + process_event(&event); + } + } + + if (g_game->get_mouse_enabled() && (g_mouse_mode == MANY_MOUSE)) ManyMouse_Update_Mice(); + + check_console_refresh(); + + // added by JFA for -idleexit + if (get_idleexit() > 0 && elapsed_ms_time(idle_timer) > get_idleexit()) set_quitflag(); + + // if the coin queue has something entered into it + if (!g_coin_queue.empty()) + { + struct coin_input coin = g_coin_queue.front(); // examine the next element in the queue to be considered + + // NOTE : when cpu timers are flushed, the coin queue is automatically "reshuffled" + // so it is safe not to check to see whether the cpu timers were flushed here + + // if it's safe to activate the coin + //if (get_total_cycles_executed(0) > coin.cycles_when_to_enable) + { + // if we're supposed to enable this coin + if (coin.coin_enabled) + { + g_game->input_enable(coin.coin_val, NOMOUSE); + } + // else we are supposed to disable this coin + else + { + g_game->input_disable(coin.coin_val, NOMOUSE); + } + g_coin_queue.pop(); // remove coin entry from queue + } + // else it's not safe to activate the coin, so we just wait + } + // else the coin queue is empty, so we needn't do anything ... + +} + +#ifdef CPU_DEBUG +void toggle_console() +{ + if (get_console_initialized()) + { + // if console is down, get rid of it + if (g_consoledown) + { + g_consoledown = false; + SDL_EnableUNICODE(0); + display_repaint(); + } + // if console is not down, display it + else + { + g_consoledown = true; + SDL_EnableUNICODE(1); + } + } +} +#endif + +// processes incoming input +void process_event(SDL_Event *event) +{ + unsigned int i = 0; + + // by RDG2010 + // make things easier to read... + SDLKey keyPressed = event->key.keysym.sym; + + switch (event->type) + { + case SDL_KEYDOWN: + reset_idle(); // added by JFA for -idleexit + + + // by RDG2010 + // Get SINGE full access to keyboard input (like Thayers) + + + { + singe *l_singe = dynamic_cast(g_game); + if (l_singe) l_singe->process_keydown(keyPressed, g_key_defs); + } + + + + break; + case SDL_KEYUP: + // MPO : since con_getkey doesn't catch the key up event, we shouldn't call reset_idle here. + //reset_idle(); // added by JFA for -idleexit + + // by RDG2010 + // Get SINGE full access to keyboard input (like Thayers) + + if (keyPressed == SDLK_g) + { + if ((g_game->get_mouse_enabled()) && (g_mouse_mode == MANY_MOUSE)) + { + bolGrab = !bolGrab; + if (bolGrab) + { + SDL_WM_GrabInput(SDL_GRAB_ON); + ManyMouse_Quit(); + ManyMouse_Init_Mice(); + } + else + SDL_WM_GrabInput(SDL_GRAB_OFF); + } + } + else + { + singe *l_singe = dynamic_cast(g_game); + if (l_singe) l_singe->process_keyup(keyPressed, g_key_defs); + + } + + break; + case SDL_JOYAXISMOTION: + //reset_idle(); // added by JFA for -idleexit + // reset_idle removed here because the analog controls were registering + // even when the joystick was not in use. Joystick buttons still reset the idle. + process_joystick_motion(event); + break; + case SDL_JOYHATMOTION: + // only process events for the first hat + if ( event->jhat.hat == 0 ) + { + reset_idle(); + process_joystick_hat_motion(event); + } + break; + case SDL_JOYBUTTONDOWN: + reset_idle(); // added by JFA for -idleexit + + // added by Russ + // loop through buttons and look for a press + for (i = 0; i < (sizeof(joystick_buttons_map) / sizeof(int)); i++) { + if (event->jbutton.button == i) { + input_enable((Uint8) joystick_buttons_map[i], NOMOUSE); + break; + } + } + + break; + case SDL_JOYBUTTONUP: + reset_idle(); // added by JFA for -idleexit + + // added by Russ + for (i = 0; i < (sizeof(joystick_buttons_map) / sizeof(int)); i++) { + if (event->jbutton.button == i) { + input_disable((Uint8) joystick_buttons_map[i], NOMOUSE); + break; + } + } + + break; + /* + case SDL_MOUSEBUTTONDOWN: + // added by ScottD + // loop through buttons and look for a press + for (i = 0; i < (sizeof(mouse_buttons_map) / sizeof(int)); i++) { + if (event->button.button == i) { + input_enable((Uint8)mouse_buttons_map[i]); + break; + } + } + break; + case SDL_MOUSEBUTTONUP: + // added by ScottD + for (i = 0; i < (sizeof(mouse_buttons_map) / sizeof(int)); i++) { + if (event->button.button == i) { + input_disable((Uint8)mouse_buttons_map[i]); + break; + } + } + break; + + case SDL_MOUSEMOTION: + // added by ScottD + g_game->OnMouseMotion(event->motion.x, event->motion.y, event->motion.xrel, event->motion.yrel); + break; + */ + case SDL_QUIT: + // if they are trying to close the window + set_quitflag(); + break; + default: + break; + } + + if (g_game->get_mouse_enabled() && (g_mouse_mode == SDL_MOUSE)) + { + switch (event->type) + { + case SDL_MOUSEBUTTONDOWN: + // added by ScottD + // loop through buttons and look for a press + for (i = 0; i < (sizeof(mouse_buttons_map) / sizeof(int)); i++) { + if (event->button.button == i) { + //input_enable((Uint8)mouse_buttons_map[i]); + g_game->input_enable((Uint8)mouse_buttons_map[i], NOMOUSE); + break; + } + } + break; + case SDL_MOUSEBUTTONUP: + // added by ScottD + for (i = 0; i < (sizeof(mouse_buttons_map) / sizeof(int)); i++) { + if (event->button.button == i) { + //input_disable((Uint8)mouse_buttons_map[i]); + g_game->input_disable((Uint8)mouse_buttons_map[i], NOMOUSE); + break; + } + } + break; + + case SDL_MOUSEMOTION: + // added by ScottD + g_game->OnMouseMotion(event->motion.x, event->motion.y, event->motion.xrel, event->motion.yrel, NOMOUSE); // Last parameter is for ManyMouse use only. + break; + } + } + + // added by JFA for -idleexit + if (get_idleexit() > 0 && elapsed_ms_time(idle_timer) > get_idleexit()) set_quitflag(); + +} + +// if a key is pressed, we go here +void process_keydown(SDLKey key) +{ + // go through each key def (defined in enum in daphne.h) and check to see if the key entered matches + // If we have a match, the switch to be used is the value of the index "move" + for (Uint8 move = 0; move < SWITCH_COUNT; move++) + { + if ((key == g_key_defs[move][0]) || (key == g_key_defs[move][1])) + { + input_enable(move, NOMOUSE); + } + } + + // check for ALT-ENTER here + if ((key == SDLK_LALT) || (key == SDLK_RALT)) + { + g_alt_pressed = true; + } + else if ((key == SDLK_RETURN) && (g_alt_pressed)) + { + vid_toggle_fullscreen(); + } + // end ALT-ENTER check +} + +// if a key is released, we go here +void process_keyup(SDLKey key) +{ + // go through each key def (defined in enum in daphne.h) and check to see if the key entered matches + // If we have a match, the switch to be used is the value of the index "move" + for (Uint8 move = 0; move < SWITCH_COUNT; move++) + { + if ((key == g_key_defs[move][0]) || (key == g_key_defs[move][1])) + { + input_disable(move, NOMOUSE); + } + } + + // if they are releasing an ALT key + if ((key == SDLK_LALT) || (key == SDLK_RALT)) + { + g_alt_pressed = false; + } +} + +// processes movements of the joystick +void process_joystick_motion(SDL_Event *event) +{ + + static int x_axis_in_use = 0; // true if joystick is left or right + static int y_axis_in_use = 0; // true if joystick is up or down + + // if they are moving along the verticle axis + if (event->jaxis.axis == 1) + { + // if they're moving up + if (event->jaxis.value < -JOY_AXIS_MID) + { + input_enable(SWITCH_UP, NOMOUSE); + y_axis_in_use = 1; + } + // if they're moving down + else if (event->jaxis.value > JOY_AXIS_MID) + { + input_enable(SWITCH_DOWN, NOMOUSE); + y_axis_in_use = 1; + } + + // if they just barely stopped moving up or down + else if (y_axis_in_use == 1) + { + input_disable(SWITCH_UP, NOMOUSE); + input_disable(SWITCH_DOWN, NOMOUSE); + y_axis_in_use = 0; + } + } // end verticle axis + + // horizontal axis + else + { + // if they're moving right + if (event->jaxis.value > JOY_AXIS_MID) + { + input_enable(SWITCH_RIGHT, NOMOUSE); + x_axis_in_use = 1; + } + // if they're moving left + else if (event->jaxis.value < -JOY_AXIS_MID) + { + input_enable(SWITCH_LEFT, NOMOUSE); + x_axis_in_use = 1; + } + // if they just barely stopped moving right or left + else if (x_axis_in_use == 1) + { + input_disable(SWITCH_RIGHT, NOMOUSE); + input_disable(SWITCH_LEFT, NOMOUSE); + x_axis_in_use = 0; + } + } // end horizontal axis +} + +// processes movement of the joystick hat +void process_joystick_hat_motion(SDL_Event *event) +{ + + static Uint8 prev_hat_position = SDL_HAT_CENTERED; + + if ( ( event->jhat.value & SDL_HAT_UP ) && !( prev_hat_position & SDL_HAT_UP ) ) + { + // hat moved to the up position + input_enable(SWITCH_UP, NOMOUSE); + } + else if ( !( event->jhat.value & SDL_HAT_UP ) && ( prev_hat_position & SDL_HAT_UP ) ) + { + // up hat released + input_disable(SWITCH_UP, NOMOUSE); + } + + if ( ( event->jhat.value & SDL_HAT_RIGHT ) && !( prev_hat_position & SDL_HAT_RIGHT ) ) + { + // hat moved to the right position + input_enable(SWITCH_RIGHT, NOMOUSE); + } + else if ( !( event->jhat.value & SDL_HAT_RIGHT ) && ( prev_hat_position & SDL_HAT_RIGHT ) ) + { + // right hat released + input_disable(SWITCH_RIGHT, NOMOUSE); + } + + if ( ( event->jhat.value & SDL_HAT_DOWN ) && !( prev_hat_position & SDL_HAT_DOWN ) ) + { + // hat moved to the down position + input_enable(SWITCH_DOWN, NOMOUSE); + } + else if ( !( event->jhat.value & SDL_HAT_DOWN ) && ( prev_hat_position & SDL_HAT_DOWN ) ) + { + // down hat released + input_disable(SWITCH_DOWN, NOMOUSE); + } + + if ( ( event->jhat.value & SDL_HAT_LEFT ) && !( prev_hat_position & SDL_HAT_LEFT ) ) + { + // hat moved to the left position + input_enable(SWITCH_LEFT, NOMOUSE); + } + else if ( !( event->jhat.value & SDL_HAT_LEFT ) && ( prev_hat_position & SDL_HAT_LEFT ) ) + { + // left hat released + input_disable(SWITCH_LEFT, NOMOUSE); + } + + prev_hat_position = event->jhat.value; +} + +// functions to help us avoid 'extern' statements +bool get_consoledown() +{ + return (g_consoledown); +} + +void set_consoledown (bool value) +{ + g_consoledown = value; +} + +// draws console if it's down and if there's been enough of a delay +void check_console_refresh() +{ + + static unsigned int console_refresh = 0; + const unsigned int refresh_every = 125; // refreshes console every (this many) ms + + if (g_consoledown) + { + if (elapsed_ms_time(console_refresh) > refresh_every) + { + DrawConsole(); + vid_blit(get_screen_blitter(), 0, 0); + vid_flip(); + console_refresh = refresh_ms_time(); + } + } +} + +// if user has pressed a key/moved the joystick/pressed a button +void input_enable(Uint8 move, int mouseID) +{ + // first test universal input, then pass unknown input on to the game driver + + switch (move) + { + default: + g_game->input_enable(move, mouseID); + break; + case SWITCH_RESET: + g_game->reset(); + break; + case SWITCH_SCREENSHOT: + g_ldp->request_screenshot(); + break; + case SWITCH_PAUSE: + if (g_game->get_pause_key_flag()) // rdg + g_game->toggle_game_pause(); + break; + case SWITCH_QUIT: + set_quitflag(); + break; + case SWITCH_COIN1: + case SWITCH_COIN2: + // coin inputs are buffered to ensure that they are not dropped while the cpu is busy (such as during a seek) + // therefore if the input is coin1 or coin2 AND we are using a real cpu (and not a program such as seektest) + //if (get_cpu_hz(0) > 0) + { + add_coin_to_queue(true, move); + } + break; + case SWITCH_CONSOLE: + // we must not bring down the console if blitting is not allowed + if (g_ldp->is_blitting_allowed()) + { +#ifdef CPU_DEBUG + toggle_console(); +#endif + } + break; + } +} + +// if user has released a key/released a button/moved joystick back to center position +void input_disable(Uint8 move, int mouseID) +{ + // don't send reset or screenshots key-ups to the individual games because they will return warnings that will alarm users + if ((move != SWITCH_RESET) && (move != SWITCH_SCREENSHOT) && (move != SWITCH_QUIT) + && (move != SWITCH_PAUSE)) + { + // coin inputs are buffered to ensure that they are not dropped while the cpu is busy (such as during a seek) + // therefore if the input is coin1 or coin2 AND we are using a real cpu (and not a program such as seektest) + //if (((move == SWITCH_COIN1) || (move == SWITCH_COIN2)) && (get_cpu_hz(0) > 0)) + if ((move == SWITCH_COIN1) || (move == SWITCH_COIN2)) + { + add_coin_to_queue(false, move); + } + else + { + g_game->input_disable(move, mouseID); + } + } + // else do nothing +} + +inline void add_coin_to_queue(bool enabled, Uint8 val) +{ + Uint64 total_cycles = 0;//get_total_cycles_executed(0); + struct coin_input coin; + coin.coin_enabled = enabled; + coin.coin_val = val; + + // make sure that we are >= to the total cycles executed otherwise coin insertions will be really quick + if (g_last_coin_cycle_used < total_cycles) + { + g_last_coin_cycle_used = total_cycles; + } + g_last_coin_cycle_used += g_sticky_coin_cycles; // advance to the next safe slot + coin.cycles_when_to_enable = g_last_coin_cycle_used; // and assign this safe slot to this current coin + g_coin_queue.push(coin); // add the coin to the queue ... +} + +// added by JFA for -idleexit +void reset_idle(void) +{ + static bool bSoundOn = false; + + // At this time, the only way the sound will be muted is if -startsilent was passed via command line. + // So the first key press should always unmute the sound. + if (!bSoundOn) + { + bSoundOn = true; + set_sound_mute(false); + } + + idle_timer = refresh_ms_time(); +} +// end edit + +// primarily to disable joystick use if user wishes not to use one +void set_use_joystick(bool val) +{ + g_use_joystick = val; +} + +bool set_mouse_mode(int thisMode) +{ + bool result = false; + + if (g_game->get_mouse_enabled()) + { + if (g_mouse_mode == MANY_MOUSE) ManyMouse_Quit(); + if (thisMode == MANY_MOUSE || thisMode == SDL_MOUSE) + { + g_mouse_mode = thisMode; + result = true; + memset(mouse_buttons_map, 0, 6); // Erase array + if (thisMode == SDL_MOUSE) + { + + mouse_buttons_map[0] = SWITCH_BUTTON1; // 0 (Left Button) + mouse_buttons_map[1] = SWITCH_BUTTON3; // 1 (Middle Button) + mouse_buttons_map[2] = SWITCH_BUTTON2; // 2 (Right Button) + mouse_buttons_map[3] = SWITCH_BUTTON1; // 3 (Wheel Up) + mouse_buttons_map[4] = SWITCH_BUTTON2; // 4 (Wheel Down) + mouse_buttons_map[5] = SWITCH_MOUSE_DISCONNECT; // Dummy value so array matches in both branches. + } + else + { + mouse_buttons_map[0] = SWITCH_BUTTON3; // 0 (Left Button) + mouse_buttons_map[1] = SWITCH_BUTTON1; // 1 (Middle Button) + mouse_buttons_map[2] = SWITCH_BUTTON2; // 2 (Right Button) + mouse_buttons_map[3] = SWITCH_MOUSE_SCROLL_UP; // 3 (Wheel Up) + mouse_buttons_map[4] = SWITCH_MOUSE_SCROLL_DOWN; // 4 (Wheel Down) + mouse_buttons_map[5] = SWITCH_MOUSE_DISCONNECT; // 4 (Wheel Down) + + ManyMouse_Init_Mice(); + + } // end if + + } // end if + + } // end if + + return result; + +} diff --git a/io/input.h b/io/input.h new file mode 100644 index 000000000..271e59f21 --- /dev/null +++ b/io/input.h @@ -0,0 +1,129 @@ +/* + * input.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef INPUT_H +#define INPUT_H + +enum +{ + SWITCH_UP, + SWITCH_LEFT, + SWITCH_DOWN, + SWITCH_RIGHT, + SWITCH_START1, + SWITCH_START2, + SWITCH_BUTTON1, + SWITCH_BUTTON2, + SWITCH_BUTTON3, + SWITCH_COIN1, + SWITCH_COIN2, + SWITCH_SKILL1, + SWITCH_SKILL2, + SWITCH_SKILL3, + SWITCH_SERVICE, + SWITCH_TEST, + SWITCH_RESET, + SWITCH_SCREENSHOT, + SWITCH_QUIT, + SWITCH_PAUSE, + SWITCH_CONSOLE, + SWITCH_TILT, + SWITCH_MOUSE_SCROLL_UP, + SWITCH_MOUSE_SCROLL_DOWN, + SWITCH_MOUSE_DISCONNECT, + SWITCH_COUNT, +}; // daphne inputs for arcade and additional controls, leave SWITCH_COUNT at the end + +/////////////////////// + +#include + +// to be passed into the coin queue +struct coin_input +{ + bool coin_enabled; // whether the coin was enabled or disabled + Uint8 coin_val; // either SWITCH_COIN1 or SWITCH_COIN2 + Uint64 cycles_when_to_enable; // the cycle count that we must have surpassed in order to be able to enable the coin +}; + +//////////////////////// + + +// By RDG === Many Mouse related stuff + +#define MAX_MICE 128 +#define SCROLLWHEEL_DISPLAY_TICKS 100 + + + +typedef struct +{ + int connected; + int x; + int y; + int relx; + int rely; + SDL_Color color; + char name[64]; + Uint32 buttons; + Uint32 scrolluptick; + Uint32 scrolldowntick; + Uint32 scrolllefttick; + Uint32 scrollrighttick; +} Mouse; + +static Mouse mice[MAX_MICE]; + + +///// + +int SDL_input_init(); +int SDL_input_shutdown(); + +// Filters out mouse events if 'bFilteredOut' is true. +// The purpose is so that games that don't use the mouse don't get a bunch of extra mouse +// events which can hurt performance. +void FilterMouseEvents(bool bFilteredOut); + +void SDL_check_input(); + +#ifdef CPU_DEBUG +void toggle_console(); +#endif + +void process_event(SDL_Event *event); +void process_keydown(SDLKey key); +void process_keyup(SDLKey key); +void process_joystick_motion(SDL_Event *event); +void process_joystick_hat_motion(SDL_Event *event); +bool get_consoledown(); +void set_consoledown(bool); +void check_console_refresh(); +void input_enable(Uint8, int); +void input_disable(Uint8, int); +inline void add_coin_to_queue(bool enabled, Uint8 val); +void reset_idle(void); // added by JFA +void set_use_joystick(bool val); +bool set_mouse_mode(int); + +#endif // INPUT_H + diff --git a/io/logger.cpp b/io/logger.cpp new file mode 100644 index 000000000..b39f8d05a --- /dev/null +++ b/io/logger.cpp @@ -0,0 +1,24 @@ +#include "logger.h" + +ILogger::~ILogger() +{ +} + +void NullLogger::DeleteInstance() +{ + delete this; +} + +void NullLogger::Log(const string &strText) +{ + // do nothing, since this is a null logger +} + +NullLogger::NullLogger() +{ +} + +ILogger *NullLogger::GetInstance() +{ + return new NullLogger(); +} diff --git a/io/logger.h b/io/logger.h new file mode 100644 index 000000000..7de9d2ed6 --- /dev/null +++ b/io/logger.h @@ -0,0 +1,34 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include +using namespace std; + +class ILogger +{ +public: + virtual void DeleteInstance() = 0; + + virtual void Log(const string &strText) = 0; +protected: + virtual ~ILogger(); +}; + +// doesn't actually do anything, useful for testing +class NullLogger : public ILogger +{ + friend class LoggerFactory; + +public: + // we want the null logger to be creatable directly without using the factory, so that + // our tests don't need to rely on ConsoleLogger + static ILogger *GetInstance(); + + void DeleteInstance(); + + void Log(const string &strText); +private: + NullLogger(); +}; + +#endif // LOGGER_H diff --git a/io/logger_console.cpp b/io/logger_console.cpp new file mode 100644 index 000000000..ef425bf6a --- /dev/null +++ b/io/logger_console.cpp @@ -0,0 +1,21 @@ +#include "logger_console.h" + +void ConsoleLogger::DeleteInstance() +{ + delete this; +} + +void ConsoleLogger::Log(const string &strText) +{ + printline(strText.c_str()); +} + +ConsoleLogger::ConsoleLogger() +{ +} + +ILogger *ConsoleLogger::GetInstance() +{ + ConsoleLogger *pInstance = new ConsoleLogger(); + return pInstance; +} diff --git a/io/logger_console.h b/io/logger_console.h new file mode 100644 index 000000000..b0d9b39a7 --- /dev/null +++ b/io/logger_console.h @@ -0,0 +1,21 @@ +#ifndef FILE_LOGGER_H +#define FILE_LOGGER_H + +#include "logger.h" +#include "conout.h" + +// logs to the console +class ConsoleLogger : public ILogger +{ + friend class LoggerFactory; +public: + static ILogger *GetInstance(); + void DeleteInstance(); + + void Log(const string &strText); +private: + ConsoleLogger(); +}; + + +#endif // FILE_LOGGER_H diff --git a/io/logger_factory.cpp b/io/logger_factory.cpp new file mode 100644 index 000000000..10a5931ee --- /dev/null +++ b/io/logger_factory.cpp @@ -0,0 +1,19 @@ +#include "logger_factory.h" +#include "logger_console.h" + +ILogger *LoggerFactory::GetInstance(LoggerType type) +{ + ILogger *pInstance = 0; + + switch (type) + { + default: + pInstance = NullLogger::GetInstance(); + break; + case CONSOLE: + pInstance = ConsoleLogger::GetInstance(); + break; + } + + return pInstance; +} diff --git a/io/logger_factory.h b/io/logger_factory.h new file mode 100644 index 000000000..6fb553816 --- /dev/null +++ b/io/logger_factory.h @@ -0,0 +1,18 @@ +#ifndef LOGGER_FACTORY_H +#define LOGGER_FACTORY_H + +#include "logger.h" + +class LoggerFactory +{ +public: + typedef enum + { + NULLTYPE, + CONSOLE, + } LoggerType; + + static ILogger *GetInstance(LoggerType type); +}; + +#endif // LOGGER_FACTORY_H diff --git a/io/mpo_fileio.cpp b/io/mpo_fileio.cpp new file mode 100644 index 000000000..5bb9be3d6 --- /dev/null +++ b/io/mpo_fileio.cpp @@ -0,0 +1,360 @@ +/* + * mpo_fileio.cpp + * + * Copyright (C) 2005 Matthew P. Ownby + * + * This file is part of MPOLIB, a multi-purpose library + * + * MPOLIB 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. + * + * MPOLIB 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 + */ + +// MPO's NOTE: +// I may wish to use MPOLIB in a proprietary product some day. Therefore, +// the only way I can accept other people's changes to my code is if they +// give me full ownership of those changes. + +// mpo_fileio.cpp +// by Matt Ownby + +// Replacement functions for the traditional fopen/fread/fclose/etc functions +// Main purpose: to support files larger than 4 gigs +// Secondary purpose: to not rely on MSCVRT dll in windows + +#include "mpo_fileio.h" + +#ifndef WIN32 +#include // for malloc +#endif + +// if this doesn't crash, you're good to go! +// if anyone knows how to do this check at compile time, let me know!!! +void mpo_test() +{ + if (sizeof(MPO_UINT64) != 8) // make sure this is really 64-bit + { + int i = 0; + int b; + + b = 5 / i; // force crash + } +} + +bool mpo_file_exists(const char *filename) +{ + bool result = false; + mpo_io *io = NULL; + + io = mpo_open(filename, MPO_OPEN_READONLY); + if (io) + { + mpo_close(io); + result = true; + } + return result; +} + +mpo_io *mpo_open(const char *filename, int flags) +{ + mpo_io *io = NULL; + bool success = false; + + // dynamically allocate, will be freed by mpo_close + io = (mpo_io *) malloc(sizeof(mpo_io)); + +#ifdef WIN32 + ZeroMemory(io, sizeof(mpo_io)); + io->handle = INVALID_HANDLE_VALUE; + + if (flags == MPO_OPEN_READONLY) + { + io->handle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + } + else if (flags == MPO_OPEN_READWRITE) + { + io->handle = CreateFile(filename, GENERIC_READ | GENERIC_WRITE,0, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } + else if (flags == MPO_OPEN_CREATE) + { + io->handle = CreateFile(filename, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } + else if (flags == MPO_OPEN_APPEND) // append + { + // will this seek to the end of the file automatically? + io->handle = CreateFile(filename, GENERIC_WRITE, 0, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (io->handle != INVALID_HANDLE_VALUE) + { + mpo_seek(0, MPO_SEEK_END, io); // seek to the end of the file for appending + } + } + else // unknown value, error + { + } + + // if opening the file succeeded + if (io->handle != INVALID_HANDLE_VALUE) + { + /* + // GetFileSizeEx apparently only works for Win2k and WinXP so I reverted to GetFileSize for the older windows + LARGE_INTEGER size; + GetFileSizeEx(io->handle, &size); // get the file size, we always want it.. + io->size = size.QuadPart; + io->eof = false; + result = true; + */ + + DWORD hSize = 0; + DWORD lSize = 0; + lSize = GetFileSize(io->handle, &hSize); + // if getting the file size succeeded + if (lSize != INVALID_FILE_SIZE) + { + io->size = hSize; // assign higher 32-bits initially + io->size <<= 32; // shift up 32-bits + io->size |= lSize; // and merge in lower 32-bit bits + io->eof = false; + + // now try to get the file time + FILETIME last_modified; + if (GetFileTime(io->handle, NULL, NULL, &last_modified)) + { + io->time_last_modified = last_modified.dwHighDateTime; // high part + io->time_last_modified <<= 32; // shift up 32 + io->time_last_modified |= last_modified.dwLowDateTime; // low part + success = true; + } + // else it failed for unknown reasons + } + // else getfilesize failed + } +#else + const char *mode = "rb"; // assume reading + if (flags == MPO_OPEN_CREATE) + { + mode = "wb"; + } + else if (flags == MPO_OPEN_READWRITE) + { + if (mpo_file_exists(filename)) mode = "rb+"; // read/write existing file + else mode = "wb+"; // create file, open in read/write mode + } + else if (flags == MPO_OPEN_APPEND) + { + mode = "ab"; + } + // else unknown... eror + + io->handle = MPO_FOPEN(filename, mode); + if (io->handle) + { + struct stat teh_stats; // to get last modified + MPO_FSEEK(io->handle, 0, SEEK_END); // go to end of file + io->size = MPO_FTELL(io->handle); // get position (total file size) + MPO_FSEEK(io->handle, 0, SEEK_SET); // go to beginning + io->eof = false; + if (fstat(fileno(io->handle), &teh_stats) == 0) + { + io->time_last_modified = teh_stats.st_mtime; + success = true; + } + // else something went wrong (probably won't ever happen so we won't add error handling) + } +#endif + + // if something went wrong + if (!success) + { + free(io); + io = NULL; + } + + return io; +} + +// returns true on success +// EOF is when bytes_read is 0, but true is returned +bool mpo_read (void *buf, size_t bytes_to_read, + MPO_BYTES_READ *bytes_read, mpo_io *io) +{ + bool result = false; + MPO_BYTES_READ backup_bytes_read = 0; // in case their 'bytes_read' is NULL + + // if they don't care what bytes_read is, then we'll just squelch it + if (bytes_read == NULL) + { + bytes_read = &backup_bytes_read; + } + +#ifdef WIN32 + LPDWORD ptr = bytes_read; + if (ReadFile(io->handle, buf, (DWORD) bytes_to_read, ptr, NULL) != 0) + { + result = true; + } + + /* + else + { + char s[160]; + DWORD i = GetLastError(); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, i, 0, s, sizeof(s), NULL); + printline(s); + tmp = "Error message # is " + g_numstr.ToStr((unsigned int) i); + printline(tmp.c_str()); + } + */ + +#else + *bytes_read = fread(buf, 1, bytes_to_read, io->handle); + + // if we read some bytes, or if we properly got to EOF + if ((*bytes_read > 0) || ((*bytes_read == 0) || feof(io->handle) != 0)) + { + result = true; + } +#endif + + // if we hit EOF, set a flag for convenience + if ((*bytes_read) != bytes_to_read) + { + io->eof = true; + } + + return result; +} + +// returns true on success +bool mpo_write (const void *buf, size_t bytes_to_write, unsigned int *bytes_written, mpo_io *io) +{ + bool result = false; + + unsigned int backup_bytes_written = 0; // in case their 'bytes_written' is NULL + + // if they don't care what bytes_written is, then we'll just squelch it + if (bytes_written == NULL) + { + bytes_written = &backup_bytes_written; + } + +#ifdef WIN32 + LPDWORD ptr = (LPDWORD) bytes_written; + if (WriteFile(io->handle, buf, (DWORD) bytes_to_write, ptr, NULL) != 0) + { + result = true; + } +#else + *bytes_written = fwrite(buf, 1, bytes_to_write, io->handle); + if (*bytes_written == bytes_to_write) + { + result = true; + } +#endif + return result; +} + +// fseek replacement +// returns true if seek was successful +bool mpo_seek(MPO_INT64 offset, seek_type type, mpo_io *io) +{ + bool result = false; + +#ifdef WIN32 + /* + // This code (SetFilePointerEx) works but only for Win2k and WinXP so I have commented it out + LARGE_INTEGER l; + l.QuadPart = offset; + LARGE_INTEGER pre_result; + pre_result.QuadPart = -1; + + // if seek is successful + if (SetFilePointerEx(io->handle, l, &pre_result, type) != 0) + { + // result should now contain the current position + } + else + { + pre_result.QuadPart = -1; + } + + result = true; // no decent error checking here + */ + + LONG loffset = (LONG) offset; // NOTE : assumes long is 32-bits + LONG hoffset = (LONG) (offset >> 32); + DWORD pre_result = 0; + + pre_result = SetFilePointer(io->handle, loffset, &hoffset, type); + + // if we potentially got an error ... +// if (pre_result == INVALID_SET_FILE_POINTER) + if (pre_result == -1) // INVALID_SET_FILE_POINTER is -1 but some old visual studio 6's don't have this defined + { + result = false; + pre_result = GetLastError(); // check to see if we really got an error + if (pre_result == NO_ERROR) + { + result = true; + } + } + + // no error + else + { + result = true; + } + +#else + int pre_result = MPO_FSEEK(io->handle, offset, type); + if (pre_result == 0) result = true; +#endif + + return result; +} + +void mpo_close(mpo_io *io) +{ + if (io != NULL) + { +#ifdef WIN32 + CloseHandle(io->handle); +#else + fclose(io->handle); +#endif + io->handle = 0; + io->eof = false; + io->size = 0; + io->time_last_modified = 0; + free(io); // de-allocate + } + // else we cannot reference a NULL pointer +} + +bool mpo_mkdir(const char *dirname) +{ + bool result = false; +#ifdef WIN32 + if (CreateDirectory(dirname, NULL) != 0) result = true; +#else + // create directory with minimal permissions + if (mkdir(dirname, 0700) == 0) + { + result = true; + } +#endif + return result; +} diff --git a/io/mpo_fileio.h b/io/mpo_fileio.h new file mode 100644 index 000000000..3f626cd9b --- /dev/null +++ b/io/mpo_fileio.h @@ -0,0 +1,114 @@ +/* + * mpo_fileio.h + * + * Copyright (C) 2005 Matthew P. Ownby + * + * This file is part of MPOLIB, a multi-purpose library + * + * MPOLIB 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. + * + * MPOLIB 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 + */ + +// MPO's NOTE: +// I may wish to use MPOLIB in a proprietary product some day. Therefore, +// the only way I can accept other people's changes to my code is if they +// give me full ownership of those changes. + +// mpo.h +// by Matt Ownby + +#ifndef MPO_FILEIO_H +#define MPO_FILEIO_H + +#ifdef WIN32 +#include +#else +#include +#include // for fstat +#endif + +#include "numstr.h" // for MPO_UINT64 definition + +#ifdef WIN32 +#define MPO_HANDLE HANDLE +#define MPO_BYTES_READ DWORD +#else +#define MPO_HANDLE FILE * +#define MPO_BYTES_READ size_t + +#ifdef LINUX +#define MPO_FOPEN fopen64 +#define MPO_FSEEK fseeko64 +#define MPO_FTELL ftello64 +#endif + +#ifdef MAC_OSX +#define MPO_FOPEN fopen +#define MPO_FSEEK fseeko +#define MPO_FTELL ftello +#endif + +#endif + +struct mpo_io +{ + MPO_HANDLE handle; // handle of the file (keep this at the beginning of the struct to make it easy to statically initialize) + MPO_UINT64 size; // the size of the file + + // A unit of time representing when this file was last modified. + // It will mean something different in win32 and linux and thus is only useful for + // comparing against other files to see which one was modified most recently. + MPO_UINT64 time_last_modified; + + bool eof; // whether we have reached the End-Of-File +}; + +// ways that file can be opened +enum +{ + MPO_OPEN_READONLY, // opens pre-existing file in read-only mode + MPO_OPEN_READWRITE, // opens pre-existing file in read/write mode, or creates file if it does not exist + MPO_OPEN_CREATE, // creates/overwrites file, for writing purposes + MPO_OPEN_APPEND, // creates/appends file, for writing purposes +}; + +typedef enum +{ +#ifdef WIN32 + MPO_SEEK_SET = FILE_BEGIN, + MPO_SEEK_CUR = FILE_CURRENT, + MPO_SEEK_END = FILE_END + +#else + MPO_SEEK_SET = SEEK_SET, + MPO_SEEK_CUR = SEEK_CUR, + MPO_SEEK_END = SEEK_END +#endif +} seek_type; + +void mpo_test(); +bool mpo_file_exists(const char *filename); + +// returns a pointer to an mpo_io structure if successful, NULL if unsuccessful +mpo_io *mpo_open(const char *filename, int flags); + +bool mpo_read (void *buf, size_t bytes_to_read, MPO_BYTES_READ *bytes_read, mpo_io *io); +bool mpo_write (const void *buf, size_t bytes_to_write, unsigned int *bytes_written, mpo_io *io); +bool mpo_seek(MPO_INT64 offset, seek_type type, mpo_io *io); +void mpo_close(mpo_io *io); + +// Attempts to create a directory (with permissions such that only the user can access that dir) +// 'dirname' is the name of the directory to create, returns on true on success +bool mpo_mkdir(const char *dirname); +#endif // MPO_FILEIO_H diff --git a/io/mpo_mem.h b/io/mpo_mem.h new file mode 100644 index 000000000..b8698f0da --- /dev/null +++ b/io/mpo_mem.h @@ -0,0 +1,53 @@ +#ifndef MPO_MEM_H +#define MPO_MEM_H + +#include // for endian def + +// mpo_mem.h +// by Matt Ownby + +// some memory functions/macros to make memory management more manageable :) + +// does C++ style allocation ... +#define MPO_MALLOC(bytes) new unsigned char[bytes] + +// only frees memory if it hasn't already been freed +#define MPO_FREE(ptr) if (ptr != 0) { delete [] ptr; ptr = 0; } + +//////////////// + +// Endian-macros + +// LOAD_LIL_SINT16: loads little-endian 16-bit value +// Usage: Sint16 val = LOAD_LIL_SINT16(void *ptr); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +// little endian version +#define LOAD_LIL_SINT16(ptr) (Sint16) *((Sint16 *) (ptr)) +#else +// big endian version +#define LOAD_LIL_SINT16(ptr) (Sint16) (*((Uint8 *) (ptr)) | ((*((Uint8 *) (ptr)+1)) << 8)) +#endif + +// LOAD_LIL_UINT32: loads little-endian 32-bit value +// Usage: Uint32 val = LOAD_LIL_UINT32(void *ptr); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +// little endian version +#define LOAD_LIL_UINT32(ptr) (Uint32) *((Uint32 *) (ptr)) +#else +// big endian version +#define LOAD_LIL_UINT32(ptr) (Uint32) (*((Uint8 *) (ptr)) | ((*((Uint8 *) (ptr)+1)) << 8) | ((*((Uint8 *) (ptr)+2)) << 16) | ((*((Uint8 *) (ptr)+3)) << 24)) +#endif + +// STORE_LIL_UINT32: stores 32-bit unsigned 'val' to 'ptr' in little-endian format +// Usage: STORE_LIL_UINT32(void *ptr, Uint32 val); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define STORE_LIL_UINT32(ptr,val) *((Uint32 *) (ptr)) = (val) +#else +#define STORE_LIL_UINT32(ptr,val) *((Uint8 *) (ptr)) = (val) & 0xFF; \ + *(((Uint8 *) (ptr))+1) = ((val) >> 8) & 0xFF; \ + *(((Uint8 *) (ptr))+2) = ((val) >> 16) & 0xFF; \ + *(((Uint8 *) (ptr))+3) = ((val) >> 24) & 0xFF +#endif + + +#endif // MPO_MEM_H diff --git a/io/my_stdio.h b/io/my_stdio.h new file mode 100644 index 000000000..427c15938 --- /dev/null +++ b/io/my_stdio.h @@ -0,0 +1,28 @@ +// my_stdio.h +// by Matt Ownby + +// common stuff that many .cpp files may need to use + +#ifndef MY_STDIO_H +#define MY_STDIO_H + +#ifdef WIN32 + +// we don't want WIN32 using stdio because +// a) it's not available on xbox +// b) it requires MSCVRT.DLL and VS.NET uses a new version that many people don't have +#include + +// win32 doesn't have snprintf +#define snprintf _snprintf +#else + +// non-win32 can just use regular stdio +#include + +#endif // WIN32 + +#include "mpo_fileio.h" + +#endif // MY_STDIO_H + diff --git a/io/network.cpp b/io/network.cpp new file mode 100644 index 000000000..a44296b6c --- /dev/null +++ b/io/network.cpp @@ -0,0 +1,638 @@ +/* + * network.cpp + * + * Copyright (C) 2002 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include +#include // for lousy random number generation +#include +#include + +#ifdef MAC_OSX +#include +#include +#include +#include +#include +#include +#endif + +#ifdef WIN32 +#include +//#include +//#include +//#include +#endif + +#ifdef FREEBSD +#include +#include +#endif + +#ifdef LINUX +#include // MATT : I'm not sure if this is good for UNIX in general so I put it here +#endif + +#ifdef UNIX +#include +#include +#include +#include // for DNS +#include +#include // for write +#endif + + +#include // for crc32 calculation +#include "../io/error.h" +#include "../daphne.h" +#include "network.h" + +// arbitrary port I've chosen to send incoming data +#define NET_PORT 7733 + +// ip address to send data to +// I changed this to 'stats' in case I ever want to change the IP address of the stats +// server without changing the location of the web server. +#define NET_IP "stats.daphne-emu.com" + +// which version of this simple protocol we are using (so the server can support multiple versions) +static const unsigned char PROTOCOL_VERSION = 1; + +#define USERID_FILENAME "userid.bin" + +bool g_send_data_to_server = false; // whether user allows us to send data to server + +//////////////////// + +// disable sending data to server for paranoid users +// (I don't know why anyone should be paranoid, this is open source for crying out loud) +void net_no_server_send() +{ + g_send_data_to_server = false; +} + +// returns a unique (hopefully) randomly generated user id so we can track how many +// different daphne users there are out there +unsigned int get_user_id() +{ + bool id_exists = false; // id already exists? + unsigned int id = 0; + FILE *F = NULL; + + F = fopen(USERID_FILENAME, "rb"); + // if they already have a userid generated previously + if (F) + { + unsigned int len = fread(&id, 1, sizeof(id), F); + + // make sure we read something ... + if (len == sizeof(id)) + { + id_exists = true; + } + fclose(F); + } + + // if we don't have an ID yet then generate one now + if (!id_exists) + { + F = fopen(USERID_FILENAME, "wb"); + if (F) + { +#ifdef UNIX + struct timeval tv; + gettimeofday(&tv, NULL); // get a random number (time) + srand(tv.tv_sec); // seed randomizer with current usec's elapsed (hopefully super random) + id = rand() ^ tv.tv_usec; // hopefully this value will be so random that it will be unique +#endif +#ifdef WIN32 + SYSTEMTIME cur_time; + FILETIME file_time; + GetSystemTime(&cur_time); + SystemTimeToFileTime(&cur_time, &file_time); + srand(file_time.dwHighDateTime); + id = rand() ^ file_time.dwLowDateTime; +#endif + fwrite(&id, sizeof(id), 1, F); + fclose(F); + } + // else we couldn't create so we'll just try again next time + } + + return id; +} + +int g_sockfd = -1; // our socket file descriptor +struct net_packet g_packet; // what we're gonna send + +void net_set_gamename(char *gamename) +{ + strncpy(g_packet.gamename, gamename, sizeof(g_packet.gamename)); +} + +void net_set_ldpname(char *ldpname) +{ + strncpy(g_packet.ldpname, ldpname, sizeof(g_packet.ldpname)); +} + +#ifdef WIN32 +// some code I found to calculate cpu mhz +_inline unsigned __int64 GetCycleCount(void) +{ + _asm _emit 0x0F + _asm _emit 0x31 +} +#endif + +// gets the cpu's mhz (rounds to nearest 50 MHz) +unsigned int get_cpu_mhz() +{ + unsigned int result = 0; + unsigned int mod = 0; +#ifdef LINUX +#ifdef NATIVE_CPU_X86 + FILE *F; + double mhz; + int iRes = 0; + const char *s = "cat /proc/cpuinfo | grep MHz | sed -e 's/^.*: //'"; + F = popen(s, "r"); + if (F) + { + iRes = fscanf(F, "%lf", &mhz); + pclose(F); + } + result = (unsigned int) mhz; +#endif // NATIVE_CPU_X86 +#ifdef NATIVE_CPU_MIPS + result = 294; // assume playstation 2 for now :) +#endif // NATIVE_CPU_MIPS +#endif // LINUX + +#ifdef FREEBSD + FILE *F; + double mhz; + char command[128]="dmesg | grep CPU | perl -e 'while (<>) {if ($_ =~ /\\D+(\\d+).+-MHz.+/) {print \"$1\n\"}}' > /tmp/result.txt"; + system(command); + F = fopen("/tmp/result.txt", "rb"); + if (F) + { + fscanf(F, "%lf", &mhz); + fclose(F); + unlink("/tmp/result.txt"); + } + result = (unsigned int) mhz; +#endif + + +#ifdef WIN32 + unsigned __int64 m_startcycle; + unsigned __int64 m_res; + + m_startcycle = GetCycleCount(); + Sleep(1000); + m_res = GetCycleCount()-m_startcycle; + + result = (unsigned int)(m_res / 1000000); // convert Hz to MHz +#endif + +#ifdef MAC_OSX + long cpuSpeed = 0; + Gestalt(gestaltProcClkSpeed, &cpuSpeed); + result = (unsigned int)(cpuSpeed / 1000000); + return result; +#endif + + // round to nearest 50 MHz + result += 25; // for rounding + mod = result % 50; + result -= mod; + + return result; +} + +// gets the cpu's memory, rounds to nearest 64 megs of RAM +unsigned int get_sys_mem() +{ + unsigned int result = 0; + unsigned int mod = 0; + unsigned int mem = 0; +#ifdef LINUX + FILE *F; + int iRes = 0; + const char *s = "ls -l /proc/kcore | awk '{print $5}'"; + F = popen(s, "r"); + if (F) + { + iRes = fscanf(F, "%u", &mem); // this breaks if they have over 2 gigs of ram :) + pclose(F); + } + +#endif + +#ifdef FREEBSD + size_t len; + len = sizeof(mem); + sysctlbyname("hw.physmem", &mem, &len, NULL, NULL); + +#endif + +#ifdef WIN32 + MEMORYSTATUS memstat; + GlobalMemoryStatus(&memstat); + mem = memstat.dwTotalPhys; +#endif + + result = (mem / (1024*1024)) + 32; // for rounding + mod = result % 64; + result -= mod; + + return result; +} + +char *get_video_description() +{ + static char result[NET_LONGSTRSIZE] = { "Unknown video" }; + +#ifdef LINUX +#ifdef NATIVE_CPU_X86 + FILE *F; + // PCI query fix by Arnaud G. Gibert + const char *s = "lspci | grep -i \"VGA compatible controller\" | awk -F ': ' '{print $2}'"; + F = popen(s, "r"); + if (F) + { + unsigned int len = fread(result, 1, 79, F); + if (len > 1) result[len-1] = 0; // make sure string is null terminated + pclose(F); + } +#endif // NATIVE_CPU_X86 +#ifdef NATIVE_CPU_MIPS + strcpy(result, "Playstation2"); // assume PS2 for now hehe +#endif // MIPS +#endif + +#ifdef FREEBSD + //I haven't found a nice way to get graphic adaptor informations :( +#endif + +#ifdef WIN32 + typedef BOOL (WINAPI *infoproc)(PVOID, DWORD, PVOID, DWORD); + infoproc pEnumDisplayDevices; + HINSTANCE hInstUser32; + DISPLAY_DEVICE DispDev; + bool bEnumDisplayOk = true; // if it's ok to enumerate the display device (winNT may crash when doing this) + + // The call to EnumDisplayDevicesA may crash under WindowsNT. + // Therefore we acquire the Windows version here, and if it's NT, + // skip the following code. + + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + // Try calling GetVersionEx using the OSVERSIONINFOEX structure. + // If that fails, try using the OSVERSIONINFO structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) + { + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + + // if GetVersionEx fails under all circumstances, then we will err on the side of caution and not enumerate + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + { + bEnumDisplayOk = false; + } + } + + // if it's Windows NT, then don't enumerate the display + if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osvi.dwMajorVersion <= 4)) + { + bEnumDisplayOk = false; + } + + // if it's ok to enumerate the display device + if (bEnumDisplayOk) + { + hInstUser32 = LoadLibrary("user32"); + if (hInstUser32) + { + pEnumDisplayDevices = (infoproc) GetProcAddress(hInstUser32, "EnumDisplayDevicesA"); + if (pEnumDisplayDevices) + { + ZeroMemory(&DispDev, sizeof(DISPLAY_DEVICE)); + DispDev.cb = sizeof(DISPLAY_DEVICE); + if ((*pEnumDisplayDevices)(NULL, 0, &DispDev, 0)) + { + strncpy(result, (char *) DispDev.DeviceString, sizeof(result)-1); + } + } + FreeLibrary(hInstUser32); + } + } + // else we can't enumerate +#endif + + return result; +} + +char *get_cpu_name() +{ + static char result[NET_LONGSTRSIZE] = { 0 }; + strcpy(result, "UnknownCPU"); // default ... + +#ifdef NATIVE_CPU_X86 + unsigned int reg_ebx, reg_ecx, reg_edx; +#ifdef WIN32 + _asm + { + xor eax, eax + cpuid + mov reg_ebx, ebx + mov reg_ecx, ecx + mov reg_edx, edx + } +#else + asm + ( + "xor %%eax, %%eax\n\t" + "cpuid\n\t" + : "=b" (reg_ebx), "=c" (reg_ecx), "=d" (reg_edx) + : /* no inputs */ + : "cc", "eax" /* a is clobbered upon completion */ + ); +#endif + + result[0] = (char) ((reg_ebx) & 0xFF); + result[1] = (char) ((reg_ebx >> 8) & 0xFF); + result[2] = (char) ((reg_ebx >> 16) & 0xFF); + result[3] = (char) (reg_ebx >> 24); + + result[4] = (char) ((reg_edx) & 0xFF); + result[5] = (char) ((reg_edx >> 8) & 0xFF); + result[6] = (char) ((reg_edx >> 16) & 0xFF); + result[7] = (char) ((reg_edx >> 24) & 0xFF); + + result[8] = (char) ((reg_ecx) & 0xFF); + result[9] = (char) ((reg_ecx >> 8) & 0xFF); + result[10] = (char) ((reg_ecx >> 16) & 0xFF); + result[11] = (char) ((reg_ecx >> 24) & 0xFF); +#endif // NATIVE_CPU_X86 + +#ifdef NATIVE_CPU_MIPS + strcpy(result, "MIPS R5900 V2.0"); // assume playstation 2 for now +#endif // NATIVE_CPU_MIPS + +#ifdef NATIVE_CPU_SPARC + strcpy(result, "Sparc"); +#endif // NATIVE_CPU_SPARC + +//On Mac, we can tell what type of CPU by simply checking the ifdefs thanks to the universal binary. +#ifdef MAC_OSX +#ifdef __PPC__ + strcpy(result, "PowerPC"); +#else + strcpy(result, "GenuineIntel"); +#endif +#endif + + return result; +} + +char *get_os_description() +{ + static char result[NET_LONGSTRSIZE] = { "Unknown OS" }; + +#ifdef LINUX + struct utsname buf; + unsigned int i = 0; + int uname_result = uname(&buf); + int found_first_period = 0; + + // if uname did not return any error ... + if (uname_result == 0) + { + // find the second period in the linux version, so we can terminate there + for (i = 0; i < (sizeof(result)-10); i++) + { + if (buf.release[i] == '.') + { + // if we haven't found the first period in the linux version yet + if (!found_first_period) + { + found_first_period = 1; + } + + // if we have already found the first period, then this is the second period, + // so get out of the loop + else + { + break; + } + } + } + + strcpy(result, "Linux "); + strncpy(&result[6], buf.release, i); + result[i+6] = 0; // terminate string just in case + } // end if uname worked + +#endif + +#ifdef FREEBSD + size_t len; + char buff[16] = { "Unknown" }; + len = sizeof(buff); + sysctlbyname("kern.ostype", &buff, &len, NULL, NULL); + strcpy(result,buff); + strcat(result," "); + sysctlbyname("kern.osrelease", &buff, &len, NULL, NULL); + strcat(result,buff); +#endif + +#ifdef WIN32 + OSVERSIONINFO info; + memset(&info, 0, sizeof(OSVERSIONINFO)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&info); + switch (info.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + switch (info.dwMinorVersion) + { + case 0: + strcpy(result, "Windows 95"); + break; + case 10: + strcpy(result, "Windows 98"); + break; + case 90: + strcpy(result, "Windows ME"); + break; + default: + strcpy(result, "Windows 95 Derivative"); + break; + } + break; + case VER_PLATFORM_WIN32_NT: + switch (info.dwMinorVersion) + { + case 0: + if (info.dwMajorVersion == 6) + strcpy(result, "Vista"); + else + strcpy(result, "Windows NT/2000"); + break; + case 1: + if (info.dwMajorVersion == 6) + strcpy(result, "Windows 7"); + if (info.dwMajorVersion == 5) + strcpy(result, "Windows XP/.NET"); + break; + case 2: + if (info.dwMajorVersion == 5) + strcpy(result, "Windows XP x64"); + break; + default: + strcpy(result, "Windows NT Derivative"); + break; + } + break; + default: + strcpy(result, "Unknown Windows"); + break; + } +#endif + +#ifdef SOLARIS + strcpy(result, "Solaris"); +#endif + +#ifdef MAC_OSX + strcpy(result, "Mac OSX"); +#endif + + return result; + +} + +// send stats to server +void net_send_data_to_server() +{ + struct sockaddr_in saRemote; + struct hostent *info = NULL; + char ip[81]; + + if (!g_send_data_to_server) return; // if user forbids data to be sent, don't do it + +#ifdef DEBUG + // I don't wanna mess up the server stats with people trying to debug daphne + return; +#endif + +#ifdef WIN32 + // initialize Winschlock + WSADATA wsaData; + + WSAStartup(MAKEWORD(1,1), &wsaData ); +#endif + + info = gethostbyname(NET_IP); // do DNS to convert address to numbers + + // if the DNS resolution worked + if (info) + { +// inet_ntop(AF_INET, info->h_addr, ip, sizeof(ip)); + sprintf(ip, "%u.%u.%u.%u", (unsigned char) info->h_addr_list[0][0], + (unsigned char) info->h_addr_list[0][1], + (unsigned char) info->h_addr_list[0][2], + (unsigned char) info->h_addr_list[0][3]); + + g_sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (g_sockfd != -1) + { + memset(&saRemote, 0, sizeof(saRemote)); + saRemote.sin_family = AF_INET; + saRemote.sin_addr.s_addr = inet_addr(ip); // inet_addr is broken and should not be used + saRemote.sin_port = htons(NET_PORT); + + // if we are able to connect to socket successfully + if (connect(g_sockfd, (struct sockaddr *) &saRemote, sizeof(saRemote)) == 0) + { + g_packet.user_id = get_user_id(); + g_packet.os = OS_UNKNOWN; +#ifdef WIN32 + g_packet.os = OS_WIN32; +#endif +#ifdef LINUX +#ifdef NATIVE_CPU_X86 + g_packet.os = OS_X86_LINUX; +#endif +#ifdef NATIVE_CPU_MIPS + g_packet.os = OS_PS2_LINUX; +#endif +#endif // end LINUX + +#ifdef FREEBSD + g_packet.os = OS_X86_FREEBSD; +#endif + +#ifdef SOLARIS +#ifdef NATIVE_CPU_SPARC + g_packet.os = OS_SPARC_SOLARIS; +#endif +#endif // end SOLARIS + +#ifdef MAC_OSX + g_packet.os = OS_MAC_OSX; +#endif + + // safety check + if (g_packet.os == OS_UNKNOWN) + { + printerror("your OS is unknown in network.cpp, please fix this"); + } + + strncpy(g_packet.os_desc, get_os_description(), sizeof(g_packet.os_desc)); + g_packet.protocol = PROTOCOL_VERSION; + g_packet.mhz = get_cpu_mhz(); + g_packet.mem = get_sys_mem(); + strncpy(g_packet.video_desc, get_video_description(), sizeof(g_packet.video_desc)); + strncpy(g_packet.cpu_name, get_cpu_name(), sizeof(g_packet.cpu_name)); + strncpy(g_packet.daphne_version, get_daphne_version(), sizeof(g_packet.daphne_version)); + + // now compute CRC32 of the rest of the packet + g_packet.crc32 = crc32(0L, Z_NULL, 0); + g_packet.crc32 = crc32(g_packet.crc32, (unsigned char*) &g_packet, sizeof(g_packet) - sizeof(g_packet.crc32)); + send(g_sockfd, (const char *) &g_packet, sizeof(g_packet), 0); + } + // else connection was refused (server down) + +#ifdef WIN32 + closesocket(g_sockfd); +#else + close(g_sockfd); // we're done! +#endif + } + } // end if DNS look-up worked +} diff --git a/io/network.h b/io/network.h new file mode 100644 index 000000000..a8eaf1b93 --- /dev/null +++ b/io/network.h @@ -0,0 +1,64 @@ +/* + * network.h + * + * Copyright (C) 2002 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// THESE VALUES MUST NOT CHANGE BECAUSE THE SERVER IS RELYING ON THEM +#define OS_UNKNOWN 0 +#define OS_X86_LINUX 1 +#define OS_WIN32 2 +#define OS_X86_FREEBSD 3 +#define OS_PS2_LINUX 4 +#define OS_SPARC_SOLARIS 5 +#define OS_MAC_OSX 6 +#define OS_XBOX_NATIVE 7 +/////////////////////////////////////////////////////////////////////// + +#define NET_STRSIZE 15 +#define NET_LONGSTRSIZE 80 + +struct net_packet +{ + unsigned char protocol; + unsigned int user_id; + unsigned char os; + char os_desc[NET_LONGSTRSIZE]; // long OS description + unsigned int mhz; + unsigned int mem; + char cpu_name[NET_LONGSTRSIZE]; // long cpu description + char video_desc[NET_LONGSTRSIZE]; // long video description + char daphne_version[NET_STRSIZE]; + char gamename[NET_STRSIZE]; + char ldpname[NET_STRSIZE]; + + // keep this always at the end + unsigned int crc32; // a checksum of the preceeding data +}; + +void net_no_server_send(); +unsigned int get_user_id(); +void net_set_gamename(char *gamename); +void net_set_ldpname(char *ldpname); +unsigned int get_cpu_mhz(); +unsigned int get_sys_mem(); +char *get_video_description(); +char *get_cpu_name(); +char *get_os_description(); +void net_send_data_to_server(); diff --git a/io/numstr.cpp b/io/numstr.cpp new file mode 100644 index 000000000..dc0894415 --- /dev/null +++ b/io/numstr.cpp @@ -0,0 +1,288 @@ +/* + * mpo_numstr.cpp + * + * Copyright (C) 2005 Matthew P. Ownby + * + * This file is part of MPOLIB, a multi-purpose library + * + * MPOLIB 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. + * + * MPOLIB 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 + */ + +// MPO's NOTE: +// I may wish to use MPOLIB in a proprietary product some day. Therefore, +// the only way I can accept other people's changes to my code is if they +// give me full ownership of those changes. + +#include "numstr.h" + +#ifndef WIN32 +#include // for toupper +#endif + +const char *DIGITS = "0123456789ABCDEF"; + +// NOTE : this function doesn't do full safety checking in the interest of simplicity and speed +int numstr::ToInt32(const char *str) +{ + const int BASE = 10; // for now we always assume base is 10 because I never seem to use anything else + int result = 0; + bool found_first_digit = false; // whether we have found the first digit or not + int sign_mult = 1; // 1 if the number is positive, -1 if it's negative + + for (unsigned int i = 0; i < my_strlen(str); i++) + { + if (!found_first_digit) + { + if (is_digit(str[i], BASE)) + { + found_first_digit = true; + } + + // if it a negative number? + else if (str[i] == '-') + { + sign_mult = -1; + } + + // else it's an unknown character, so we ignore it until we get to the first digit + } + + // note: we do not want this to be an "else if" because the above 'if' needs to flow into this + if (found_first_digit) + { + // make sure we aren't dealing with any non-integers + if ((str[i] >= '0') && (str[i] <= '9')) + { + result *= BASE; + result += str[i] - '0'; + } + // else we've hit unknown characters so we're done + else + { + break; + } + } + } + + return result * sign_mult; +} + +unsigned int numstr::ToUint32(const char *str, int base) +{ + unsigned int u = 0; + ToUint(str,u,base); + return u; +} + +MPO_UINT64 numstr::ToUint64(const char *str, int base) +{ + MPO_UINT64 u = 0; + ToUint(str,u,base); + return u; +} + +double numstr::ToDouble(const char *str) +{ + const double BASE = 10.0; // this makes it easier for now ... + const double BASE_DIVIDE = 0.1; // because multiplaying by 0.1 is faster than dividing by 10.0 + bool found_period = false; // whether we've encountered the period in the double yet + bool found_first_digit = false; + double result = 0.0; + double divide_by = 1.0; // after we pass the decimal point, we need to divide subsequent numbers to put them in their proper sphere + double sign_mult = 1.0; // final result is multiplied by this to set the sign + + for (unsigned int i = 0; i < my_strlen(str); i++) + { + if (!found_first_digit) + { + if (is_digit(str[i], (int) BASE)) + { + found_first_digit = true; + } + + // if it a negative number? + else if (str[i] == '-') + { + sign_mult = -1.0; + } + + else if (str[i] == '.') + { + found_period = true; + } + + // else it's an unknown character, so we ignore it until we get to the first digit + } + + // note: we do not want this to be an "else if" because the above 'if' needs to flow into this + if (found_first_digit) + { + // make sure we aren't dealing with any non-integers + if ((str[i] >= '0') && (str[i] <= '9')) + { + // if we haven't encountered the decimal place yet + if (found_period == false) + { + result *= BASE; + result += str[i] - '0'; + } + // if we are passed the decimal place + else + { + divide_by *= BASE_DIVIDE; // each new digit we find needs to be divided by 10x the previous divide_by value + result += ((str[i] - '0') * divide_by); + } + } + // else if we've hit the decimal point + else if (str[i] == '.') + { + found_period = true; + } + // else we've hit unknown characters so we're done + else + { + break; + } + } + } + + return result * sign_mult; +} + +// DUMMY functions to force template instantiation +// (since I can't figure out how to make the compiler do this without! arrgh) + +string numstr::ToStr(int num, int base, unsigned int min_digits) +{ + unsigned int dummy = 0; // see comment in .h for IToStr for explanation + return IToStr(num, dummy, base, min_digits); +} + +string numstr::ToStr(MPO_INT64 num, int base, unsigned int min_digits) +{ + MPO_UINT64 dummy = 0; // see comment in .h for IToStr for explanation + return IToStr(num, dummy, base, min_digits); +} + +string numstr::ToStr(unsigned char c, int base, unsigned int min_digits) +{ + return UToStr(c, base, min_digits); +} + +string numstr::ToStr(unsigned int u, int base, unsigned int min_digits) +{ + return UToStr(u, base, min_digits); +} + +string numstr::ToStr(MPO_UINT64 u, int base, unsigned int min_digits) +{ + return UToStr(u, base, min_digits); +} + +string numstr::ToStr(double d, unsigned int min_digits_before, unsigned int min_digits_after, unsigned int max_digits_after) +{ + string result = "(overflow)"; + const double BASE = 10.0; // we will only support base 10 with doubles to simplify things ... + unsigned int decimal_length = 0; + + // bounds check: make sure the double is within our limits (2^62 was the highest I could get it to work without introducing overflow errors) + if ((d <= 4611686018427387904.0) && (d >= -4611686018427387904.0)) + { + MPO_INT64 int64_portion = (MPO_INT64) d; // strip off floating point part + d = d - int64_portion; // isolate just the decimal portion + + result = ToStr(int64_portion, 10, min_digits_before); // use our other function to calculate the int portion + + result = result + "."; // add decimal place, it will always be displayed even if there is no fractional value to this number + + if (d < 0) d *= -1.0; // force d to be positive + + // NOTE : d will now always be positive + do + { + d *= BASE; // move decimal point one notch to the right + int int_portion = (int) d; // grab the number that is above the decimal point + result = result + DIGITS[int_portion]; + d = d - int_portion; + decimal_length++; // gotta keep track of this for 'min_digits_after' calculation + } while ((d != 0.0) && (max_digits_after > decimal_length)); + + while (decimal_length < min_digits_after) + { + result = result + "0"; // pad trailing zeroes + decimal_length++; + } + } + // else return default result to indicate error + + return result; +} + +string numstr::ToUnitStr(MPO_UINT64 u) +{ + string result; + double d; + + // if less than 1 k + if (u < 1024) + { + result = ToStr(u) + " B"; + } + + // less than 1 meg + else if (u < 1048576) + { + d = u * 0.0009765625; // same as dividing by 1024 + result = ToStr(d, 0, 1, 2) + " KiB"; + } + + // less than 1 gig + else if (u < 1073741824) + { + d = u / (1048576.0); // convert to megs + result = ToStr(d, 0, 1, 2) + " MiB"; + } + + // else leave it as gigs, we won't go any higher for now + else + { + d = u / (1073741824.0); // convert to gigs + result = ToStr(d, 0, 1, 2) + " GiB"; + } + + return result; +} + +unsigned int numstr::my_strlen(const char *s) +{ + unsigned int i = 0; + while (s[i] != 0) i++; + return i; +} + +//////////////////////////////// +// private funcs + +inline bool numstr::is_digit(char ch, int base) +{ + if ((base == 10) && (ch >= '0') && (ch <= '9')) return(true); + else if ((base == 16) && ( + ((ch >= '0') && (ch <= '9')) || + ((toupper(ch) >= 'A') && (toupper(ch) <= 'F')) + )) return(true); + // else no other base is supported + + return false; +} diff --git a/io/numstr.h b/io/numstr.h new file mode 100644 index 000000000..3c7600282 --- /dev/null +++ b/io/numstr.h @@ -0,0 +1,189 @@ +/* + * mpo_numstr.h + * + * Copyright (C) 2005 Matthew P. Ownby + * + * This file is part of MPOLIB, a multi-purpose library + * + * MPOLIB 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. + * + * MPOLIB 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 + */ + +// MPO's NOTE: +// I may wish to use MPOLIB in a proprietary product some day. Therefore, +// the only way I can accept other people's changes to my code is if they +// give me full ownership of those changes. + +// numstr.h +// by Matt Ownby + +#ifndef NUMSTR_H +#define NUMSTR_H + +#ifdef WIN32 +typedef unsigned __int64 MPO_UINT64; +typedef __int64 MPO_INT64; +#else +typedef unsigned long long MPO_UINT64; +typedef long long MPO_INT64; +#endif + +#include + +using namespace std; + +class numstr +{ +public: + static int ToInt32(const char *str); + static unsigned int ToUint32(const char *str, int base = 10); + static MPO_UINT64 ToUint64(const char *str, int base = 10); + static double ToDouble(const char *s); + static string ToStr(int i, int base = 10, unsigned int min_digits = 0); + static string ToStr(MPO_INT64 num, int base = 10, unsigned int min_digits = 0); + static string ToStr(unsigned int u, int base = 10, unsigned int min_digits = 0); + static string ToStr(unsigned char u, int base = 10, unsigned int min_digits = 0); + static string ToStr(MPO_UINT64 u, int base = 10, unsigned int min_digits = 0); + + // NOTE : double cannot be > 2^63 (size of signed 64-bit int) or this conversion will fail + static string ToStr(double d, unsigned int min_digits_before = 0, unsigned int min_digits_after = 0, unsigned int max_digits_after = 5); + + // converts raw bytes to KiB, MiB, or GiB to make it more readable + static string ToUnitStr(MPO_UINT64 u); + + static unsigned int my_strlen(const char *s); +private: + inline static bool is_digit(char ch, int base); + + // NOTE : this is put in the .h because VC++ 6.0 can't handle it any other way + // convert a string to an unsigned number + template static void ToUint(const char *str, T &result, int base) + { + bool found_first_digit = false; // whether we have found the first digit or not + + result = 0; + + // go through each digit + for (unsigned int i = 0; i < my_strlen(str); i++) + { + if (!found_first_digit) + { + if (is_digit(str[i], base)) + { + found_first_digit = true; + } + + // else it's an unknown character, so we ignore it until we get to the first digit + } + + // note: we do not want this to be an "else if" because the above 'if' needs to flow into this + if (found_first_digit) + { + // converting from base10 ASCII + if ((base == 10) && (str[i] >= '0') && (str[i] <= '9')) + { + result *= 10; + result += str[i] - '0'; + } + // converting from HEX ASCII + else if (base == 16) + { + // if the number is between '0' and '9' + if ((str[i] >= '0') && (str[i] <= '9')) + { + result *= 16; + result += str[i] - '0'; + } + // if the number is between 'A' and 'F' + else if ((toupper(str[i]) >= 'A') && (toupper(str[i]) <= 'F')) + { + result *= 16; + result += (toupper(str[i]) - 'A') + 10; // A is the same as 10 decimal + } + } + // else other bases are unsupported + else + { + break; + } + } + } + } + + // NOTE : this is put in the .h file because VC++ 6.0 can't handle it any other way + // convert unsigned number to string + template static string UToStr(T u, int base = 10, unsigned int min_digits = 0) + { + string result = ""; + const char *DIGITS = "0123456789ABCDEF"; + + do + { + result = DIGITS[(u % base)] + result; + u = u / base; + } while (u != 0); + + // pad the front of the number with 0's to satisfy the min_digits requirement + while (result.length() < min_digits) + { + result = "0" + result; + } + + return result; + } + + // NOTE : this is put in the .h file because VC++ 6.0 can't handle it any other way + // convert unsigned number to string + // NOTE #2: the UT class is just an unsigned version of the T class because I couldn't + // figure out how to do (unsigned T) in this function without getting a syntax error. + template static string IToStr(T num, UT unsigned_num, int base = 10, unsigned int min_digits = 0) + { + string result = ""; + const char *DIGITS = "0123456789ABCDEF"; + bool negative = false; // whether the number is negative + UT i = 0; + + // we will only support negative numbers with base 10 + if (base == 10) + { + if (num < 0) + { + num *= -1; // make it positive + negative = true; + } + } + + i = (UT) num; // now convert it to an unsigned number. this makes negative numbers positive for non-base 10 representations + + do + { + result = DIGITS[(i % base)] + result; + i = i / base; + } while (i != 0); + + // pad the front of the number with 0's to satisfy the min_digits requirement + while (result.length() < min_digits) + { + result = "0" + result; + } + + if (negative) result = "-" + result; // add - sign to the front + + return result; + } + + +}; + +#endif // NUMSTR_H diff --git a/io/unzip.cpp b/io/unzip.cpp new file mode 100644 index 000000000..5b8509647 --- /dev/null +++ b/io/unzip.cpp @@ -0,0 +1,1346 @@ +/* unzip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read unzip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char unz_copyright[] = + " unzip 0.15 Copyright 1998 Gilles Vollant "; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ +// FILE* file; /* io structore of the zipfile */ + mpo_io *file; // MPO + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ +// FILE* file; /* io structore of the zipfile */ + mpo_io *file; // MPO + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +/* +local int unzlocal_getByte(FILE *fin, int *pi) +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} +*/ + +// MPO rewrote this function to use mpo_io +local int unzlocal_getByte(mpo_io *fin, int *pi) +{ + unsigned char c; + + if (mpo_read(&c, 1, NULL, fin)) + { + if (fin->eof) + { + return UNZ_EOF; + } + else + { + *pi = (int) c; + return UNZ_OK; + } + } + else + { + return UNZ_ERRNO; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +//local int unzlocal_getShort ( FILE *fin, uLong *pX) +local int unzlocal_getShort ( mpo_io *fin, uLong *pX) // MPO +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +//local int unzlocal_getLong (FILE *fin, uLong *pX) +local int unzlocal_getLong (mpo_io *fin, uLong *pX) // MPO +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char *fileName1, const char *fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare ( + const char* fileName1, + const char* fileName2, + int iCaseSensitivity) +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir( + //FILE *fin) + mpo_io *fin) // MPO +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + // start MPO +// if (fseek(fin,0,SEEK_END) != 0) +// return 0; + +// uSizeFile = ftell( fin ); + mpo_seek(0, MPO_SEEK_END, fin); // probably not necessary, but just in case + uSizeFile = (uLong) fin->size; // WARNING : we assume that we won't handle any huge .zip files + // stop MPO + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + //if (fseek(fin,uReadPos,SEEK_SET)!=0) + if (!mpo_seek(uReadPos, MPO_SEEK_SET, fin)) // MPO + break; + +// if (fread(buf,(uInt)uReadSize,1,fin)!=1) + if (!mpo_read(buf, uReadSize, NULL, fin) || fin->eof) // MPO + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen ( + const char *path) +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; +// FILE * fin ; + mpo_io *fin = NULL; // MPO + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + // start MPO +// fin=fopen(path,"rb"); +// if (fin==NULL) + fin = mpo_open(path, MPO_OPEN_READONLY); + if (!fin) + // stop MPO + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + +// if (fseek(fin,central_pos,SEEK_SET)!=0) + if (!mpo_seek(central_pos, MPO_SEEK_SET, fin)) // MPO + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + +// fclose(s->file); + mpo_close(s->file); // MPO + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo ( + unzFile file, + unz_global_info *pglobal_info) +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate ( + uLong ulDosDate, + tm_unz* ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal ( + unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; +// if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + if (!mpo_seek(s->pos_in_central_dir+s->byte_before_the_zipfile, MPO_SEEK_SET, s->file)) // MPO + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) // MPO + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) +// if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + if (!mpo_read(szFileName, uSizeRead, NULL, s->file) || s->file->eof) // MPO + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + if (mpo_seek(lSeek, MPO_SEEK_CUR, s->file)) // MPO + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) +// if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + if (!mpo_read(extraField, uSizeRead, NULL, s->file) || s->file->eof) // MPO + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + if (mpo_seek(lSeek, MPO_SEEK_CUR, s->file)) // MPO + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) +// if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + if (!mpo_read(szComment, uSizeRead, NULL, s->file) || s->file->eof) // MPO + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo ( + unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile ( + unzFile file) +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile ( + unzFile file) +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile ( + unzFile file, + const char *szFileName, + int iCaseSensitivity) +{ + unz_s* s; + int err; + + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader ( + unz_s* s, + uInt* piSizeVar, + uLong *poffset_local_extrafield, + uInt *psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + +// if (fseek(s->file,s->cur_file_info_internal.offset_curfile + +// s->byte_before_the_zipfile,SEEK_SET)!=0) + if (!mpo_seek(s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile, + MPO_SEEK_SET, s->file)) // MPO + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) // MPO + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) // MPO + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) // MPO + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) // MPO + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ // MPO + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ // MPO + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ // MPO + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ // MPO + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) // MPO + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) // MPO + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile ( + unzFile file) +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile ( + unzFile file, + voidp buf, + unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; +// if (fseek(pfile_in_zip_read_info->file, +// pfile_in_zip_read_info->pos_in_zipfile + +// pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + if (!mpo_seek(pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, MPO_SEEK_SET, + pfile_in_zip_read_info->file)) // MPO + return UNZ_ERRNO; +// if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, +// pfile_in_zip_read_info->file)!=1) + if (!mpo_read(pfile_in_zip_read_info->read_buffer, uReadThis, NULL, + pfile_in_zip_read_info->file) || pfile_in_zip_read_info->file->eof) // MPO + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell ( + unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof ( + unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield ( + unzFile file, + voidp buf, + unsigned len) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + +// if (fseek(pfile_in_zip_read_info->file, +// pfile_in_zip_read_info->offset_local_extrafield + +// pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + if (!mpo_seek(pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, MPO_SEEK_SET, + pfile_in_zip_read_info->file)) // MPO + return UNZ_ERRNO; + +// if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + if (!mpo_read(buf, size_to_read, NULL, pfile_in_zip_read_info->file) + || pfile_in_zip_read_info->file->eof) // MPO + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile ( + unzFile file) +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment ( + unzFile file, + char *szComment, + uLong uSizeBuf) +{ +// int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + +// if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + if (!mpo_seek(s->central_pos+22, MPO_SEEK_SET, s->file)) // MPO + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; +// if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + if (!mpo_read(szComment, uReadThis, NULL, s->file) || s->file->eof) // MPO + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} diff --git a/io/unzip.h b/io/unzip.h new file mode 100644 index 000000000..b3a16db05 --- /dev/null +++ b/io/unzip.h @@ -0,0 +1,283 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +// start MATT +#ifdef WIN32 +#pragma warning (disable:4131) // disable the warning about using old-styled parameter +#endif +// end MATT + +#ifndef _unz_H +#define _unz_H + +#include "mpo_fileio.h" // MPO, for non-fopen file I/O + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/ldp-out/Makefile b/ldp-out/Makefile new file mode 100644 index 000000000..f39a0a4b2 --- /dev/null +++ b/ldp-out/Makefile @@ -0,0 +1,21 @@ +# sub Makefile for ldp-out + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = ldp.o framemod.o ldp-vldp.o ldp-vldp-audio.o ldp-vldp-gl.o + +.SUFFIXES: .cpp + +all: ${OBJS} + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +clean: + rm -f ${OBJS} *.d + diff --git a/ldp-out/framemod.cpp b/ldp-out/framemod.cpp new file mode 100644 index 000000000..499799340 --- /dev/null +++ b/ldp-out/framemod.cpp @@ -0,0 +1,216 @@ +/* + * framemod.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +// framemod.cpp +// by Matt Ownby + +// contains functions to convert the regular DL/SA NTSC frames to other formats such as PAL + +#include "framemod.h" +#include "../daphne.h" // for get_frame_modifer +#include "../io/conout.h" + +// returns 0 if no frame conversion is needed, else it returns a 1 +bool need_frame_conversion() +{ + + // if we are using a search offset, a SA91 disc, or PAL, + // return non-zero + return( (get_search_offset() != 0) || (get_frame_modifier() != MOD_NONE)); + +} + +// returns the Frames Per Kilosecond of the target disc that we are converting frames to +unsigned int get_frame_conversion_fpks() +{ + unsigned int uResult = 0; + + switch (get_frame_modifier()) + { + case MOD_SA91: + uResult = 29970; + break; + case MOD_PAL_DL: + case MOD_PAL_SA: + case MOD_PAL_DL_SC: + case MOD_PAL_SA_SC: + uResult = 25000; + break; + default: + printline("Error in get_frame_conversion_fpks, no frame modifier is enabled"); + break; + }; + + return uResult; +} + +// converts a standard DL/SA '83 NTSC frame to PAL, Space Ace'91, etc ... +// the resulting frame is returned +Uint32 do_frame_conversion(int source_frame) +{ + + double result_frame = (double) source_frame; // it needs to be a float for precise math + int search_offset = get_search_offset(); + + result_frame = result_frame + search_offset; // apply any existing search offsets + + // if we are using space ace 91 we need to convert from 24 FPS to 30 FPS and add a time constant + if (get_frame_modifier() == MOD_SA91) + { + // if the frame in question is one of the slides at the beginning, + // we need to do a more thought-out conversion + if (result_frame <= 145) + { + // frames 40 through 75 + if ((result_frame >= 40) && (result_frame <= 75)) + { + result_frame = 151; + } + // frames 112 through 139 + else if ((result_frame >= 112) && (result_frame <= 139)) + { + result_frame = 151; + } + else + { + switch ( (int) result_frame) + { + case 37: + case 38: + case 39: + result_frame = 145; + break; + case 76: + case 77: + case 78: + result_frame = 169; + break; + case 79: + case 80: + case 81: + result_frame = 175; + break; + case 82: + case 83: + case 84: + case 85: + case 86: + case 87: + result_frame = 217; + break; + case 88: + case 89: + case 90: + result_frame = 121; + break; + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 100: + case 101: + case 102: + result_frame = 151; + break; + case 97: + case 98: + case 99: + case 142: + case 143: + case 144: + case 145: + result_frame = 145; + break; + + // if there is no good match, just use space ace logo + default: + result_frame = 1; + } // end switch + } + } + + // if frame to be modified is greater than 145 + else + { + result_frame = result_frame / 23.976; // convert frames to seconds + result_frame += 7.80807717679; // add time difference between SA '83 and SA '91 + result_frame *= 29.97; // convert seconds to SA91 frames + result_frame += 0.5; // add 0.5 so when truncating, the average becomes the resulting frame + } + } // end if Space Ace 91 + + // regular Dragon's Lair PAL conversion + else if (get_frame_modifier() == MOD_PAL_DL) + { + result_frame = result_frame - 152; + + // catch potential error + if (result_frame < 1) + { + result_frame = 1; + printline("NOTE: NTSC frame requested is not available on PAL DL disc"); + } + } + + // Space Ace PAL conversion + else if (get_frame_modifier() == MOD_PAL_SA) + { + result_frame = result_frame * (25.0 / 23.976); // convert NTSC frames to PAL frames + // NTSC and PAL discs have a 1:1 time correspondance + result_frame += 0.5; // add 0.5 so when truncating, the average becomes the resulting frame + } + + // Dragon's Lair PAL for the Software Corner conversion + else if (get_frame_modifier() == MOD_PAL_DL_SC) + { + result_frame = result_frame - 230; + + // catch potential error + if (result_frame < 1) + { + result_frame = 1; + printline("NOTE: NTSC frame requested is not available on DL Software Corner disc"); + } + } + + // Space Ace PAL Software Corner conversion + else if (get_frame_modifier() == MOD_PAL_SA_SC) + { + result_frame = result_frame * (25.0 / 23.976); // convert NTSC frames to PAL frames + // NTSC and PAL '83 Space Ace discs have a 1:1 time correspondance + result_frame += 79.5; + // Software Corner disc has 79 extra frames than PAL Space Ace + // add 0.5 to round to the nearest whole number when truncating + } + + // bug catcher + else + { + printline("Bug in framemod.cpp, unknown frame modifier!"); + } + + return( (Uint32) result_frame); + +} diff --git a/ldp-out/framemod.h b/ldp-out/framemod.h new file mode 100644 index 000000000..d266c73a1 --- /dev/null +++ b/ldp-out/framemod.h @@ -0,0 +1,36 @@ +/* + * framemod.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FRAMEMOD_H +#define FRAMEMOD_H + +enum { MOD_NONE, MOD_SA91, MOD_PAL_DL, MOD_PAL_SA, MOD_PAL_DL_SC, MOD_PAL_SA_SC }; // frame modifiers + +////////////////////////////////////////////// + +#include // for data types + +bool need_frame_conversion(); +unsigned int get_frame_conversion_fpks(); +Uint32 do_frame_conversion(int source_frame); + +#endif diff --git a/ldp-out/ldp-vldp-audio.cpp b/ldp-out/ldp-vldp-audio.cpp new file mode 100644 index 000000000..06b27a8ce --- /dev/null +++ b/ldp-out/ldp-vldp-audio.cpp @@ -0,0 +1,716 @@ +/* + * ldp-vldp-audio.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// LDP-VLDP-AUDIO.CPP +// by Matt Ownby + +// handles the audio portion of VLDP (using Ogg Vorbis) + +#ifdef WIN32 +#pragma warning (disable:4100) // disable the warning about unreferenced formal parameters (MSVC++) +#endif + +#ifdef UNIX +//#define TRY_MMAP 1 // NOTE : this seems to fail on read-only filesystems (such as NTFS mounted from linux) +#endif + +#include "../timer/timer.h" +#include "../io/conout.h" +#include "../io/mpo_fileio.h" +#include "../sound/sound.h" +#include "ldp-vldp.h" + +#ifdef DEBUG +#include // this may include an extra .DLL in windows that I don't want to rely on +#endif + +#include +#include +#include +#include + +#ifndef GP2X +#include // OGG VORBIS specific headers +#include +#else +// gp2x ogg vorbis decoding files +#include +#include +#endif + +#ifdef TRY_MMAP +#include +#endif + +// how much uncompressed audio we deal with at a time +#define AUDIO_BUF_CHUNK 4096 + +// Macros to lock and unlock the mutex for the audio to make sure we aren't playing audio while +// we are loading or seeking +#define OGG_LOCK SDL_mutexP(g_ogg_mutex) +#define OGG_UNLOCK SDL_mutexV(g_ogg_mutex) + +///////////////////////////////////////// + +typedef void *(*audiocopyproc)(void *dest, const void *src, size_t bytes_to_copy); +audiocopyproc paudiocopy = memcpy; // pointer to the audio copy procedure (defaults to memcpy) + +SDL_mutex *g_ogg_mutex = NULL; +mpo_io *g_pIOAudioHandle = NULL; +OggVorbis_File s_ogg; + +Uint32 g_audio_filesize = 0; // total size of the audio stream +Uint32 g_audio_filepos = 0; // the position in the file of our audio stream +Uint8 *g_big_buf = NULL; // holds entire Ogg stream in RAM :) +bool g_audio_ready = false; // whether audio is ready to be parsed +bool g_audio_playing = false; // whether the audio is to be playing or not +Uint32 g_playing_timer = 0; // the time at which we began playing audio +Uint32 g_samples_played = 0; // how many samples have played since we've been timing +bool g_audio_left_muted = false; // left audio channel enabled +bool g_audio_right_muted = false; // right audio channel enabled + +#ifdef AUDIO_DEBUG +Uint64 g_u64CallbackByteCount = 0; +unsigned int g_uCallbackFloodTimer = 0; +unsigned int g_uCallbackDbgTimer = 0; +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +// resets mm states +void mmreset() +{ + g_audio_filepos = 0; // rewind back to position #0 +} + +// replaces fread +size_t mmread (void *ptr, size_t size, size_t nmemb, void *datasource) +{ + size_t bytes_to_read = size * nmemb; // how many bytes to be read + Uint8 *src = ((Uint8 *) datasource) + g_audio_filepos; // where to get the data from + +// printf("mmread being called.. size is %d, nmemb is %d, bytes_to_read is %d\n", size, nmemb, bytes_to_read); + + if (g_audio_filepos + bytes_to_read > g_audio_filesize) + { + bytes_to_read = 0; + if (g_audio_filepos < g_audio_filesize) + { + bytes_to_read = g_audio_filesize - g_audio_filepos; + } + } + + if (bytes_to_read != 0) + { + memcpy(ptr, src, bytes_to_read); // copy the memory + g_audio_filepos += bytes_to_read; + } + + return (bytes_to_read); +} + +#ifdef WIN32 +#define int64_t __int64 +#endif + +int mmseek (void *datasource, int64_t offset, int whence) +{ + int result = -1; + +// printf("mmseek being called, whence is %d\n", whence); + + // just to get rid of warnings + if (datasource) + { + } + + switch (whence) + { + case SEEK_SET: + // bug fix by Arnaud Gibert + if (offset <= g_audio_filesize) + { + // make sure offset is positive so we don't get into trouble + if (offset >= 0) + { + g_audio_filepos = (Uint32) offset; + } + else + { + printline("mmseek, SEEK_SET used with a negative offset!"); + } + result = 0; + } + break; + case SEEK_CUR: + if (offset + g_audio_filepos <= g_audio_filesize) + { + g_audio_filepos = (unsigned int) (g_audio_filepos + offset); + result = 0; + } + break; + case SEEK_END: +// printf("SEEK_END being called, offset is %x, whence is %d!\n", (Uint32) offset, whence); + if (g_audio_filesize + offset <= g_audio_filesize) + { + g_audio_filepos = (unsigned int) (g_audio_filesize + offset); + result = 0; + } + break; + } + + return result; +} + +int mmclose (void *datasource) +{ + // safety check + if (datasource != g_big_buf) + { + printline("ldp-vldp-audio.cpp: datasource != g_bigbuf, this should never happen!"); + } + +#ifdef TRY_MMAP + printline("Unmapping audio stream from memory ..."); + munmap(g_big_buf, g_audio_filesize); + datasource = NULL; +#else + printline("Freeing memory used to store audio stream..."); + //free(datasource); + delete [] g_big_buf; + g_big_buf = NULL; +#endif + + mpo_close(g_pIOAudioHandle); + g_pIOAudioHandle = NULL; + + return 0; +} + +long mmtell (void *datasource) +{ +// printf("mmtell being called, filepos is %x\n", (Uint32) g_audio_filepos); + + if (datasource) + { + } + + return g_audio_filepos; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// public audio stuff + +void ldp_vldp::enable_audio1() +{ + g_audio_left_muted = false; + set_audiocopy_callback(); +} + +void ldp_vldp::enable_audio2() +{ + g_audio_right_muted = false; + set_audiocopy_callback(); +} + +void ldp_vldp::disable_audio1() +{ + g_audio_left_muted = true; + set_audiocopy_callback(); +} + +void ldp_vldp::disable_audio2() +{ + g_audio_right_muted = true; + set_audiocopy_callback(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// + +// mute audio data +void *audiocopy_mute(void *dest, const void *src, size_t bytes_to_copy) +{ +#ifdef WIN32 + ZeroMemory(dest, bytes_to_copy); +#else + bzero(dest, bytes_to_copy); +#endif + return NULL; +} + +// copies left-channel audio data to right-channel +void *audiocopy_left_only(void *dest, const void *src, size_t bytes_to_copy) +{ +#ifdef DEBUG + assert(bytes_to_copy % 4 == 0); // stereo 16-bit audio should always be divisible by 4 +#endif + Uint32 *dst32 = (Uint32 *) dest; + Uint16 *src16_L = (Uint16 *) src; // point to first bit of left-channel data + + bytes_to_copy >>= 2; // divide by 4 because we will be advancing 4 bytes per iteration + for (unsigned int index = 0; index < bytes_to_copy; index++) + { + *dst32 = (*src16_L << 16) | *src16_L; // we only care about left-channel + dst32++; + src16_L += 2; // skip over right channel data + } + return NULL; // for compatiblity reasons, we don't use this value +} + +// copies right-channel audio data to left-channel +void *audiocopy_right_only(void *dest, const void *src, size_t bytes_to_copy) +{ +#ifdef DEBUG + assert(bytes_to_copy % 4 == 0); // stereo 16-bit audio should always be divisible by 4 +#endif + + Uint32 *dst32 = (Uint32 *) dest; + Uint16 *src16_R = (Uint16 *) src + 1; // point to the first bit of data that occurs on the right channel + + bytes_to_copy >>= 2; // divide by 4 because we will be advancing 4 bytes per iteration + for (unsigned int index = 0; index < bytes_to_copy; index++) + { + // fastest method (third attempt) + *dst32 = (*src16_R << 16) | *src16_R; // we only care about the right-channel + dst32++; + src16_R += 2; // skip over left channel data + } + return NULL; +} + +// sets the audio copy callbackto be used, based on which audio channels are muted +// this should only be called when the mute status of the channels is changed +void ldp_vldp::set_audiocopy_callback() +{ + if (g_audio_left_muted) + { + if (g_audio_right_muted) paudiocopy = audiocopy_mute; // both channels are muted + else paudiocopy = audiocopy_right_only; // only right channel is on + } + else + { + if (g_audio_right_muted) paudiocopy = audiocopy_left_only; // only left channel is on + else paudiocopy = (audiocopyproc) memcpy; // default, both channels on + } +} + +// changes file extension of m2vpath so it ends in .ogg (and add suffix for alt soundtrack if needed) +void ldp_vldp::oggize_path(string &oggpath, string m2vpath) +{ + oggpath = m2vpath; + oggpath.replace(oggpath.length()-4, 4, m_altaudio_suffix); // append optional alternate audio suffix (if this string is blank it should be ok) + oggpath += ".ogg"; +} + +// initializes VLDP audio, returns 1 on success or 0 on failure +bool ldp_vldp::audio_init() +{ + bool result = false; + +#ifdef AUDIO_DEBUG + g_u64CallbackByteCount = 0; + g_uCallbackFloodTimer = 0; + g_uCallbackDbgTimer = GET_TICKS(); +#endif + + // create a mutex to prevent threads from interfering + g_ogg_mutex = SDL_CreateMutex(); + if (g_ogg_mutex) + { + result = true; + } + + return result; +} + +// shuts down VLDP audio +void ldp_vldp::audio_shutdown() +{ + // if we have an audio file still open, close it + if (g_pIOAudioHandle != 0) + { + close_audio_stream(); + } + + // if we successfully created a mutex previously, then destroy it now + if (g_ogg_mutex) + { + SDL_DestroyMutex(g_ogg_mutex); + g_ogg_mutex = NULL; + } +} + +void ldp_vldp::close_audio_stream() +{ + OGG_LOCK; + + g_audio_ready = false; + g_audio_playing = false; + ov_clear(&s_ogg); + + OGG_UNLOCK; +} + +bool ldp_vldp::open_audio_stream(const string &strFilename) +{ + bool result = false; + ov_callbacks mycallbacks = + { + mmread, + mmseek, + mmclose, + mmtell + }; + + OGG_LOCK; // can't have audio callback running during this + + // if an audio stream is already open, close it first + if (g_pIOAudioHandle != 0) + { + close_audio_stream(); + } + + mmreset(); // reset the mm wrappers for new use + + g_pIOAudioHandle = mpo_open((m_mpeg_path + strFilename).c_str(), MPO_OPEN_READONLY); + // if audio file was opened successfully + if (g_pIOAudioHandle) + { + g_audio_filesize = static_cast(g_pIOAudioHandle->size & 0xFFFFFFFF); +#ifdef TRY_MMAP + g_big_buf = (Uint8 *) mmap(NULL, g_audio_filesize, PROT_READ, MAP_PRIVATE, fileno(g_pIOAudioHandle->handle), 0); + if (!g_big_buf) + { + printline("ERROR : mmap failed"); + } +#else + g_big_buf = new unsigned char[g_audio_filesize]; + if (g_big_buf) + { + mpo_read(g_big_buf, g_audio_filesize, NULL, g_pIOAudioHandle); // read entire stream into RAM + } + else + { + printline("ERROR : out of memory"); + } +#endif + if (g_big_buf) + { + int open_result = ov_open_callbacks(g_big_buf, &s_ogg, NULL, 0, mycallbacks); + + // if we opening the .OGG succeeded + if (open_result == 0) + { + // now check to make sure it's stereo and the proper sample rate + vorbis_info *info = ov_info(&s_ogg, -1); + + // if they meet the proper specification, let them proceed + if ((info->channels == 2) && (info->rate == 44100)) + { + g_audio_ready = true; + result = true; + } + else + { + char s[160]; + printline("OGG ERROR : Your .ogg file needs to have 2 channels and 44100 Hz"); + sprintf(s, "OGG ERROR : Your .ogg file has %u channel(s) and is %ld Hz", info->channels, info->rate); + printline(s); + printline("OGG ERROR : Your .ogg file will be ignored (you won't hear any audio)"); + } + } + else + { + char s[160]; + sprintf(s, "ov_open_callbacks failed! Error code is %d\n", open_result); + printline(s); + sprintf(s, "OV_EREAD=%d OV_ENOTVORBIS=%d OV_EVERSION=%d OV_EBADHEADER=%d OV_EFAULT=%d\n", + OV_EREAD, OV_ENOTVORBIS, OV_EVERSION, OV_EBADHEADER, OV_EFAULT); + printline(s); + } + } + // else we've already printed error messages, so we don't need to do anything else + + // close file if we got an earlier error + if (!result) + { + mpo_close(g_pIOAudioHandle); + g_pIOAudioHandle = NULL; + + // if we have memory allocated, de-allocate it + if (g_big_buf) + { +#ifdef TRY_MMAP + munmap(g_big_buf, g_audio_filesize); +#else + delete [] g_big_buf; +#endif + g_big_buf = NULL; + } + } + + } // end if we could open file + else + { + // don't show this message to end-users, a surprising number of them report this as a bug and it's really getting annoying :) +#ifdef DEBUG + string s; + s = "No audio file (" + strFilename + ") was found to go with the opened video file"; + printline(s.c_str()); + printline("NOTE : This is not necessarily a problem, some video doesn't have audio!"); +#endif + } + + OGG_UNLOCK; + + return result; +} + +// seeks to a sample position in the audio stream +// returns true if successful or false if failed +bool ldp_vldp::seek_audio(Uint64 u64Samples) +{ + bool result = false; + + OGG_LOCK; // can't have audio callback running during this + + if (ov_seekable(&s_ogg)) + { + ov_pcm_seek(&s_ogg, u64Samples); + g_audio_playing = false; // audio should not be playing immediately after a seek + result = true; + } + else + { + printline("DOH! OGG stream is not seekable!"); + } + + OGG_UNLOCK; + + return result; +} + +// starts playing the audio +void ldp_vldp::audio_play(Uint32 timer) +{ + OGG_LOCK; + g_playing_timer = timer; + g_samples_played = 0; + g_audio_playing = true; + OGG_UNLOCK; +} + +// pauses the audio at the current position +void ldp_vldp::audio_pause() +{ + OGG_LOCK; + g_audio_playing = false; + OGG_UNLOCK; +} + +//////////////////////////////////////////////////////////////////////////////////////// + +char g_small_buf[AUDIO_BUF_CHUNK] = { 0 }; +Uint8 g_leftover_buf[AUDIO_BUF_CHUNK] = { 0 }; +int g_leftover_samples = 0; + +// our audio callback +void ldp_vldp_audio_callback(Uint8 *stream, int len, int unused) +{ +#ifdef AUDIO_DEBUG + g_u64CallbackByteCount += len; + unsigned int uFloodTimer = (GET_TICKS() - g_uCallbackDbgTimer) / 1000; + if (uFloodTimer != g_uCallbackFloodTimer) + { + g_uCallbackFloodTimer = uFloodTimer; + string s = "audio callback frequency is: " + numstr::ToStr((g_u64CallbackByteCount / uFloodTimer) >> 2); + printline(s.c_str()); + } +#endif + + OGG_LOCK; // make sure nothing changes with any ogg stuff while we decode + + // if audio is ready to be read and if it is playing + if (g_audio_ready && g_audio_playing) + { + bool audio_caught_up = false; + int loop_count = 0; + + // normally we only want to go through this loop once + // The exception is if we are behind, in which case we want to process audio until we're caught up again + // we don't want to loop endlessly in here if there is a bug, which is why we have a loop count + while ((!audio_caught_up) && (loop_count++ < 10)) + { + long samples_read = 0; + int samples_copied = 0; + Uint32 bytes_to_read = 0; + Uint32 correct_samples = 0; // how many samples we should have played up to this point + int nop; + + // if we have some samples from last time for the audio stream + if (g_leftover_samples) + { + if (g_leftover_samples <= len) + { + paudiocopy(stream, g_leftover_buf, g_leftover_samples); + samples_copied += g_leftover_samples; + g_leftover_samples = 0; + } + else + { + paudiocopy(stream, g_leftover_buf, len); + memmove(g_leftover_buf, g_leftover_buf + len, g_leftover_samples - len); // shift remaining buf to front + // memmove is used because the memory area overlaps + samples_copied = len; + g_leftover_samples -= len; + } + } + + while (samples_copied < len) + { +#ifndef GP2X + samples_read = ov_read(&s_ogg, &g_small_buf[0], + AUDIO_BUF_CHUNK,0,2,1, &nop); +#else + // gp2x version + samples_read = ov_read(&s_ogg, &g_small_buf[0], AUDIO_BUF_CHUNK, &nop); +#endif + + if (samples_read > 0) + { + bytes_to_read = len - samples_copied; // how much space we have left to fill + // (samples_copied can and often is 0) + + // if we have more space to fill than samples available, then we only want to read + // as many samples as we have available + if (bytes_to_read > (Uint32) samples_read) + { + bytes_to_read = samples_read; + } + // else we have to split the buffer + else + { + g_leftover_samples = samples_read - bytes_to_read; + memcpy(g_leftover_buf, g_small_buf + bytes_to_read, g_leftover_samples); + } + + paudiocopy(stream + samples_copied, g_small_buf, bytes_to_read); + samples_copied += bytes_to_read; + } // end if samples were read + + // if we got an error + else if (samples_read < 0) + { + printline("Problem reading samples!"); + g_audio_playing = false; + break; + } + + // else, samples_read == 0 in which case we've come to the end of the stream + else + { + printline("End of audio stream detected!"); + g_audio_playing = false; + break; + } + + } // end while we have not filled the buffer + + // NOW WE CHECK TO SEE IF THE AUDIO IS LAGGING TOO FAR BEHIND + // IF IT IS, WE NEED TO SKIP FORWARD + + g_samples_played += len; // update stats on how many samples have played so we can make sure audio is in sync + + //unsigned int cur_time = refresh_ms_time(); + unsigned int cur_time = g_ldp->get_elapsed_ms_since_play(); + // if our timer is set to the current time or some previous time + if (g_playing_timer < cur_time) + { + static const Uint64 uBYTES_PER_S = AUDIO_FREQ * AUDIO_BYTES_PER_SAMPLE; // needs to be uint64 to prevent overflow from subsequent math + correct_samples = (unsigned int) ((uBYTES_PER_S * (cur_time - g_playing_timer)) / 1000); + // how many samples should have played + // 176.4 = 44.1 samples per millisecond * 2 for stereo * 2 for 16-bit + } + // our timer is set to some time in the future (used with skipping) so we actually + // should not have played any samples at this point + else + { +// fprintf(stderr, "LDP-VLDP-AUDIO : Timer is in the future\n"); + correct_samples = 0; + } + + // if we're ahead instead of behind, don't loop + if (correct_samples <= g_samples_played) + { + audio_caught_up = true; + + /* + // warn user if we're too far ahead (this should never happen) + if ((g_samples_played - correct_samples) > len) + { + string s = "ldp-vldp-audio callback: audio is too far ahead! played: " + + numstr::ToStr(g_samples_played) + ", expected: " + numstr::ToStr(correct_samples); + printline(s.c_str()); + } + */ + } + + // if we're not too far behind, don't loop + else if ((Sint32) (correct_samples - g_samples_played) < len) + { + audio_caught_up = true; + } + + // if we're too far behind, notify the user for testing purposes + else + { + /* + char s[160]; + sprintf(s, "AUDIO : played %u, expected %u, timer=%u, curtime=%u", g_samples_played, correct_samples, g_playing_timer, g_ldp->get_elapsed_ms_since_play()); + printline(s); + */ + audio_caught_up = false; + SDL_Delay(0); // don't starve other processes while trying to catch up + } + } // end while we're not caught up + + } // end if audio is playing + + // Either we have no audio file opened OR + // disc is not playing, pause audio and make sure we don't have any extraneous audio lingering around when + // we start playing again + else + { + // fill audio stream with silence since it will be expecting to get something back from us +#ifdef WIN32 + ZeroMemory(stream, len); +#else + bzero(stream, len); +#endif + + g_leftover_samples = 0; + } + + OGG_UNLOCK; + +} diff --git a/ldp-out/ldp-vldp-gl.cpp b/ldp-out/ldp-vldp-gl.cpp new file mode 100644 index 000000000..91cca76fc --- /dev/null +++ b/ldp-out/ldp-vldp-gl.cpp @@ -0,0 +1,780 @@ + +#ifdef USE_OPENGL + +#ifdef MAC_OSX +#include +#else +#include +#endif + +#include // for memcpy +#include "../vldp2/vldp/vldp.h" // to get the vldp structs +#include "ldp-vldp.h" +#include "ldp-vldp-gl.h" +#include "ldp.h" +#include "../io/mpo_mem.h" +#include "../io/conout.h" +#include "../game/game.h" +#include "../daphne.h" +#include "../video/video.h" +#include "../video/blend.h" +#include "../video/palette.h" + +#ifdef DEBUG +#include +#endif + +enum +{ + TEX_Y, // holds Y buffer + TEX_U, // U buffer + TEX_V, // V buffer + NUM_YUV_TEXTURES, +}; + +enum +{ + TEX_VID_OVERLAY, // video overlay + TEX_VID_PALETTE, // color palette look-up texture + TEX_SCANLINES, // scanlines texture (if enabled by user) + NUM_TEXTURES // this must be last! +}; + +// for speed.. I am in a hurry and don't want to mess w/ functions :( +extern Uint32 g_uRGBAPalette[]; +extern unsigned int g_filter_type; + +// for speed +extern unsigned g_uCPUMsBehind; + +// for speed +extern bool g_take_screenshot; // if true, a screenshot will be taken at the next available opportunity + +// buffers to hold video frame texture +// There are two sets of each buffer to hold copies of the YUV buffers +GLuint g_textureYUVIDs[2][NUM_YUV_TEXTURES]; + +// buffers to hold non-YUV textures +GLuint g_textureIDs[NUM_TEXTURES]; + +// g_textureYUVIDs[g_uCurTextureArray] is the currently active texture array :) +unsigned int g_uCurTextureArray = 0; + +// dimensions of YUV frame (in pixels) +unsigned int g_uTexWidth = 0, g_uTexHeight = 0; + +// dimensions of output window (in pixels) +unsigned int g_uVidWidth = 0, g_uVidHeight = 0; + +// the height of the video overlay (pre-calculate for speed) +// The video overlay's height often goes off the screen +unsigned int g_uOverlayHeight = 0; + +// the same as g_game->get_video_visible_lines() +unsigned int g_uVisibleLines = 240; + +bool g_bShaderInitialized = false; +bool g_bOpenGLInitialized = false; + +GLuint g_FSHandle = 0, g_PHandle = 0; +GLuint g_hndF8Bit = 0, g_prgF8Bit = 0; + +// how many frames have been prepared +unsigned int g_uFramePrepReq = 0; + +// last frame index to be requested to be displayed, and last frame index that was displayed +// (index corresponds to g_uFramePrepReq) +unsigned int g_uFrameDispReq = 0; +unsigned int g_uFrameDispAck = 0; + +// blank requested means the next frame we display should be blank, with overlay drawn on top +bool g_bBlankRequested = false; + +// what gamevid was last time the think() function was called +SDL_Surface *g_gamevid_old = NULL; + +// so we know when a new vblank has occurred +unsigned int g_uVblankCountOld = 0; + +#define Y_IDX 0 +#define U_IDX 1 +#define V_IDX 2 + +// This number logically only needs to be 2 but performs much better as 4 :) +#define YUV_BUF_COUNT 4 + +unsigned char *g_ptr[YUV_BUF_COUNT][3]; + +// Macros to lock and unlock the mutex to make sure two threads aren't accessing shared vars at the same time +#define VLDP_GL_LOCK SDL_mutexP(g_vldp_gl_mutex) +#define VLDP_GL_UNLOCK SDL_mutexV(g_vldp_gl_mutex) + +// mutex to protect shared data +SDL_mutex *g_vldp_gl_mutex = NULL; + +// Thanks to Peter Bengtsson for the reference code to help me figure out +// how to convert YUV to RGB using a fragment shader. +const GLchar *g_FProgram= + "uniform sampler2D Ytex;\n" + "uniform sampler2D Utex,Vtex;\n" + "void main(void) {\n" + " float r,g,b,y,u,v;\n" + " y=texture2D(Ytex,gl_TexCoord[0].st).r;\n" + " u=texture2D(Utex,gl_TexCoord[0].st).r;\n" + " v=texture2D(Vtex,gl_TexCoord[0].st).r;\n" + + " y=1.1643*(y-0.0625);\n" + " u=u-0.5;\n" + " v=v-0.5;\n" + + " r=y+1.5958*v;\n" + " g=y-0.39173*u-0.81290*v;\n" + " b=y+2.017*u;\n" + + " gl_FragColor=vec4(r,g,b,1.0);\n" + "}\n"; + +// 8-bit texture fragment program (by Matt Ownby, my first fragment shader! woohoo!) +const GLchar *g_F8Bit = + "uniform sampler1D smpColorPalette;\n" + "uniform sampler2D smpPixels;\n" + "void main(void) {\n" + " float idx;\n" + // idx gets a value between 0.0 and 1.0 which corresponds to 0-255 on our color palette + " idx=texture2D(smpPixels, gl_TexCoord[0].st).r;\n" + // 255/256 (0.99609375) converts 0.0-1.0 to the left border of the color that we want in the palette texture + // Adding 1/512 (0.001953125) centers us inside the color that we want so that there can be no ambiguity + " gl_FragColor=texture1D(smpColorPalette, (idx * 0.99609375) + 0.001953125);\n" + "}\n"; + +void ldp_vldp_gl_blend_y(Uint8 *g_ptrY) +{ + // NOTE : this function is unoptimized, because it is low-priority. + // I just coded it up quickly to make sure it is supported to save myself any questions + // from people who are wondering why it's not working. + + g_blend_line1 = g_ptrY; + g_blend_line2 = g_ptrY + g_uTexWidth; + g_blend_dest = MPO_MALLOC(g_uTexWidth); + g_blend_iterations = g_uTexWidth; + + if (g_blend_dest) + { + // two rows at a time ... + for (unsigned int uRow = 0; uRow < g_uTexHeight; uRow += 2) + { + g_blend_func(); + + // overwrite two source lines with blended line + memcpy(g_blend_line1, g_blend_dest, g_uTexWidth); + memcpy(g_blend_line2, g_blend_dest, g_uTexWidth); + + g_blend_line1 += (g_uTexWidth << 1); + g_blend_line2 += (g_uTexWidth << 1); + } + MPO_FREE(g_blend_dest); + } +} + +void draw_prepared_frame(SDL_Surface *gamevid) +{ + int w_half = g_uVidWidth >> 1, h_half = g_uVidHeight >> 1; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + // if this isn't supposed to be a blank frame + if (!g_bBlankRequested) + { + glUseProgram(g_PHandle); // start using the program + + // ASSUMPTION: YUV textures have already been prepared + + // bind the YUV textures for the current frame + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[g_uCurTextureArray][TEX_U]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[g_uCurTextureArray][TEX_V]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[g_uCurTextureArray][TEX_Y]); + + // draw the textured rectangle + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex3i(-w_half, -h_half, 0); + glTexCoord2f(1, 1); glVertex3i(w_half, -h_half, 0); + glTexCoord2f(1, 0); glVertex3i(w_half, h_half, 0); + glTexCoord2f(0, 0); glVertex3i(-w_half, h_half, 0); + glEnd(); + + glUseProgram(0); // stop using fragment shader + } // end if it's not supposed to be a blank frame + // else the frame is supposed to be blank, so we don't draw the VLDP frame + else + { + // we've done our duty and blanked... + g_bBlankRequested = false; + } + + // STEP 2: Display 8-bit video overlay (if it exists) + + // if there is game video that needs to be displayed + if (gamevid) + { + g_uOverlayHeight = gamevid->h; + + // start using 8-bit texture fragment program + glUseProgram(g_prgF8Bit); + + // bind color palette to texture unit 1 + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_1D, g_textureIDs[TEX_VID_PALETTE]); + // The palette texture has already been copied over in on_palette_change_gl() + + // update 8-bit pixels to texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, g_textureIDs[TEX_VID_OVERLAY]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, gamevid->w, gamevid->h, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, gamevid->pixels); + + glPushMatrix(); + + // take vertical offset into account + + // The bottom of the rectangle must be the bottom of the overlay, + // relative to the size of the mpeg video. + // (many overlays are too big vertically to fit on the screen) + + // We have to rescale the vertical coordinates in case g_uVisibleLines + // is not the same as the screen's height. + GLfloat fScaleFactor = (GLfloat) g_uVidHeight / g_uVisibleLines; + glScalef(1.0, fScaleFactor, 1.0); + + // We have to do the translation after we do the scale, because + // the video row offset must be scaled too. + glTranslatef(0, (GLfloat) -g_game->get_video_row_offset(), 0); + + // iY is initialized as the bottom row + GLint iY = ((g_uVisibleLines / 2) - g_uOverlayHeight); + + // draw the textured rectangle + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex3i(-w_half, iY, 1); // bottom left + glTexCoord2f(1, 1); glVertex3i(w_half, iY, 1); // bottom right + + iY += g_uOverlayHeight; + + glTexCoord2f(1, 0); glVertex3i(w_half, iY, 1); // top right + glTexCoord2f(0, 0); glVertex3i(-w_half, iY, 1); // top left + glEnd(); + glPopMatrix(); + + // stop using fragment program + glUseProgram(0); + +#if 0 + glDisable(GL_TEXTURE_2D); + + glPushMatrix(); + fScaleFactor = (GLfloat) g_uVidHeight / g_uVisibleLines; + glScalef(1.0, fScaleFactor, 1.0); + glTranslatef(0, (GLfloat) -g_game->get_video_row_offset(), 0); + iY = ((g_uVisibleLines / 2) - g_uOverlayHeight); + + glColor4f(1.0, 1.0, 1.0, 0.35f); // draw border so we can see where overlay's border is + glBegin(GL_QUADS); + glVertex3i(-w_half, iY, 3); // bottom left + glVertex3i(w_half, iY, 3); // bottom right + + iY += g_uOverlayHeight; + + glVertex3i(w_half, iY, 3); // top right + glVertex3i(-w_half, iY, 3); // top left + glEnd(); + glPopMatrix(); + + glColor4f(1.0, 0.0, 0.0, 0.25); + glBegin(GL_QUADS); + glVertex3i(-w_half, -h_half, 4); // bottom left + glVertex3i(w_half, -h_half, 4); // bottom right + glVertex3i(w_half, h_half, 4); // top right + glVertex3i(-w_half, h_half, 4); // top left + glEnd(); + glEnable(GL_TEXTURE_2D); +#endif + + } // end if game video exists + + // if scanlines are enabled + if (g_filter_type & FILTER_SCANLINES) + { + glBindTexture(GL_TEXTURE_2D, g_textureIDs[TEX_SCANLINES]); + glBegin(GL_QUADS); + glTexCoord2i(0, g_uVidHeight >> 1); glVertex3i(-w_half, -h_half, 2); + glTexCoord2i(1, g_uVidHeight >> 1); glVertex3i(w_half, -h_half, 2); + glTexCoord2i(1, 0); glVertex3i(w_half, h_half, 2); + glTexCoord2i(0, 0); glVertex3i(-w_half, h_half, 2); + glEnd(); + } +} + +void ldp_vldp_gl_think(unsigned int uVblankCount) +{ + // this is used by multiple branches so we define it here + SDL_Surface *gamevid = g_game->get_finished_video_overlay(); + bool bOkToDraw = false; + + VLDP_GL_LOCK; + + // if we have at least 1 new frame requested to be displayed + if (g_uFrameDispReq > g_uFrameDispAck) + { +#ifdef DEBUG + assert(g_ldp->is_blitting_allowed() == false); +#endif + + // STEP 1: copy frame into video card texture memory + + // Use the other texture array so that we can buffer our next YUV image and + // still allow access to the current one in case the video overlay changes before + // VLDP is ready to display the next YUV image + unsigned int uNextTextureArray = g_uCurTextureArray ^ 1; + + // acknowledge that we've drawn (or will draw very soon) this new frame + ++g_uFrameDispAck; + + // this allows us to display frames that are slightly behind but buffered + unsigned int uIdx = g_uFrameDispAck % YUV_BUF_COUNT; + + // lock while we access g_ptr* and g_bFrameQueued + // copy YUV frame into openGL texture buffer + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[uNextTextureArray][TEX_U]); + glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE, g_uTexWidth >> 1, g_uTexHeight >> 1,0,GL_LUMINANCE,GL_UNSIGNED_BYTE, + g_ptr[uIdx][U_IDX]); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[uNextTextureArray][TEX_V]); + glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,g_uTexWidth >> 1,g_uTexHeight >> 1,0,GL_LUMINANCE,GL_UNSIGNED_BYTE, + g_ptr[uIdx][V_IDX]); + + // if blending is requested, then blend the Y plane now before sending it to the texture + if (g_filter_type & FILTER_BLEND) + { + ldp_vldp_gl_blend_y(g_ptr[uIdx][Y_IDX]); + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,g_textureYUVIDs[uNextTextureArray][TEX_Y]); + glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,g_uTexWidth,g_uTexHeight,0,GL_LUMINANCE,GL_UNSIGNED_BYTE, + g_ptr[uIdx][Y_IDX]); + + g_uCurTextureArray ^= 1; // flip texture array so we're using our new VLDP frame when we draw + + bOkToDraw = true; // it's ok to draw the frame now ... + } + + // if our ROM-generated video overlay has changed + // (THIS SHOULD NOT BE AN 'ELSE IF' BECAUSE WE WANT TO UPDATE BOTH AT THE SAME FRAME IF NEEDED DUE TO VSYNC DELAY) + if (gamevid != g_gamevid_old) + { + g_gamevid_old = gamevid; + bOkToDraw = true; + } + // else do nothing ... + + VLDP_GL_UNLOCK; + + // If it's time to draw a new frame and if we have a new frame to draw + // (We don't want to draw every time bOkToDraw is true because if the laserdisc video + // changes at 30 FPS and the overlay changes at 60 FPS, we will have updates at 90 FPS + // which is too fast for most monitor refresh rates, although it does work fine with + // vsync disabled) + if ((uVblankCount != g_uVblankCountOld) && (bOkToDraw)) + { + // if we're not too far behind, then display the frame + // I chose 33 because it is approximately 2 frames on a 60 Hz monitor, and 1 NTSC frame + if (g_uCPUMsBehind < 33) + { + // draw it! (this should go really fast since the textures are already set up) + draw_prepared_frame(gamevid); + SDL_GL_SwapBuffers(); + + // if we've been instructed to take a screenshot, do so now that the image has been displayed + if (g_take_screenshot) + { + printline("Screenshot requested!"); + g_take_screenshot = false; + take_screenshot_GL(); + } + } + // else we're too far behind and SDL_GL_SwapBuffers can take a long time if vsync is enabled, + // so drop this frame to try to catch up. + + // TODO : maybe we should show every 4th frame even if we are dropping just to avoid + // having 'dead' air + + g_uVblankCountOld = uVblankCount; + } +} + +extern unsigned int g_draw_width, g_draw_height; + +bool check_shader(GLuint uFHandle, GLuint &uPHandle) +{ + char s[32768]; + bool bResult = false; + + GLint i = 0; + GLsizei iCharsWritten = 0; + + // see if compile succeeded + glGetShaderiv(uFHandle,GL_COMPILE_STATUS,&i); + if (i == GL_TRUE) + { + // create the program + uPHandle = glCreateProgram(); + + /* Create a complete program object. */ + glAttachShader(uPHandle,uFHandle); + glLinkProgram(uPHandle); + + // see if link succeeded + glGetProgramiv(uPHandle, GL_LINK_STATUS, &i); + + // if link succeeded + if (i == GL_TRUE) + { + bResult = true; + } + else + { + glGetProgramiv(uPHandle, GL_INFO_LOG_LENGTH, &i); + glGetProgramInfoLog(uPHandle,i,&iCharsWritten,s); + outstr("OpenGL Shader Link Failed: "); + printline(s); + } + } + // else compile failed + else + { + glGetShaderiv(uFHandle, GL_INFO_LOG_LENGTH, &i); + glGetShaderInfoLog(uFHandle,i,&iCharsWritten,s); + outstr("OpenGL Shader Compile Failed: "); + printline(s); + } + + return bResult; +} + +bool init_shader() +{ + bool bResult = false; + + glewInit(); + if (glewIsSupported("GL_VERSION_2_0")) + { + printline("OpenGL v2.0 is supported."); + + /* Set up program objects. */ + g_FSHandle=glCreateShader(GL_FRAGMENT_SHADER); + g_hndF8Bit=glCreateShader(GL_FRAGMENT_SHADER); + + /* Compile the shader. */ + glShaderSource(g_FSHandle,1,&g_FProgram,NULL); + glCompileShader(g_FSHandle); + + glShaderSource(g_hndF8Bit, 1, &g_F8Bit, NULL); + glCompileShader(g_hndF8Bit); + + // check to see if compilation succeeded + if (check_shader(g_FSHandle, g_PHandle)) + { + if (check_shader(g_hndF8Bit, g_prgF8Bit)) + { + // setup our shader variables + int i = 0; + + // setup variables for YUV->RGB program + glUseProgram(g_PHandle); + i=glGetUniformLocation(g_PHandle,"Utex"); + glUniform1i(i,1); + i=glGetUniformLocation(g_PHandle,"Vtex"); + glUniform1i(i,2); + i=glGetUniformLocation(g_PHandle,"Ytex"); + glUniform1i(i,0); + + // setup variables for 8-bit texture program + glUseProgram(g_prgF8Bit); + i=glGetUniformLocation(g_prgF8Bit,"smpColorPalette"); + glUniform1i(i,1); + // pixels on texture unit 0 + i=glGetUniformLocation(g_prgF8Bit,"smpPixels"); + glUniform1i(i,0); + glUseProgram(0); + + bResult = true; + } + } + } + else + { + printline("OpenGL v2.0 is required for VLDP OpenGL mode."); + } + + return bResult; +} + +bool init_vldp_opengl() +{ + bool bResult = false; + int i = 0; + + // if we've never initialized + if (!g_bOpenGLInitialized) + { + g_uVidWidth = g_draw_width; + g_uVidHeight = g_draw_height; + + // find out how many visible lines the video overlay supports + g_uVisibleLines = g_game->get_video_visible_lines(); + + glGenTextures(NUM_TEXTURES, g_textureIDs); // generate texture buffers + glGenTextures(NUM_YUV_TEXTURES, g_textureYUVIDs[0]); // " " " + glGenTextures(NUM_YUV_TEXTURES, g_textureYUVIDs[1]); // " " " + + // setup texture parameters + for (i = 0; i < NUM_TEXTURES; i++) + { + GLuint uType = GL_LINEAR; + GLuint uParam = GL_CLAMP_TO_EDGE; // no reason to ever use GL_CLAMP based on what I've now learned :) + GLenum uTarget = GL_TEXTURE_2D; + + switch (i) + { + // the color palette texture is 1-Dimensional + // We _must_ use GL_NEAREST for TEX_VID_PALETTE because it is a lookup table. + case TEX_VID_PALETTE: + uTarget = GL_TEXTURE_1D; + uType = GL_NEAREST; + break; + // the scanlines texture must repeat due to its design + case TEX_SCANLINES: + uParam = GL_REPEAT; + break; + // IMPORTANT: For TEX_VID_OVERLAY, we _must_ use GL_NEAREST for our shader to work properly. + case TEX_VID_OVERLAY: + uType = GL_NEAREST; + break; + } + + glBindTexture(uTarget, g_textureIDs[i]); + glTexParameteri(uTarget, GL_TEXTURE_WRAP_S, uParam); + glTexParameteri(uTarget, GL_TEXTURE_WRAP_T, uParam); + glTexParameteri(uTarget, GL_TEXTURE_MAG_FILTER, uType); + glTexParameteri(uTarget, GL_TEXTURE_MIN_FILTER, uType); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + + // setup YUV texture parameters + for (i = 0; i < NUM_YUV_TEXTURES; i++) + { + GLenum uTarget = GL_TEXTURE_2D; + GLuint uParam = GL_CLAMP_TO_EDGE; // this solves the 'green border' problem (GL_CLAMP was causing it) + GLuint uType = GL_LINEAR; + + for (int j = 0; j < 2; ++j) + { + glBindTexture(uTarget, g_textureYUVIDs[j][i]); + glTexParameteri(uTarget, GL_TEXTURE_WRAP_S, uParam); + glTexParameteri(uTarget, GL_TEXTURE_WRAP_T, uParam); + glTexParameteri(uTarget, GL_TEXTURE_MAG_FILTER, uType); + glTexParameteri(uTarget, GL_TEXTURE_MIN_FILTER, uType); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + } + + // NOW CREATE SCANLINES TEXTURE (it is so small it's ok to create it even if we don't use it) + glBindTexture(GL_TEXTURE_2D, g_textureIDs[TEX_SCANLINES]); + + Uint32 uScanLineTex[4] = + { + 0xFF000000, 0xFF000000, // first line (black) + 0, 0 // second line (totally transparent) + }; + + // apply the texture + glTexImage2D(GL_TEXTURE_2D, + 0, // level is 0 + GL_RGBA, + 2, // 2 wide + 2, // 2 tall + 0, // border is 0 + GL_RGBA, GL_UNSIGNED_BYTE, uScanLineTex); + + // if shaders don't init properly, then shutdown + if (init_shader()) + { + // we need a mutex to handle thread syncing + g_vldp_gl_mutex = SDL_CreateMutex(); + + // if mutex creates successfully + if (g_vldp_gl_mutex) + { + // IMPORTANT: this must be set to true before on_palette_change_gl is called!!! + g_bOpenGLInitialized = true; + + // This is important for us to do here, because the palette may have been finalized + // before we initialized VLDP GL, and it may never change hereafter. Therefore, + // we need to make sure that it is set at least once. + on_palette_change_gl(); + + bResult = true; + } + else + { + printline("g_vldp_gl_mutex could not be created"); + } + } + } + else bResult = true; + + return bResult; +} + +void free_gl_resources() +{ + // if we successfully created a mutex previously, then destroy it now + if (g_vldp_gl_mutex) + { + SDL_DestroyMutex(g_vldp_gl_mutex); + g_vldp_gl_mutex = NULL; + } + + for (unsigned int u = 0; u < YUV_BUF_COUNT; ++u) + { + MPO_FREE(g_ptr[u][Y_IDX]); + MPO_FREE(g_ptr[u][U_IDX]); + MPO_FREE(g_ptr[u][V_IDX]); + } +} + +// gets called when the color palette changes +void on_palette_change_gl() +{ + // this function may get called before we've initialized our GL stuff, in which + // case, we will have to ignore it. + if (g_bOpenGLInitialized) + { + // These shouldn't be necessary to do here, but I've left them here, commented out, + // in case problems are discovered on other hardware and they are needed. +// glActiveTexture(GL_TEXTURE1); +// glBindTexture(GL_TEXTURE_1D, g_textureIDs[TEX_VID_PALETTE]); + + // apply modified palette to palette texture + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, + g_uRGBAPalette); + } + // else we're not initialized, so there's nothing we can do ... +} + +////////////////////////////// +// threaded stuff here + +// opengl version of the callback +int prepare_frame_GL_callback(struct yuv_buf *src) +{ + int result = VLDP_TRUE; + + VLDP_GL_LOCK; + + /* + // used to test super don overflow problem, can probably be removed once we're + // sure the problem is really gone :) + if (*((unsigned int *) src->Y) == 0xbbbec1c2) + { + int i = 0; + } + */ + + // NOTE : we have multiple YUV buffers because, due to threading, it's possible + // for these callbacks to get called many times before the gl_think function + // is called. + // One scenario: prepare callback, display callback, followed by another prepare + // callback. Now we have 2 frames prepared, 1 frame requested to be displayed, + // and our gl_think hasn't even run yet! We need a way to keep track of all + // of this stuff without throwing anything away (hopefully). + + // if we're out of buffer room, we'll have to kill an old frame and + // not display it + while ((g_uFrameDispReq - g_uFrameDispAck) >= YUV_BUF_COUNT) + { + // this effectively will ensure that the frame is dropped + // (this should never happen but it's here as a safety) + ++g_uFrameDispAck; + } + + // If a prepared frame hasn't been displayed, then we should overwrite it instead of keeping it. + g_uFramePrepReq = g_uFrameDispReq + 1; + + // this handles auto-wraparound for us nicely + unsigned int uIdx = g_uFramePrepReq % YUV_BUF_COUNT; + + // store decoded frame for displaying later + memcpy(g_ptr[uIdx][Y_IDX], src->Y, src->Y_size); + memcpy(g_ptr[uIdx][U_IDX], src->U, src->UV_size); + memcpy(g_ptr[uIdx][V_IDX], src->V, src->UV_size); + + VLDP_GL_UNLOCK; + + return result; +} + +void display_frame_GL_callback(struct yuv_buf *buf) +{ + VLDP_GL_LOCK; + + // set the request display frame to the last prepared frame + g_uFrameDispReq = g_uFramePrepReq; + + VLDP_GL_UNLOCK; +} + +void report_mpeg_dimensions_GL_callback(int width, int height) +{ + VLDP_GL_LOCK; + + // blitting is not allowed once we create the YUV overlay ... + g_ldp->set_blitting_allowed(false); + + if (((unsigned) width != g_uTexWidth) || ((unsigned) height != g_uTexHeight)) + { + for (unsigned int u = 0; u < YUV_BUF_COUNT; ++u) + { + MPO_FREE(g_ptr[u][Y_IDX]); + MPO_FREE(g_ptr[u][U_IDX]); + MPO_FREE(g_ptr[u][V_IDX]); + g_ptr[u][Y_IDX] = MPO_MALLOC(width * height); + g_ptr[u][U_IDX] = MPO_MALLOC((width * height) >> 2); + g_ptr[u][V_IDX] = MPO_MALLOC((width * height) >> 2); + } + } + + g_uTexWidth = width; + g_uTexHeight = height; + + VLDP_GL_UNLOCK; +} + +void render_blank_frame_GL_callback() +{ + VLDP_GL_LOCK; + g_bBlankRequested = true; + + // force a frame update to ensure blanking happens + // (we don't need to populate the YUV buffer because the frame will be blank) + ++g_uFramePrepReq; + ++g_uFrameDispReq; + + VLDP_GL_UNLOCK; +} + +#endif // USE_OPENGL diff --git a/ldp-out/ldp-vldp-gl.h b/ldp-out/ldp-vldp-gl.h new file mode 100644 index 000000000..a5adc2d0e --- /dev/null +++ b/ldp-out/ldp-vldp-gl.h @@ -0,0 +1,30 @@ +#ifndef LDP_VLDP_GL_H +#define LDP_VLDP_GL_H + +#ifdef USE_OPENGL + +#ifdef MAC_OSX +#include +#else +#include +#endif + + +void ldp_vldp_gl_think(unsigned int uVblankCount); + +bool init_vldp_opengl(); +bool init_shader(); +void free_gl_resources(); + +// gets called when the color palette changes +void on_palette_change_gl(); + +void report_mpeg_dimensions_GL_callback(int width, int height); +int prepare_frame_GL_callback(struct yuv_buf *buf); +void display_frame_GL_callback(struct yuv_buf *buf); +void render_blank_frame_GL_callback(); + +#endif // USE_OPENGL + +#endif // LDP_VLDP_GL_H + diff --git a/ldp-out/ldp-vldp.cpp b/ldp-out/ldp-vldp.cpp new file mode 100644 index 000000000..02434b65f --- /dev/null +++ b/ldp-out/ldp-vldp.cpp @@ -0,0 +1,2288 @@ +/* +* ldp-vldp.cpp +* +* Copyright (C) 2001 Matt Ownby +* +* This file is part of DAPHNE, a laserdisc arcade game emulator +* +* DAPHNE 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. +* +* DAPHNE 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 +*/ + +// ldp-vldp.c +// by Matt Ownby + +// pretends to be an LDP, but uses the VLDP library for output +// (for people who have no laserdisc player) + +#ifdef WIN32 +#pragma warning (disable:4100) // disable the warning about unreferenced formal parameters (MSVC++) +#pragma warning (disable:4786) // disable warning about truncating to 255 in debug info +#define strcasecmp stricmp +#endif + +#ifdef DEBUG +#include +#endif +// +#include +#include +#include +#include "../io/conout.h" +#include "../io/error.h" +#include "../video/video.h" +#include "../timer/timer.h" +#include "../daphne.h" // for get_quitflag, set_quitflag +#include "../io/homedir.h" +#include "../io/input.h" +#include "../io/fileparse.h" +#include "../io/mpo_mem.h" +#include "../io/numstr.h" // for debug +#include "../io/network.h" // to query amount of RAM the system has (get_sys_mem) +#include "../game/game.h" +#include "../video/rgb2yuv.h" +#include "ldp-vldp.h" +#include "framemod.h" +#include "ldp-vldp-gl.h" // for OpenGL callbacks +//#include "ldp-vldp-gp2x.h" // for GP2X callbacks (if no gp2x, this is harmless) +#include "../vldp2/vldp/vldp.h" // to get the vldp structs +#include "../video/palette.h" +#include "../video/SDL_DrawText.h" +#include "../video/blend.h" + +#define API_VERSION 11 + +static const unsigned int FREQ1000 = AUDIO_FREQ * 1000; // let compiler compute this ... + +// video overlay stuff +Sint32 g_vertical_offset = 0; // (used a lot, we only want to calc it once) + +double g_dPercentComplete01 = 0.0; // send by child thread to indicate how far our parse is complete +bool g_bGotParseUpdate = false; // if true, it means we've received a parse update from VLDP +bool g_take_screenshot = false; // if true, a screenshot will be taken at the next available opportunity +unsigned int g_vertical_stretch = 0; +unsigned int g_filter_type = FILTER_NONE; // what type of filter to use on our data (if any) + +// these are globals because they are used by our callback functions +SDL_Rect *g_screen_clip_rect = NULL; // used a lot, we only want to calculate once +SDL_Overlay *g_hw_overlay = NULL; +struct yuv_buf g_blank_yuv_buf; // this will contain a blank YUV overlay suitable for search/seek blanking +Uint8 *g_line_buf = NULL; // temp sys RAM for doing calculations so we can do fastest copies to slow video RAM +Uint8 *g_line_buf2 = NULL; // 2nd buf +Uint8 *g_line_buf3 = NULL; // 3rd buf + +//////////////////////////////////////// + +// 2 pixels of black in YUY2 format (different for big and little endian) +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define YUY2_BLACK 0x7f007f00 +#else +#define YUY2_BLACK 0x007f007f +#endif + +///////////////////////////////////////// + +// We have to dynamically load the .DLL/.so file due to incompatibilities between MSVC++ and mingw32 library files +// These pointers and typedefs assist us in doing so. + +typedef const struct vldp_out_info *(*initproc)(const struct vldp_in_info *in_info); +initproc pvldp_init; // pointer to the init proc ... + +// pointer to all functions the VLDP exposes to us ... +const struct vldp_out_info *g_vldp_info = NULL; + +// info that we provide to the VLDP DLL +struct vldp_in_info g_local_info; + +///////////////////////////////////////// + +ldp_vldp::ldp_vldp() +{ + m_bIsVLDP = true; // this is VLDP, so this value is true ... + blitting_allowed = true; // blitting is allowed until we get to a certain point in initialization + m_target_mpegframe = 0; // mpeg frame # we are seeking to + m_mpeg_path = ""; + m_cur_mpeg_filename = ""; + m_file_index = 0; // # of mpeg files in our list + m_framefile = ".txt"; + m_framefile = g_game->get_shortgamename() + m_framefile; // create a sensible default framefile name + m_bFramefileSet = false; + m_altaudio_suffix = ""; // no alternate audio by default + m_audio_file_opened = false; + m_cur_ldframe_offset = 0; + m_blank_on_searches = false; + m_blank_on_skips = false; + m_seek_frames_per_ms = 0; + m_min_seek_delay = 0; + m_vertical_stretch = 0; + + m_testing = false; // don't run tests by default + + m_bPreCache = m_bPreCacheForce = false; + m_mPreCachedFiles.clear(); + + m_uSoundChipID = 0; + + enable_audio1(); // both channels should be on by default + enable_audio2(); +} + +ldp_vldp::~ldp_vldp() +{ + pre_shutdown(); +} + +// called when daphne starts up +bool ldp_vldp::init_player() +{ + bool result = false; + bool need_to_parse = false; // whether we need to parse all video + + g_vertical_stretch = m_vertical_stretch; // callbacks don't have access to m_vertical_stretch + + // load the .DLL first in case we call any of its functions elsewhere + if (load_vldp_lib()) + { + // try to read in the framefile + if (read_frame_conversions()) + { + // just a sanity check to make sure their frame file is correct + if (first_video_file_exists()) + { + // if the last video file has not been parsed, assume none of them have been + // This is safe because if they have been parsed, it will just skip them + if (!last_video_file_parsed()) + { + printnotice("Press any key to parse your video file(s). This may take a while. Press ESC if you'd rather quit."); + need_to_parse = true; + } + + if (audio_init() && !get_quitflag()) + { + // if our game is using video overlay, + // AND if we're not doing tests that an overlay would interfere with + // we'll use our slower callback + if (g_game->get_active_video_overlay() && !m_testing) + { + g_local_info.prepare_frame = prepare_frame_callback_with_overlay; + } + + // otherwise we can draw the frame much faster w/o worrying about + // video overlay + else + { + g_local_info.prepare_frame = prepare_frame_callback_without_overlay; + } + g_local_info.display_frame = display_frame_callback; +#ifdef GP2X + // gp2x receives a yuy2 frame directly + g_local_info.prepare_yuy2_frame = prepare_gp2x_frame_callback; + g_local_info.display_yuy2_frame = display_gp2x_frame_callback; +#endif // GP2X + g_local_info.report_parse_progress = report_parse_progress_callback; + g_local_info.report_mpeg_dimensions = report_mpeg_dimensions_callback; + g_local_info.render_blank_frame = blank_overlay; + g_local_info.blank_during_searches = m_blank_on_searches; + g_local_info.blank_during_skips = m_blank_on_skips; + g_local_info.GetTicksFunc = GetTicksFunc; + +#ifdef USE_OPENGL + // if we're using openGL, then we have a different set of callbacks ... + if (get_use_opengl()) + { + g_local_info.prepare_frame = prepare_frame_GL_callback; + g_local_info.display_frame = display_frame_GL_callback; + g_local_info.report_mpeg_dimensions = report_mpeg_dimensions_GL_callback; + g_local_info.render_blank_frame = render_blank_frame_GL_callback; + if (!init_vldp_opengl()) + { + printerror("OpenGL v2.0 initialization failed."); + set_quitflag(); + } + } +#endif + g_vldp_info = pvldp_init(&g_local_info); + + // if we successfully made contact with VLDP ... + if (g_vldp_info != NULL) + { + // make sure we are using the API that we expect + if (g_vldp_info->uApiVersion == API_VERSION) + { + // this number is used repeatedly, so we calculate it once + g_vertical_offset = g_game->get_video_row_offset(); + + // if testing has been requested then run them ... + if (m_testing) + { + list lstrPassed, lstrFailed; + run_tests(lstrPassed, lstrFailed); + // run releasetest to see actual results now ... + printline("Run releasetest to see printed results!"); + set_quitflag(); + } + + // bPreCacheOK will be true if precaching succeeds or is never attempted + bool bPreCacheOK = true; + + // If precaching has been requested, do it now. + // The check for RAM requirements is done inside the + // precache_all_video function, so we don't need to worry about that here. + if (m_bPreCache) + { + bPreCacheOK = precache_all_video(); + } + + // if we need to parse all the video + if (need_to_parse) + { + parse_all_video(); + } + + // if precaching succeeded or we didn't request precaching + if (bPreCacheOK) + { + blitting_allowed = false; // this is the point where blitting isn't allowed anymore + + // open first file so that + // we can draw video overlay even if the disc is not playing + if (open_and_block(m_mpeginfo[0].name)) + { + // although we just opened a video file, we have not opened an audio file, + // so we want to force a re-open of the same video file when we do a real search, + // in order to ensure that the audio file is opened also. + m_cur_mpeg_filename = ""; + + // set MPEG size ASAP in case different from NTSC default + m_discvideo_width = g_vldp_info->w; + m_discvideo_height = g_vldp_info->h; + + if (is_sound_enabled()) + { + struct sounddef soundchip; + soundchip.type = SOUNDCHIP_VLDP; + // no further parameters necessary + m_uSoundChipID = add_soundchip(&soundchip); + } + + result = true; + } + else + { + printline("LDP-VLDP ERROR : first video file could not be opened!"); + } + } // end if it's ok to proceed + // else precaching failed + else + { + printerror("LDP-VLDP ERROR : precaching failed"); + } + } // end if API matches up + else + { + printerror("VLDP library is the wrong version!"); + } + + } // end if reading the frame conversion file worked + else + { + printline("LDP-VLDP ERROR : vldp_init returned NULL (which shouldn't ever happen)"); + } + } // if audio init succeeded + else + { + // only report an audio problem if there is one + if (!get_quitflag()) + { + printline("Could not initialize VLDP audio!"); + } + + // otherwise report that they quit + else + { + printline("VLDP : Quit requested, shutting down!"); + } + } // end if audio init failed or if user opted to quit instead of parse + } // end if first file was present (sanity check) + // else if first file was not found, we do just quit because an error is printed elsewhere + } // end if framefile was read in properly + else + { + // if the user didn't specify a framefile from the command-line, then give them a little hint. + if (!m_bFramefileSet) + { + printline("You must specify a -framefile argument when using VLDP."); + } + // else the other error messages are more than sufficient + } + } // end if .DLL was loaded properly + else + { + printline("Could not load VLDP dynamic library!!!"); + } + + // if init didn't completely finish, then we need to shutdown everything + if (!result) + { + shutdown_player(); + } + + return result; +} + +void ldp_vldp::shutdown_player() +{ + // if VLDP has been loaded + if (g_vldp_info) + { + g_vldp_info->shutdown(); + g_vldp_info = NULL; + } + + if (is_sound_enabled()) + { + if (!delete_soundchip(m_uSoundChipID)) + { + printline("ldp_vldp::shutdown_player WARNING : sound chip could not be deleted"); + } + } + free_vldp_lib(); + audio_shutdown(); + free_yuv_overlay(); // de-allocate overlay if we have one allocated ... + +#ifdef USE_OPENGL + free_gl_resources(); +#endif + +} + +bool ldp_vldp::open_and_block(const string &strFilename) +{ + bool bResult = false; + + // during parsing, blitting is allowed + // NOTE: we want this here so that it is true before the initial open command is called. + // Otherwise we'd put it inside wait_for_status ... + blitting_allowed = true; + + // see if this filename has been precached + map::const_iterator mi = m_mPreCachedFiles.find(strFilename); + + // if the file has not been precached and we are able to open it + if ((mi == m_mPreCachedFiles.end() && + (g_vldp_info->open((m_mpeg_path + strFilename).c_str()))) + // OR if the file has been precached and we are able to refer to it + || (g_vldp_info->open_precached(mi->second, (m_mpeg_path + strFilename).c_str()))) + { + bResult = wait_for_status(STAT_STOPPED); + if (bResult) + { + m_cur_mpeg_filename = strFilename; + } + } + + blitting_allowed = false; + + return bResult; +} + +bool ldp_vldp::precache_and_block(const string &strFilename) +{ + bool bResult = false; + + // during precaching, blitting is allowed + // NOTE: we want this here so that it is true before the initial open command is called. + // Otherwise we'd put it inside wait_for_status ... + blitting_allowed = true; + + if (g_vldp_info->precache((m_mpeg_path + strFilename).c_str())) + { + bResult = wait_for_status(STAT_STOPPED); + } + + blitting_allowed = false; + + return bResult; +} + +bool ldp_vldp::wait_for_status(unsigned int uStatus) +{ + bool bResult = false; + + while (g_vldp_info->status == STAT_BUSY) + { + // if we got a parse update, then show it ... + if (g_bGotParseUpdate) + { + // redraw screen blitter before we display it + update_parse_meter(); + vid_blank(); + vid_blit(get_screen_blitter(), 0, 0); + vid_flip(); + g_bGotParseUpdate = false; + } + + SDL_check_input(); // so that windows events are handled + make_delay(20); // be nice to CPU + } + + // if opening succeeded + if ((unsigned int) g_vldp_info->status == uStatus) + { + bResult = true; + } + + return bResult; +} + +bool ldp_vldp::nonblocking_search(char *frame) +{ + + bool result = false; + string filename = ""; + string oggname = ""; + Uint32 target_ld_frame = (Uint32) atoi(frame); + Uint64 u64AudioTargetPos = 0; // position in audio to seek to (in samples) + unsigned int seek_delay_ms = 0; // how many ms this seek must be delayed (to simulate laserdisc lag) + + audio_pause(); // pause the audio before we seek so we don't have overrun + + // do we need to compute seek_delay_ms? + // (This is best done sooner than later so get_current_frame() is more accurate + if (m_seek_frames_per_ms > 0) + { + // this value should be approximately the last frame we displayed + // it doesn't get changed to the new frame until the seek is complete + Uint32 cur_frame = get_current_frame(); + unsigned int frame_delta = 0; // how many frames we're skipping + + // if we're seeking forward + if (target_ld_frame > cur_frame) + { + frame_delta = target_ld_frame - cur_frame; + } + else + { + frame_delta = cur_frame - target_ld_frame; + } + + seek_delay_ms = (unsigned int) (frame_delta / m_seek_frames_per_ms); + +#ifdef DEBUG + string msg = "frame_delta is "; + msg += numstr::ToStr(frame_delta); + msg += " and seek_delay_ms is "; + msg += numstr::ToStr(seek_delay_ms); + printline(msg.c_str()); +#endif + + } + + // make sure our seek delay does not fall below our minimum + if (seek_delay_ms < m_min_seek_delay) seek_delay_ms = m_min_seek_delay; + + m_target_mpegframe = mpeg_info(filename, target_ld_frame); // try to get a filename + + // if we can convert target frame into a filename, do it! + if (filename != "") + { + result = true; // now we assume success unless we fail + + // if the file to be opened is different from the one we have opened + // OR if we don't yet have a file open ... + // THEN open the file! :) + if (filename != m_cur_mpeg_filename) + { + // if we were able to successfully open the video file + if (open_and_block(filename)) + { + result = true; + + // this is done inside open_and_block now ... + //m_cur_mpeg_filename = filename; // make video file our new current file + + // if sound is enabled, try to open an audio stream to match the video stream + if (is_sound_enabled()) + { + // try to open an optional audio file to go along with video + oggize_path(oggname, filename); + m_audio_file_opened = open_audio_stream(oggname.c_str()); + } + } + else + { + outstr("LDP-VLDP.CPP : Could not open video file "); + printline(filename.c_str()); + result = false; + } + } + + // if we're ok so far, try the search + if (result) + { + // IMPORTANT : 'uFPKS' _must_ be queried AFTER a new mpeg has been opened, + // because sometimes a framefile can include mpegs that have different framerates + // from each other. + unsigned int uFPKS = g_vldp_info->uFpks; + + m_discvideo_width = g_vldp_info->w; + m_discvideo_height = g_vldp_info->h; + + // IMPORTANT : this must come before the optional FPS adjustment takes place!!! + u64AudioTargetPos = get_audio_sample_position(m_target_mpegframe); + + if (!need_frame_conversion()) + { + // If the mpeg's FPS and the disc's FPS differ, we need to adjust the mpeg frame + // NOTE: AVOID this if you can because it makes seeking less accurate + if (g_game->get_disc_fpks() != uFPKS) + { +#ifndef GP2X // we want to show a msg w/ floating point stuff in it, which is too much for gp2x to handle + string s = "NOTE: converting FPKS from " + numstr::ToStr(g_game->get_disc_fpks()) + + " to " + numstr::ToStr(uFPKS) + ". This may be less accurate."; + printline(s.c_str()); +#endif + m_target_mpegframe = (m_target_mpegframe * uFPKS) / g_game->get_disc_fpks(); + } + } + + // try to search to the requested frame + if (g_vldp_info->search((Uint32) m_target_mpegframe, seek_delay_ms)) + { + // if we have an audio file opened, do an audio seek also + if (m_audio_file_opened) + { + result = seek_audio(u64AudioTargetPos); + } + } + else + { + printline("LDP-VLDP.CPP : Search failed in video file"); + } + } + // else opening the file failed + } + // else mpeg_info() wasn't able to provide a filename ... + else + { + printline("LDP-VLDP.CPP ERROR: frame could not be converted to file, probably due to a framefile error."); + outstr("Your framefile must begin no later than frame "); + printline(frame); + printline("This most likely is your problem!"); + } + + return(result); +} + +// it should be safe to assume that if this function is getting called, that we have not yet got a result from the search +int ldp_vldp::get_search_result() +{ + int result = SEARCH_BUSY; // default to no change + + // if search is finished and has succeeded + if (g_vldp_info->status == STAT_PAUSED) + { + result = SEARCH_SUCCESS; + } + + // if the search failed + else if (g_vldp_info->status == STAT_ERROR) + { + result = SEARCH_FAIL; + } + + // else it's busy so we just wait ... + + return result; +} + +unsigned int ldp_vldp::play() +{ + unsigned int result = 0; + string ogg_path = ""; + bool bOK = true; // whether it's ok to issue the play command + + // if we haven't opened any mpeg file yet, then do so now + if (m_cur_mpeg_filename == "") + { + bOK = open_and_block(m_mpeginfo[0].name); // get the first mpeg available in our list + if (bOK) + { + // this is done inside open_and_block now ... + //m_cur_mpeg_filename = m_mpeginfo[0].name; + + // if sound is enabled, try to load an audio stream to go with video stream ... + if (is_sound_enabled()) + { + // try to open an optional audio file to go along with video + oggize_path(ogg_path, m_mpeginfo[0].name); + m_audio_file_opened = open_audio_stream(ogg_path.c_str()); + } + + } + else + { + outstr("LDP-VLDP.CPP : in play() function, could not open mpeg file "); + printline(m_mpeginfo[0].name.c_str()); + } + } // end if we haven't opened a file yet + + // we need to keep this separate in case an mpeg is already opened + if (bOK) + { +#ifdef DEBUG + // we always expect this to be true, because we've just played :) + assert(m_uElapsedMsSincePlay == 0); +#endif + audio_play(0); + if (g_vldp_info->play(0)) + { + result = GET_TICKS(); + } + } + + if (!result) + { + printline("VLDP ERROR : play command failed!"); + } + + return result; +} + +// skips forward a certain # of frames during playback without pausing +// Caveats: Does not work with an mpeg of the wrong framerate, does not work with an mpeg +// that uses fields, and does not skip across file boundaries. +// Returns true if skip was successful +bool ldp_vldp::skip_forward(Uint32 frames_to_skip, Uint32 target_frame) +{ + bool result = false; + + target_frame = (Uint32) (target_frame - m_cur_ldframe_offset); // take offset into account + // this is ok (and possible) because we don't support skipping across files + + unsigned int uFPKS = g_vldp_info->uFpks; + unsigned int uDiscFPKS = g_game->get_disc_fpks(); + + // We don't support skipping on mpegs that differ from the disc framerate + if (uDiscFPKS == uFPKS) + { + // make sure they're not using fields + // UPDATE : I don't see any reason why using fields would be a problem anymore, + // but since I am not aware of any mpegs that use fields that require skipping, + // I am leaving this restriction in here just to be safe. + if (!g_vldp_info->uses_fields) + { + // advantage to this method is no matter how many times we skip, we won't drift because we are using m_play_time as our base + // if we have an audio file opened + if (m_audio_file_opened) + { + //Uint64 u64AudioTargetPos = (((Uint64) target_frame) * FREQ1000) / uDiscFPKS; + Uint64 u64AudioTargetPos = get_audio_sample_position(target_frame); + + // seek and play if seeking was successful + if (seek_audio(u64AudioTargetPos)) + { + audio_play(m_uElapsedMsSincePlay); + } + } + // else we have no audio file open, but that's ok ... + + // if VLDP was able to skip successfully + if (g_vldp_info->skip(target_frame)) + { + result = true; + } + else + { + printline("LDP-VLDP ERROR : video skip failed"); + } + } + else + { + printline("LDP-VLDP ERROR : Skipping not supported with mpegs that use fields (such as this one)"); + } + } + else + { + string s = "LDP-VLDP ERROR : Skipping not supported when the mpeg's framerate differs from the disc's (" + + numstr::ToStr(uFPKS / 1000.0) + " vs " + numstr::ToStr(uDiscFPKS / 1000.0) + ")"; + printline(s.c_str()); + } + + return result; +} + +void ldp_vldp::pause() +{ +#ifdef DEBUG + string s = "ldp_vldp::pause() : g_vldp_info's current frame is " + numstr::ToStr(g_vldp_info->current_frame) + + " (" + numstr::ToStr(m_cur_ldframe_offset + g_vldp_info->current_frame) + " adjusted)"; + printline(s.c_str()); +#endif + g_vldp_info->pause(); + audio_pause(); +} + +bool ldp_vldp::change_speed(unsigned int uNumerator, unsigned int uDenominator) +{ + bool bResult = false; + + // if we aren't doing 1X, then stop the audio (this can be enhanced later) + if ((uNumerator != 1) || (uDenominator != 1)) + { + audio_pause(); + } + // else the audio should be played at the correct location + else + { + string filename; // dummy, not used + + // calculate where our audio position should be + unsigned int target_mpegframe = mpeg_info(filename, get_current_frame()); + Uint64 u64AudioTargetPos = get_audio_sample_position(target_mpegframe); + + // try to get the audio playing again + if (seek_audio(u64AudioTargetPos)) + { + audio_play(m_uElapsedMsSincePlay); + } + else + { + printline("WARNING : trying to seek audio after playing at 1X failed"); + } + } + + if (g_vldp_info->speedchange(m_uFramesToSkipPerFrame, m_uFramesToStallPerFrame)) + { + bResult = true; + } + + return bResult; +} + +void ldp_vldp::think() +{ +#ifdef USE_OPENGL + // IMPORTANT: this must come before we update VLDP's uMsTimer to ensure that OpenGL has a chance to draw any pending frames before + // a new frame comes in. + if (get_use_opengl()) + { + ldp_vldp_gl_think(m_uVblankCount); + } +#endif + + // VLDP relies on this number + // (m_uBlockedMsSincePlay is only non-zero when we've used blocking seeking) + g_local_info.uMsTimer = m_uElapsedMsSincePlay + m_uBlockedMsSincePlay; + +} + +#ifdef DEBUG +// This function tests to make sure VLDP's current frame is the same as our internal current frame. +unsigned int ldp_vldp::get_current_frame() +{ + Sint32 result = 0; + + // safety check + if (!g_vldp_info) return 0; + + unsigned int uFPKS = g_vldp_info->uFpks; + + // the # of frames that have advanced since our search + unsigned int uOffset = g_vldp_info->current_frame - m_target_mpegframe; + + unsigned int uStartMpegFrame = m_target_mpegframe; + + // since the mpeg's beginning does not correspond to the laserdisc's beginning, we add the offset + result = m_cur_ldframe_offset + uStartMpegFrame + uOffset; + + // if we're out of bounds, just set it to 0 + if (result <= 0) + { + result = 0; + } + + // if we got a legitimate frame + else + { + // FIXME : THIS CODE HAS BUGS IN IT, I HAVEN'T TRACKED THEM DOWN YET HEHE + // if the mpeg's FPS and the disc's FPS differ, we need to adjust the frame that we return + if (g_game->get_disc_fpks() != uFPKS) + { + return m_uCurrentFrame; + //result = (result * g_game->get_disc_fpks()) / uFPKS; + } + } + + // if there's even a slight mismatch, report it ... + if ((unsigned int) result != m_uCurrentFrame) + { + // if VLDP is ahead, that is especially disturbing + if ((unsigned int) result > m_uCurrentFrame) + { + string s = "ldp-vldp::get_current_frame() [vldp ahead]: internal frame is " + numstr::ToStr(m_uCurrentFrame) + + ", vldp's current frame is " + numstr::ToStr(result); + printline(s.c_str()); + + s = "g_local_info.uMsTimer is " + numstr::ToStr(g_local_info.uMsTimer) + ", which means frame offset " + + numstr::ToStr((g_local_info.uMsTimer * uFPKS) / 1000000); +#ifndef GP2X + s += " (" + numstr::ToStr(g_local_info.uMsTimer * uFPKS * 0.000001) + ") "; +#endif + printline(s.c_str()); + s = "m_uCurrentOffsetFrame is " + numstr::ToStr(m_uCurrentOffsetFrame) + ", m_last_seeked frame is " + numstr::ToStr(m_last_seeked_frame); + printline(s.c_str()); + unsigned int uMsCorrect = ((result - m_last_seeked_frame) * 1000000) / uFPKS; + s = "correct elapsed ms is " + numstr::ToStr(uMsCorrect); +#ifndef GP2X + // show float if we have decent FPU + s += " (" + numstr::ToStr((result - m_last_seeked_frame) * 1000000.0 / uFPKS) + ") "; +#endif + s += ", which is frame offset " + numstr::ToStr((uMsCorrect * uFPKS) / 1000000); +#ifndef GP2X + // show float result if we have a decent FPU + s += " (" + numstr::ToStr(uMsCorrect * uFPKS * 0.000001) + ")"; +#endif + printline(s.c_str()); + + } + + // This will be behind more than 1 frame (legitimately) playing at faster than 1X, + // so uncomment this with that in mind ... + /* + // else if VLDP is behind more than 1 frame, that is also disturbing + else if ((m_uCurrentFrame - result) > 1) + { + string s = "ldp-vldp::get_current_frame() [vldp behind]: internal frame is " + numstr::ToStr(m_uCurrentFrame) + + ", vldp's current frame is " + numstr::ToStr(result); + printline(s.c_str()); + } + + // else vldp is only behind 1 frame, that is to be expected at times due to threading issues ... + */ + + } + + return m_uCurrentFrame; +} +#endif + +// takes a screenshot of the current frame + any video overlay +void ldp_vldp::request_screenshot() +{ + g_take_screenshot = true; +} + +void ldp_vldp::set_search_blanking(bool enabled) +{ + m_blank_on_searches = enabled; +} + +void ldp_vldp::set_skip_blanking(bool enabled) +{ + m_blank_on_skips = enabled; +} + +void ldp_vldp::set_seek_frames_per_ms(double value) +{ + m_seek_frames_per_ms = value; +} + +void ldp_vldp::set_min_seek_delay(unsigned int value) +{ + m_min_seek_delay = value; +} + +// sets the name of the frame file +void ldp_vldp::set_framefile(const char *filename) +{ + m_bFramefileSet = true; + m_framefile = filename; +} + +// sets alternate soundtrack +void ldp_vldp::set_altaudio(const char *audio_suffix) +{ + m_altaudio_suffix = audio_suffix; +} + +// sets alternate soundtrack +void ldp_vldp::set_vertical_stretch(unsigned int value) +{ + m_vertical_stretch = value; +} + +void ldp_vldp::test_helper(unsigned uIterations) +{ + // We aren't calling think_delay because we want to have a lot of milliseconds pass quickly without actually waiting. + + // make a certain # of milliseconds elapse .... + for (unsigned int u = 0; u < uIterations; u++) + { + pre_think(); + } + +} + +void ldp_vldp::run_tests(list &lstrPassed, list &lstrFailed) +{ + // these tests just basically stress the VLDP .DLL to make sure it will never crash + // under any circumstances + string s = ""; + bool result = false; + + // if we have at least 1 entry in our framefile + if (m_file_index > 0) + { + string path = m_mpeginfo[0].name; // create full pathname to file + + // TEST #1 : try opening and playing without seeking + s = "VLDP TEST #1 (playing and skipping)"; + if (open_and_block(path) == 1) + { + g_local_info.uMsTimer = GET_TICKS(); + if (g_vldp_info->play(g_local_info.uMsTimer) == 1) + { + test_helper(1000); + if (g_vldp_info->skip(5) == 1) + { + lstrPassed.push_back(s); + } + else + { + lstrFailed.push_back(s + " (opened and played, but could not skip)"); + } + } + else lstrFailed.push_back(s + " (opened but could not play)"); + } + else lstrFailed.push_back(s); + + // TEST #2 : try opening the file repeatedly + // This should not cause any problems + s = "VLDP TEST #2 (opening repeatedly)"; + result = true; + for (int i = 0; i < 10; i++) + { + if (!open_and_block(path)) + { + result = false; + break; + } + } + if (result) lstrPassed.push_back(s); + else lstrFailed.push_back(s); + + // TEST #3 : try opening the file and seeking to an illegal frame + s = "VLDP TEST #3 (seeking to illegal frame)"; + if (!g_vldp_info->search_and_block(65534, 0)) + { + lstrPassed.push_back(s); + } + else lstrFailed.push_back(s); + + // TEST #4 : try seeking to a (hopefully) legitimate frame + s = "VLDP TEST #4 (seeking to legit frame)"; + if (g_vldp_info->search_and_block(50, 0) == 1) + { + lstrPassed.push_back(s); + //test_helper(1000); + } + else + { + lstrFailed.push_back(s); + } + + // TEST #5 : play to the end of the file, then try playing again to see what happens + s = "VLDP TEST #5 (playing to end of file, then playing again)"; + if (open_and_block(path) == 1) + { + g_local_info.uMsTimer = m_uElapsedMsSincePlay = m_uBlockedMsSincePlay = 0; + + if (g_vldp_info->play(g_local_info.uMsTimer) == 1) + { + // wait for file to end ... + while ((g_vldp_info->status == STAT_PLAYING) && (!get_quitflag())) + { + SDL_check_input(); + test_helper(250); + } + + if (g_vldp_info->play(g_local_info.uMsTimer) == 1) + { + lstrPassed.push_back(s); + test_helper(1000); + } + else + { + lstrFailed.push_back(s + " - the second time around"); + } + } + else lstrFailed.push_back(s + "opened file, but failed to play it)"); + } + else lstrFailed.push_back(s); + + // TEST #6 : play to the end of the file, then try seeking to see what happens + s = "VLDP TEST #6 (play to end of file, then seek)"; + if (open_and_block(path) == 1) + { + g_local_info.uMsTimer = m_uElapsedMsSincePlay = m_uBlockedMsSincePlay = 0; + + if (g_vldp_info->play(g_local_info.uMsTimer) == 1) + { + // wait for file to end ... + while ((g_vldp_info->status == STAT_PLAYING) && (!get_quitflag())) + { + SDL_check_input(); + test_helper(250); + } + + if (g_vldp_info->search_and_block(50, 0) == 1) + { + lstrPassed.push_back(s); + test_helper(1000); + } + else + { + lstrFailed.push_back(s + "(failed the second time around)"); + } + } + else lstrFailed.push_back(s + "(opened file, but failed to play it)"); + } + else lstrFailed.push_back(s); + + // TEST #7 : open, seek, play, all testing timing + s = "VLDP TEST #7 (seeking, playing with timing tested)"; + if (open_and_block(path) == 1) + { + g_local_info.uMsTimer = m_uElapsedMsSincePlay = m_uBlockedMsSincePlay = 0; + + // search to beginning frame ... + if (g_vldp_info->search_and_block(0, 0) == 1) + { + test_helper(1); // make 1 ms elapse ... + SDL_Delay(1); // give VLDP thread a chance to make its own updates ... + + // make sure that frame is what we expect it to be ... + if (g_vldp_info->current_frame == 0) + { + test_helper(50); // make 50 ms elapse + SDL_Delay(1); // give VLDP thread a chance to make updates + + // make sure current frame has not changed + if (g_vldp_info->current_frame == 0) + { + g_local_info.uMsTimer = m_uElapsedMsSincePlay = m_uBlockedMsSincePlay = 0; + + // so now we start playing ... + if (g_vldp_info->play(0) == 1) + { + test_helper(32); // pause 32 ms (right before frame should change) + SDL_Delay(50); // vldp thread blah blah ... + + // current frame still should not have changed + if (g_vldp_info->current_frame == 0) + { + test_helper(1); // 1 more ms, frame should change now + SDL_Delay(50); // don't fail simply due to the cpu being overloaded + if (g_vldp_info->current_frame == 1) + { + lstrPassed.push_back(s); + } + else lstrFailed.push_back(s + " (frame didn't change to 1)"); + } + else lstrFailed.push_back(s + " (frame changed to " + numstr::ToStr(g_vldp_info->current_frame) + " after play)"); + } + else lstrFailed.push_back(s + " (play failed)"); + } + else lstrFailed.push_back(s + " (current frame changed from 0 after seek)"); + } + else lstrFailed.push_back(s + " (opened, but current frame was not 0)"); + } + else lstrFailed.push_back(s + " (opened but could not search)"); + } + else lstrFailed.push_back(s); + + } // end if there was 1 file in the framefile + else lstrFailed.push_back("VLDP TESTS (Framefile had no entries)"); +} + +// handles VLDP-specific command line args +bool ldp_vldp::handle_cmdline_arg(const char *arg) +{ + bool result = true; + + if (strcasecmp(arg, "-blend")==0) + { + g_filter_type |= FILTER_BLEND; + } + else if (strcasecmp(arg, "-scanlines")==0) + { + g_filter_type |= FILTER_SCANLINES; + } + // should we run a few VLDP tests when the player is initialized? + else if (strcasecmp(arg, "-vldptest")==0) + { + m_testing = true; + } + // should we precache all video streams to RAM? + else if (strcasecmp(arg, "-precache")==0) + { + m_bPreCache = true; + } + // even if we don't have enough RAM, should we still precache all video streams to RAM? + else if (strcasecmp(arg, "-precache_force")==0) + { + m_bPreCache = true; + m_bPreCacheForce = true; + } + + // else it's unknown + else + { + result = false; + } + + return result; +} + + +////////////////////////////////// + +// loads the VLDP dynamic library, returning true on success +bool ldp_vldp::load_vldp_lib() +{ + bool result = false; + +#ifndef STATIC_VLDP // if we're loading VLDP dynamically +#ifndef DEBUG + m_dll_instance = M_LOAD_LIB(vldp2); // load VLDP2.DLL or libvldp2.so +#else + m_dll_instance = M_LOAD_LIB(vldp2_dbg); +#endif + + // If the handle is valid, try to get the function address. + if (m_dll_instance) + { + pvldp_init = (initproc) M_GET_SYM(m_dll_instance, "vldp_init"); + + // if init function was found + if (pvldp_init) + { + result = true; + } + else + { + printerror("VLDP LOAD ERROR : vldp_init could not be loaded"); + } + } + else + { + printerror("ERROR: could not open the VLDP2 dynamic library (file not found maybe?)"); + } + +#else // else if we're loading VLDP statically + pvldp_init = vldp_init; + result = true; +#endif // STATIC_VLDP + + return result; +} + +// frees the VLDP dynamic library if we loaded it in +void ldp_vldp::free_vldp_lib() +{ +#ifndef STATIC_VLDP // if we loaded vldp dynamically, then we need to unload it properly... + + // don't free if the library was never opened + if (m_dll_instance) + { + M_FREE_LIB(m_dll_instance); + } + +#endif // STATIC_VLDP +} + + + + +// read frame conversions in from LD-frame to mpeg-frame data file +bool ldp_vldp::read_frame_conversions() +{ + struct mpo_io *p_ioFileConvert; + string s = ""; + string frame_string = ""; + bool result = false; + string framefile_path; + + framefile_path = m_framefile; + + p_ioFileConvert = mpo_open(framefile_path.c_str(), MPO_OPEN_READONLY); + + // if the file was not found in the relative directory, try looking for it in the framefile directory + if (!p_ioFileConvert) + { + framefile_path = g_homedir.get_framefile(framefile_path); // add directory to front of path + p_ioFileConvert = mpo_open(framefile_path.c_str(), MPO_OPEN_READONLY); + } + + // if the framefile was opened successfully + if (p_ioFileConvert) + { + MPO_BYTES_READ bytes_read = 0; + char *ff_buf = (char *) MPO_MALLOC((unsigned int) (p_ioFileConvert->size+1)); // add an extra byte to null terminate + if (ff_buf != NULL) + { + if (mpo_read(ff_buf, (unsigned int) p_ioFileConvert->size, &bytes_read, p_ioFileConvert)) + { + // if we successfully read in the whole framefile + if (bytes_read == p_ioFileConvert->size) + { + string err_msg = ""; + + ff_buf[bytes_read] = 0; // NULL terminate the end of the file to be safe + + // if parse was successful + if (parse_framefile( + (const char *) ff_buf, + framefile_path.c_str(), + m_mpeg_path, + &m_mpeginfo[0], + m_file_index, + sizeof(m_mpeginfo) / sizeof(struct fileframes), + err_msg)) + { + outstr("Framefile parse succeeded. Video/Audio directory is: "); + printline(m_mpeg_path.c_str()); + result = true; + } + else + { + printerror("Framefile Parse Error"); + printline(err_msg.c_str()); + err_msg = "Mpeg Path : " + m_mpeg_path; + printline(err_msg.c_str()); + printline("---BEGIN FRAMEFILE CONTENTS---"); + // print the entire contents of the framefile to make it easier to us to debug newbie problems using their daphne_log.txt + printline(ff_buf); + printline("---END FRAMEFILE CONTENTS---"); + } + } + else printerror("ldp-vldp.cpp : framefile read error"); + } + else printerror("ldp-vldp.cpp : framefile read error"); + } + else printerror("ldp-vldp.cpp : mem alloc error"); + mpo_close(p_ioFileConvert); + } + else + { + s = "Could not open framefile : " + m_framefile; + printerror(s.c_str()); + } + + return result; +} + +// if file does not exist, we print an error message +bool ldp_vldp::first_video_file_exists() +{ + string full_path = ""; + bool result = false; + + // if we have at least one file + if (m_file_index) + { + full_path = m_mpeg_path; + full_path += m_mpeginfo[0].name; + if (mpo_file_exists(full_path.c_str())) + { + result = true; + } + else + { + full_path = "Could not open file : " + full_path; // keep using full_path just because it's convenient + printerror(full_path.c_str()); + } + } + else + { + printerror("ERROR : Framefile seems empty, it's probably invalid"); + printline("Read the documentation to learn how to create framefiles."); + } + + return result; +} + +// returns true if the last video file has been parsed +// This is so we don't parse_all_video if all files are already parsed +bool ldp_vldp::last_video_file_parsed() +{ + string full_path = ""; + bool result = false; + + // if we have at least one file + if (m_file_index > 0) + { + full_path = m_mpeg_path; + full_path += m_mpeginfo[m_file_index-1].name; + full_path.replace(full_path.length() - 3, 3, "dat"); // replace pre-existing suffix (which is probably .m2v) with 'dat' + + if (mpo_file_exists(full_path.c_str())) + { + result = true; + } + } + // else there is a problem with the frame file so return false + + return result; +} + +// opens (and closes) all video files, forcing any unparsed video files to get parsed +void ldp_vldp::parse_all_video() +{ + unsigned int i = 0; + + for (i = 0; i < m_file_index; i++) + { + // if the file can be opened... + if (open_and_block(m_mpeginfo[i].name)) + { + g_vldp_info->search_and_block(0, 0); // search to frame 0 to render it so the user has something to watch while he/she waits + think(); // let opengl have a chance to display the frame + } + else + { + outstr("LDP-VLDP: Could not parse video because file "); + outstr(m_mpeginfo[i].name.c_str()); + printline(" could not be opened."); + break; + } + } +} + +bool ldp_vldp::precache_all_video() +{ + bool bResult = true; + + unsigned int i = 0; + string full_path = ""; + mpo_io *io = NULL; + + // to make sure the total file size is correct + // (it's legal for a framefile to have the same file listed more than once) + set sDupePreventer; + + MPO_UINT64 u64TotalBytes = 0; + + // first compute file size ... + for (i = 0; i < m_file_index; i++) + { + full_path = m_mpeg_path + m_mpeginfo[i].name; // create full pathname to file + + // if this file's size hasn't already been taken into account + if (sDupePreventer.find(m_mpeginfo[i].name) == sDupePreventer.end()) + { + io = mpo_open(full_path.c_str(), MPO_OPEN_READONLY); + if (io) + { + u64TotalBytes += io->size; + mpo_close(io); // we're done with this file ... + sDupePreventer.insert(m_mpeginfo[i].name); // we've used it now ... + } + // else file can't be opened ... + else + { + outstr("LDP-VLDP: when precaching, the file "); + outstr(full_path.c_str()); + printline(" cannot be opened."); + bResult = false; + break; + } + } // end if the filesize hasn't been taken into account + // else the filesize has already been taken into account + } + + // if we were able to compute the file size ... + if (bResult) + { + const unsigned int uFUDGE = 256; // how many megs we assume the OS needs in addition to our application running + unsigned int uReqMegs = (unsigned int) ((u64TotalBytes / 1048576) + uFUDGE); + unsigned int uMegs = get_sys_mem(); + + // if we have enough memory (accounting for OS overhead, which may need to increase in the future) + // OR if the user wants to force precaching despite our check ... + if ((uReqMegs < uMegs) || (m_bPreCacheForce)) + { + for (i = 0; i < m_file_index; i++) + { + // if the file in question has not yet been precached + if (m_mPreCachedFiles.find(m_mpeginfo[i].name) == m_mPreCachedFiles.end()) + { + // try to precache and if it fails, bail ... + if (precache_and_block(m_mpeginfo[i].name)) + { + // store the index of the file that we last precached + m_mPreCachedFiles[m_mpeginfo[i].name] = g_vldp_info->uLastCachedIndex; + } + else + { + full_path = m_mpeg_path + m_mpeginfo[i].name; + + outstr("LDP-VLDP: precaching of file "); + outstr(full_path.c_str()); + printline(" failed."); + bResult = false; + } + } // end if file has not been precached + // else file has already been precached, so don't precache it again + } + } + else + { + printline( ((string) "Not enough memory to precache video stream. You have about " + + numstr::ToStr(uMegs) + " but need " + + numstr::ToStr(uReqMegs)).c_str()); + bResult = false; + } + } + + return bResult; +} + +Uint64 ldp_vldp::get_audio_sample_position(unsigned int uTargetMpegFrame) +{ + Uint64 u64AudioTargetPos = 0; + + if (!need_frame_conversion()) + { + u64AudioTargetPos = (((Uint64) uTargetMpegFrame) * FREQ1000) / g_game->get_disc_fpks(); + // # of samples to seek to in the audio stream + } + // If we are already doing a frame conversion elsewhere, we don't want to do it here again twice + // but we do need to set the audio to the correct time + else + { + u64AudioTargetPos = (((Uint64) uTargetMpegFrame) * FREQ1000) / get_frame_conversion_fpks(); + } + + return u64AudioTargetPos; +} + + +// returns # of frames to seek into file, and mpeg filename +// if there's an error, filename is "" +// WARNING: This assumes the mpeg and disc are running at exactly the same FPS +// If they aren't, you will need to calculate the actual mpeg frame to seek to +// The reason I don't return time here instead of frames is because it is more accurate to +// return frames if they are at the same FPS (which hopefully they are hehe) +Uint32 ldp_vldp::mpeg_info (string &filename, Uint32 ld_frame) +{ + unsigned int index = 0; + Uint32 mpeg_frame = 0; // which mpeg frame to seek (assuming mpeg and disc have same FPS) + filename = ""; // blank 'filename' means error, so we default to this condition for safety reasons + + // find the mpeg file that has the LD frame inside of it + while ((index+1 < m_file_index) && (ld_frame >= m_mpeginfo[index+1].frame)) + { + index = index + 1; + } + + // make sure that the frame they've requested comes after the first frame in our framefile + if (ld_frame >= m_mpeginfo[index].frame) + { + // make sure a filename exists (when can this ever fail? verify!) + if (m_mpeginfo[index].name != "") + { + filename = m_mpeginfo[index].name; + mpeg_frame = (Uint32) (ld_frame - m_mpeginfo[index].frame); + m_cur_ldframe_offset = m_mpeginfo[index].frame; + } + else + { + printline("VLDP error, no filename found"); + mpeg_frame = 0; + } + } + // else frame is out of range ... + + return(mpeg_frame); +} + +//////////////////////////////////////////////////////////////////////////////////////// + +// puts the yuv_callback into a blocking state +// This is necessary if the gamevid ever becomes invalid for a period of time (ie it gets free'd and re-allocated in seektest) +// timeout is how many ms to wait before giving up +// returns true if it got the lock or false if it couldn't get a lock +bool ldp_vldp::lock_overlay(Uint32 timeout) +{ + bool bRes = false; + + if (g_vldp_info) + { + bRes = g_vldp_info->lock(timeout) == VLDP_TRUE; + } + // else g_vldp_info is NULL which means the init function hasn't been called yet probably + + return bRes; +} + +// releases the yuv_callback from its blocking state +bool ldp_vldp::unlock_overlay(Uint32 timeout) +{ +/* + Uint32 time = refresh_ms_time(); + + mutex_lock_request = false; + + // sleep until the yuv callback acknowledges that it has control once again + while (mutex_lock_acknowledge) + { + SDL_Delay(0); + + // if we've timed out + if (elapsed_ms_time(time) > timeout) + { + printline("LDP_VLDP : unlock_overlay timed out while trying to unlock"); + break; + } + } + + return (!mutex_lock_acknowledge); + */ + + return (g_vldp_info->unlock(timeout) == VLDP_TRUE); +} + +bool ldp_vldp::parse_framefile(const char *pszInBuf, const char *pszFramefileFullPath, + string &sMpegPath, struct fileframes *pFrames, unsigned int &frame_idx, unsigned int max_frames, string &err_msg) +{ + bool result = false; + const char *pszPtr = pszInBuf; + unsigned int line_number = 0; // for debugging purposes + char ch = 0; + + frame_idx = 0; + err_msg = ""; + + // read absolute or relative directory + pszPtr = read_line(pszPtr, sMpegPath); + + // if there are no additional lines + if (!pszPtr) + { + // if there is at least 1 line + if (sMpegPath.size() > 0) + { + err_msg = "Framefile only has 1 line in it. Framefiles must have at least 2 lines in it."; + } + else err_msg = "Framefile appears to be empty. Framefile must have at least 2 lines in it."; + return false; // normally I only like to have 1 return per function, but this is a good spot to return.. + } + + ++line_number; // if we get this far, it means we've read our first line + + // If sMpegPath is NOT an absolute path (doesn't begin with a unix '/' or have the second char as a win32 ':') + // then we want to use the framefile's path for convenience purposes + // (this should be win32 and unix compatible) + if ((sMpegPath[0] != '/') && (sMpegPath[0] != '\\') && (sMpegPath[1] != ':')) + { + string path = ""; + + // try to isolate the path of the framefile + if (get_path_of_file(pszFramefileFullPath, path)) + { + // put the path of the framefile in front of the relative path of the mpeg files + // This will allow people to move the location of their mpegs around to + // different directories without changing the framefile at all. + // For example, if the framefile and the mpegs are in the same directory, + // then the framefile's first line could be "./" + sMpegPath = path + sMpegPath; + } + } + // else it is an absolute path, so we ignore the framefile's path + + string s = ""; + // convert all \'s to /'s to be more unix friendly (doesn't hurt win32) + for (unsigned int i = 0; i < sMpegPath.length(); i++) + { + ch = sMpegPath[i]; + if (ch == '\\') ch = '/'; + s += ch; + } + sMpegPath = s; + + // Clean up after the user if they didn't end the path with a '/' character + if (ch != '/') + { + sMpegPath += "/"; // windows will accept / as well as \, so we're ok here + } + + string word = "", remaining = ""; + result = true; // from this point, we should assume success + Sint32 frame = 0; + + // parse through entire file + while (pszPtr != NULL) + { + pszPtr = read_line(pszPtr, s); // read in a line + ++line_number; + + // if we can find the first word (frame #) + if (find_word(s.c_str(), word, remaining)) + { + // check for overflow + if (frame_idx >= max_frames) + { + err_msg = "Framefile has too many entries in it." + " You can increase the value of MAX_MPEG_FILES and recompile."; + result = false; + break; + } + + frame = numstr::ToInt32(word.c_str()); // this should work, even with whitespace after it + + // If frame is valid AND we are able to find the name of the + // (a non-integer will be converted to 0, so we need to make sure it really is supposed to be 0) + if (((frame != 0) || (word == "0")) + && find_word(remaining.c_str(), word, remaining)) + { + pFrames[frame_idx].frame = (Sint32) frame; + pFrames[frame_idx].name = word; + ++frame_idx; + } + else + { + // This error has been stumping self-proclaimed "experienced emu'ers" + // so I am going to extra effort to make it clear to them what the + // problem is. + err_msg = "Expected a number followed by a string, but on line " + + numstr::ToStr(line_number) + ", found this: " + s + "("; + // print hex values of bad string to make troubleshooting easier + for (size_t idx = 0; idx < s.size(); idx++) + { + err_msg += "0x" + numstr::ToStr(s[idx], 16) + " "; + } + + err_msg += ")"; + result = false; + break; + } + } + // else it is probably just an empty line, so we can ignore it + + } // end while file hasn't been completely parsed + + // if we ended up with no entries AND didn't get any error, then the framefile is bad + if ((frame_idx == 0) && (result == true)) + { + err_msg = "Framefile appears to not have any entries in it."; + result = false; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// + +// returns VLDP_TRUE on success, VLDP_FALSE on failure +int prepare_frame_callback_with_overlay(struct yuv_buf *src) +{ + int result = VLDP_FALSE; + + /* + // if another thread has requested that we block, then do so. + // DANGER : This is dangerous because it has endless loop potential + // However, it is also fast and therefore we just need to be conscious coders and not let endless loops happen + if (mutex_lock_request) + { + mutex_lock_acknowledge = 1; + // wait until other thread has unlocked (endless loop potential) + while (mutex_lock_request) + { + SDL_Delay(0); + } + mutex_lock_acknowledge = 0; + } + */ + + if (SDL_LockYUVOverlay(g_hw_overlay) == 0) + { + SDL_Surface *gamevid = g_game->get_finished_video_overlay(); // This could change at any time (double buffering, for example) + // so we are forced to query it every time we run this function. If someone has a better idea, let me know + + // sanity check. Make sure the game video is the proper width. + if ((gamevid->w << 1) == g_hw_overlay->w) + { + // adjust for vertical offset + // We use _half_ of the requested vertical offset because the mpeg video is twice + // the size of the overlay + Uint8 *gamevid_pixels = (Uint8 *) gamevid->pixels - (gamevid->w * (g_vertical_offset - g_vertical_stretch)); + +#ifdef DEBUG + // make sure that the g_vertical_offset isn't out of bounds + Uint8 *last_valid_byte = ((Uint8 *) gamevid->pixels) + (gamevid->w * gamevid->h) - 1; + assert(gamevid_pixels < last_valid_byte); +#endif + + unsigned int row = 0; + unsigned int col = 0; + Uint32 w_double = g_hw_overlay->w << 1; // twice the overlay width, to avoid calculating this more than once + Uint32 h_half = g_hw_overlay->h >> 1; // half of the overlay height, to avoid calculating this more than once + Uint8 *dst_ptr; + + // this could be global, any benefit? + t_yuv_color* yuv_palette = get_yuv_palette(); + + unsigned int channel0_pitch = g_hw_overlay->pitches[0]; // this val gets used a lot so we put it into a var + + dst_ptr = (Uint8 *) g_hw_overlay->pixels[0]; + Uint8 *Y = (Uint8 *) src->Y; + Uint8 *Y2 = (Uint8 *) src->Y + g_hw_overlay->w; + Uint8 *U = (Uint8 *) src->U; + Uint8 *V = (Uint8 *) src->V; + + // if letterbox removal is active, shift video down to compensate + for (unsigned int skip = 0; skip < g_vertical_stretch; skip += 2) + { + Y += (g_hw_overlay->w * 4); + Y2 += (g_hw_overlay->w * 4); + U += g_hw_overlay->w; + V += g_hw_overlay->w; + } + + // do 2 rows at a time + for (row = 0; row < h_half; row++) + { + // calculate this here to avoid calculating too often + int adjusted_row = ((int) row) - g_vertical_offset; + bool row_in_range = ((adjusted_row >= 0) && (adjusted_row < gamevid->h)); + t_yuv_color *palette = NULL; + + // do 4 bytes at a time, for twice the width of the overlay since we're using YUY2 + for (col = 0; col < w_double; col += 4) + { + // if we can safely draw from the video overlay + if (row_in_range) palette = &yuv_palette[*gamevid_pixels]; + + // If we are out of range, OR if the current color is transparent, + // then draw the mpeg video pixel instead of the video overlay + // (if palette is NULL, the compiler shouldn't try to dereference palette->transparent) + if ((palette == NULL) || palette->transparent) + { + unsigned int Y_chunk = *((Uint16 *) Y); + unsigned int Y2_chunk = *((Uint16 *) Y2); + unsigned int V_chunk = *V; + unsigned int U_chunk = *U; + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + //Little-Endian (Intel) + *((Uint32 *) (g_line_buf + col)) = (Y_chunk & 0xFF) | (U_chunk << 8) | + ((Y_chunk & 0xFF00) << 8) | (V_chunk << 24); + *((Uint32 *) (g_line_buf2 + col)) = (Y2_chunk & 0xFF) | (U_chunk << 8) | + ((Y2_chunk & 0xFF00) << 8) | (V_chunk << 24); +#else + //Big-Endian (Mac) + *((Uint32 *) (g_line_buf + col)) = ((Y_chunk & 0xFF00) << 16) | ((U_chunk) << 16) | + ((Y_chunk & 0xFF) << 8) | (V_chunk); + *((Uint32 *) (g_line_buf2 + col)) = ((Y2_chunk & 0xFF00) << 16) | ((U_chunk) << 16) | + ((Y2_chunk & 0xFF) << 8) | (V_chunk); +#endif + } + + // if we have an overlay pixel to be drawn + else + { +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + //Little-Endian (Intel) + *((Uint32 *) (g_line_buf + col)) = + *((Uint32 *) (g_line_buf2 + col)) = palette->y | (palette->u << 8) + | (palette->y << 16) | (palette->v << 24); +#else + //Big-Endian (Mac) + *((Uint32 *) (g_line_buf + col)) = + *((Uint32 *) (g_line_buf2 + col)) = (palette->y << 24) | (palette->u << 16) + | (palette->y << 8) | (palette->v); +#endif + + } + Y += 2; + Y2 += 2; + U++; + V++; + gamevid_pixels++; + } + + // if we're not doing scanlines + if (!(g_filter_type & FILTER_SCANLINES)) + { + // no filtering at all + if (!(g_filter_type & FILTER_BLEND)) + { + memcpy(dst_ptr, g_line_buf, (g_hw_overlay->w << 1)); + memcpy(dst_ptr + channel0_pitch, g_line_buf2, (g_hw_overlay->w << 1)); + } + else + { + g_blend_func(); // blend the two lines into g_line_buf3 + // this won't affect video overlay because it is already doubled in size anyway + memcpy(dst_ptr, g_line_buf3, (g_hw_overlay->w << 1)); + memcpy(dst_ptr + channel0_pitch, g_line_buf3, (g_hw_overlay->w << 1)); + } + } + + // if we're doing scanlines + else + { + // do a black YUY2 line (the first line should be black to workaround nvidia bug) + for (int i = 0; i < (g_hw_overlay->w << 1); i+=4) + { + *((Uint32 *) (dst_ptr + i)) = YUY2_BLACK; // this value is black in YUY2 mode + } + + if (g_filter_type & FILTER_BLEND) + { + g_blend_func(); // blend the two lines into g_line_buf3 + // this won't affect video overlay because it is already doubled in size anyway + memcpy(dst_ptr + channel0_pitch, g_line_buf3, (g_hw_overlay->w << 1)); + } + else + { + memcpy(dst_ptr + channel0_pitch, g_line_buf, (g_hw_overlay->w << 1)); // this could be g_line_buf2 also + } + } + + dst_ptr += (channel0_pitch << 1); // we've done 2 rows, so skip a row + Y += g_hw_overlay->w; // we've done 2 vertical Y pixels, so skip a row + Y2 += g_hw_overlay->w; + } + + // if we've been instructed to take a screenshot, do so now that the overlay is in place + if (g_take_screenshot) + { + g_take_screenshot = false; + take_screenshot(g_hw_overlay); + } + } // end if sanity check passed + + // if sanity check failed + else + { + static bool warned = false; + + // newbies might appreciate knowing why their video overlay isn't working, so + // let's give them some instruction in the logfile. We only want to print this once + // to avoid spamming, hence the 'warned' boolean + if (!warned) + { + // if the game does not dynamically reallocate its overlay size (most of them don't) + if (!g_game->is_overlay_size_dynamic()) + { + char s[81]; + printline("WARNING : Your MPEG doesn't match your video overlay's resolution."); + printline("Video overlay will not work!"); + sprintf(s, "Your MPEG's size is %d x %d, and needs to be %d x %d", g_hw_overlay->w, g_hw_overlay->h, (gamevid->w << 1), (gamevid->h << 1)); + printline(s); + } + // else, there is no problem at all, so don't alarm the user + warned = true; + } + + if (g_game->is_overlay_size_dynamic()) + { + // MPEG size has changed, so drop a hint to any game + // that resizes dynamically. + g_game->set_video_overlay_needs_update(true); + } + } // end sanity check + + result = VLDP_TRUE; // we were successful (we return successful even if overlay part failed because we want to render _something_) + + SDL_UnlockYUVOverlay(g_hw_overlay); + } // end if locking the overlay was successful + + // else we are trying to feed info to the overlay too quickly, so we'll just have to wait + + return result; +} + +// faster callback because it assumes we have no overlay +// returns VLDP_TRUE on success, VLDP_FALSE on failure +int prepare_frame_callback_without_overlay(struct yuv_buf *buf) +{ + int result = VLDP_FALSE; + + // if locking the video overlay is successful + if (SDL_LockYUVOverlay(g_hw_overlay) == 0) + { + buf2overlay_YUY2(g_hw_overlay, buf); + + // if we've been instructed to take a screenshot, do so now that the overlay is in place + if (g_take_screenshot) + { + g_take_screenshot = false; + take_screenshot(g_hw_overlay); + } + + SDL_UnlockYUVOverlay(g_hw_overlay); + + result = VLDP_TRUE; + } + + // else just ignore + + return result; +} + +// displays the frame as fast as possible +void display_frame_callback(struct yuv_buf *buf) +{ + SDL_DisplayYUVOverlay(g_hw_overlay, g_screen_clip_rect); + +#if 0 + { + static unsigned int uOldTime = 0; + static unsigned int uFrameCount = 0; + + unsigned int uTimer = refresh_ms_time(); + unsigned int uDiff = uTimer - uOldTime; + string strMsg = "[" + numstr::ToStr(g_vldp_info->current_frame) + "] Time since last frame change: " + numstr::ToStr(uDiff) + " ms"; + FILE *F = fopen("vldp_log.txt", "ab"); + if (F) + { + fprintf(F, "%s%c%c", strMsg.c_str(), 13, 10); + fclose(F); + } + uOldTime = uTimer; + + } +#endif +} + +// This function converts the YV12-formatted 'src' to a YUY2-formatted overlay (which Xbox-Daphne may be using) +// copies the contents of src into dst +// assumes destination overlay is locked and *IMPORTANT* assumes src and dst are the same resolution +void buf2overlay_YUY2(SDL_Overlay *dst, struct yuv_buf *src) +{ + unsigned int channel0_pitch = dst->pitches[0]; + Uint8 *dst_ptr = (Uint8 *) dst->pixels[0]; + Uint8 *Y = (Uint8 *) src->Y; + Uint8 *Y2 = ((Uint8 *) src->Y) + dst->w; + Uint8 *U = (Uint8 *) src->U; + Uint8 *V = (Uint8 *) src->V; + int col, row; + + // do 2 rows at a time + for (row = 0; row < (dst->h >> 1); row++) + { + // do 4 bytes at a time, but only iterate for w_half + for (col = 0; col < (dst->w << 1); col += 4) + { + unsigned int Y_chunk = *((Uint16 *) Y); + unsigned int Y2_chunk = *((Uint16 *) Y2); + unsigned int V_chunk = *V; + unsigned int U_chunk = *U; + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + + //Little-Endian (PC) + *((Uint32 *) (g_line_buf + col)) = (Y_chunk & 0xFF) | (U_chunk << 8) | + ((Y_chunk & 0xFF00) << 8) | (V_chunk << 24); + *((Uint32 *) (g_line_buf2 + col)) = (Y2_chunk & 0xFF) | (U_chunk << 8) | + ((Y2_chunk & 0xFF00) << 8) | (V_chunk << 24); + +#else + + //Big-Endian (Mac) + *((Uint32 *) (g_line_buf + col)) = ((Y_chunk & 0xFF00) << 16) | ((U_chunk) << 16) | + ((Y_chunk & 0xFF) << 8) | (V_chunk); + *((Uint32 *) (g_line_buf2 + col)) = ((Y2_chunk & 0xFF00) << 16) | ((U_chunk) << 16) | + ((Y2_chunk & 0xFF) << 8) | (V_chunk); + +#endif + + Y += 2; + Y2 += 2; + U++; + V++; + } + + // if we're not doing scanlines + if (!(g_filter_type & FILTER_SCANLINES)) + { + // no filtering at all + if (!(g_filter_type & FILTER_BLEND)) + { + memcpy(dst_ptr, g_line_buf, (dst->w << 1)); + memcpy(dst_ptr + channel0_pitch, g_line_buf2, (dst->w << 1)); + } + else + { + g_blend_func(); // blend the two lines into g_line_buf3 + // this won't affect video overlay because it is already doubled in size anyway + memcpy(dst_ptr, g_line_buf3, (dst->w << 1)); + memcpy(dst_ptr + channel0_pitch, g_line_buf3, (dst->w << 1)); + } + } + + // if we're doing scanlines + else + { + // do a black YUY2 line first + // (on nvidia it makes the top line too bright if the black line doesn't come first!) + for (int i = 0; i < (dst->w << 1); i+=4) + { + *((Uint32 *) (dst_ptr + i)) = YUY2_BLACK; // this value is black in YUY2 mode + } + + if (g_filter_type & FILTER_BLEND) + { + g_blend_func(); // blend the two lines into g_line_buf3 + // this won't affect video overlay because it is already doubled in size anyway + memcpy(dst_ptr + channel0_pitch, g_line_buf3, (dst->w << 1)); + } + else + { + memcpy(dst_ptr + channel0_pitch, g_line_buf, (dst->w << 1)); // this could also be g_line_buf2 + } + } + + dst_ptr += (channel0_pitch << 1); // we've done 2 rows, so skip a row + Y += dst->w; // we've done 2 vertical Y pixels, so skip a row + Y2 += dst->w; + } +} + +/////////////////// + +Uint32 g_parse_start_time = 0; // when mpeg parsing began approximately ... +double g_parse_start_percentage = 0.0; // the first percentage report we received ... +bool g_parsed = false; // whether we've received any data at all ... + +// this should be called from parent thread +void update_parse_meter() +{ + // if we have some data collected + if (g_dPercentComplete01 >= 0) + { + double elapsed_s = 0; // how many seconds have elapsed since we began this ... + double total_s = 0; // how many seconds the entire operation is likely to take + double remaining_s = 0; // how many seconds are remaining + + double percent_complete = g_dPercentComplete01 * 100.0; // switch it from [0-1] to [0-100] + + elapsed_s = (elapsed_ms_time(g_parse_start_time)) * 0.001; // compute elapsed seconds + double percentage_accomplished = percent_complete - g_parse_start_percentage; // how much 'percentage' points we've accomplished + + total_s = (elapsed_s * 100.0) / percentage_accomplished; // 100 signifies 100 percent (I got this equation by doing some algebra on paper) + + // as long as percent_complete is always 100 or lower, total_s will always be >= elapsed_s, so no checking necessary here + remaining_s = total_s - elapsed_s; + + SDL_Surface *screen = get_screen_blitter(); // the main screen that we can draw on ... + SDL_FillRect(screen, NULL, 0); // erase previous stuff on the screen blitter + + // if we have some progress to report ... + if (remaining_s > 0) + { + char s[160]; + int half_h = screen->h >> 1; // calculations to center message on screen ... + int half_w = screen->w >> 1; + sprintf(s, "Video parsing is %02.f percent complete, %02.f seconds remaining.\n", percent_complete, remaining_s); + SDLDrawText(s, screen, FONT_SMALL, (half_w-((strlen(s)/2)*FONT_SMALL_W)), half_h-FONT_SMALL_H); + + // now draw a little graph thing ... + SDL_Rect clip = screen->clip_rect; + const int THICKNESS = 10; // how thick our little status bar will be + clip.y = (clip.h - THICKNESS) / 2; // where to start our little status bar + clip.h = THICKNESS; + clip.y += FONT_SMALL_H + 5; // give us some padding + + SDL_FillRect(screen, &clip, SDL_MapRGB(screen->format, 255, 255, 255)); // draw a white bar across the screen ... + + clip.x++; // move left boundary in 1 pixel + clip.y++; // move upper boundary down 1 pixel + clip.w -= 2; // move right boundary in 1 pixel + clip.h -= 2; // move lower boundary in 1 pixel + + SDL_FillRect(screen, &clip, SDL_MapRGB(screen->format, 0, 0, 0)); // fill inside with black + + clip.w = (Uint16) ((screen->w * g_dPercentComplete01) + 0.5)-1; // compute how wide our progress bar should be (-1 to take into account left pixel border) + + // go from full red (hardly complete) to full green (fully complete) + SDL_FillRect(screen, &clip, SDL_MapRGB(screen->format, + (Uint8) (255 * (1.0 - g_dPercentComplete01)), + (Uint8) (255 * g_dPercentComplete01), + 0)); + } + } +} + +// percent_complete is between 0 and 1 +// a negative value means that we are starting to parse a new file NOW +void report_parse_progress_callback(double percent_complete_01) +{ + g_dPercentComplete01 = percent_complete_01; + g_bGotParseUpdate = true; + g_parsed = true; // so we can know to re-create the overlay + + // if a new parse is starting + if (percent_complete_01 < 0) + { + // NOTE : this would be a good place to automatically free the yuv overlay + // BUT it was causing crashes... free_yuv_overlay here if you find any compatibility problems on other platforms + g_parse_start_time = refresh_ms_time(); + g_parse_start_percentage = 0; + } +} + +/////////////////// + +extern unsigned int g_draw_width, g_draw_height; + +// this always gets called before the draw_callback and always after report_parse_progress callback +void report_mpeg_dimensions_callback(int width, int height) +{ + unsigned int uTimer = refresh_ms_time(); + + // if we haven't blitted this information to the screen, then wait for other thread to do so before we continue ... + while ((g_bGotParseUpdate) && (elapsed_ms_time(uTimer) < 3000)) + { + make_delay(1); + } + + g_screen_clip_rect = &get_screen_blitter()->clip_rect; // used a lot, we only want to calculate it once + + // if draw width is less than the screen width + if (g_draw_width < g_screen_clip_rect->w) + { + // center horizontally + unsigned int uDiff = g_screen_clip_rect->w - g_draw_width; + g_screen_clip_rect->x += (uDiff / 2); + g_screen_clip_rect->w = g_draw_width; + } + + // if draw height is less than the screen height + if (g_draw_height < g_screen_clip_rect->h) + { + // center vertically + unsigned int uDiff = g_screen_clip_rect->h - g_draw_height; + g_screen_clip_rect->y += (uDiff / 2); + g_screen_clip_rect->h = g_draw_height; + } + + // if we drew some stuff on the screen, then we need to free the overlay and re-create it + if (g_parsed) + { + free_yuv_overlay(); + g_parsed = false; + } + + // if an overlay exists, but its dimensions are wrong, we need to de-allocate it + if (g_hw_overlay && ((g_hw_overlay->w != width) || (g_hw_overlay->h != height))) + { + free_yuv_overlay(); + } + + // blitting is not allowed once we create the YUV overlay ... + g_ldp->set_blitting_allowed(false); + + // if our overlay has been de-allocated, or if we never had one to begin with ... then allocate it now + if (!g_hw_overlay) + { + // create overlay, taking into account any letterbox removal we're doing + // (*4 because our pixels are *2 the height of the graphics, AND we're doing it at the top and bottom) + g_hw_overlay = SDL_CreateYUVOverlay (width, height - (g_vertical_stretch * 4), SDL_YUY2_OVERLAY, get_screen()); + + // safety check + if (!g_hw_overlay) + { + printline("ldp-vldp.cpp : YUV overlay creation failed!"); + set_quitflag(); + } + + // if overlay was successfully created, then indicate in the log whether it is HW accelerated or not + else + { + string msg = "YUV overlay is done in software (ie unaccelerated)."; + if (g_hw_overlay->hw_overlay) + { + msg = "YUV overlay is hardware accelerated."; + } + printline(msg.c_str()); // add it to the daphne_log.txt + } + + // we don't need to check whether these buffers have been allocated or not because this is checked for earlier + // when we check to see if g_hw_overlay has been allocated + g_blank_yuv_buf.Y_size = width*height; + g_blank_yuv_buf.Y = MPO_MALLOC(g_blank_yuv_buf.Y_size); + memset(g_blank_yuv_buf.Y, 0, g_blank_yuv_buf.Y_size); // blank Y color + g_blank_yuv_buf.UV_size = g_blank_yuv_buf.Y_size >> 2; + g_blank_yuv_buf.U = MPO_MALLOC(g_blank_yuv_buf.UV_size); + memset(g_blank_yuv_buf.U, 127, g_blank_yuv_buf.UV_size); // blank U color + g_blank_yuv_buf.V = MPO_MALLOC(g_blank_yuv_buf.UV_size); + memset(g_blank_yuv_buf.V, 127, g_blank_yuv_buf.UV_size); // blank V color + + // yuy2 needs twice as much space across for lines + g_line_buf = MPO_MALLOC(width * 2); + g_line_buf2 = MPO_MALLOC(width * 2); + g_line_buf3 = MPO_MALLOC(width * 2); + } + // else g_hw_overlay exists, so we don't need to re-allocate it + + // This is some one-time setup stuff that will be used by the blending functions + // It will be used by both the prepare w/ overlay and prepare w/o overlay functions + if (g_filter_type & FILTER_BLEND) + { + g_blend_line1 = g_line_buf; + g_blend_line2 = g_line_buf2; + g_blend_dest = g_line_buf3; + g_blend_iterations = g_hw_overlay->w << 1; +#ifdef DEBUG + assert(((g_blend_iterations % 8) == 0) && (g_blend_iterations >= 8)); // blend MMX does 8 bytes at a time +#endif + } + +} + +void free_yuv_overlay() +{ + if (g_hw_overlay) + { + SDL_FreeYUVOverlay(g_hw_overlay); + } + g_hw_overlay = NULL; + + // free line bufs + MPO_FREE(g_line_buf); + MPO_FREE(g_line_buf2); + MPO_FREE(g_line_buf3); + + // free blank buf ... + MPO_FREE(g_blank_yuv_buf.Y); + MPO_FREE(g_blank_yuv_buf.U); + MPO_FREE(g_blank_yuv_buf.V); +} + +// makes the laserdisc video black while drawing game's video overlay on top +void blank_overlay() +{ + // only do this if the HW overlay has already been allocated + if (g_hw_overlay) + { + g_local_info.prepare_frame(&g_blank_yuv_buf); + g_local_info.display_frame(&g_blank_yuv_buf); + } +} diff --git a/ldp-out/ldp-vldp.h b/ldp-out/ldp-vldp.h new file mode 100644 index 000000000..10ff7ed46 --- /dev/null +++ b/ldp-out/ldp-vldp.h @@ -0,0 +1,189 @@ +/* + * ldp-vldp.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef LDP_VLDP_H +#define LDP_VLDP_H + +#include +#include +#include +#include + +using namespace std; + +#ifdef WIN32 +#pragma warning (disable:4786) // disable warning about truncating to 255 in debug info +#endif + +///////////////////////////////////////////////////////////////////// + +// maximum # of mpeg files that we will handle +#define MAX_MPEG_FILES 500 + +struct fileframes +{ + string name; // name of mpeg file + Sint32 frame; // ldp frame that mpeg file starts on +}; + +// these values can be OR'd together to create multiple filter effects +const int FILTER_NONE = 0; // no filtering +const int FILTER_BLEND = (1 << 0); // blend fields together (cheap de-interlace) +const int FILTER_SCANLINES = (1 << 1); // make every other field black (to give it a more authentic look, this also de-interlaces for free) + +#include "ldp.h" +#include "../io/dll.h" + +class ldp_vldp : public ldp +{ +public: + ldp_vldp(); + ~ldp_vldp(); + bool init_player(); + void shutdown_player(); + + // NOTE : open_and_block prepands m_mpeg_path to the filename + bool open_and_block(const string &strFilename); + bool precache_and_block(const string &strFilename); + bool wait_for_status(unsigned int uStatus); + bool nonblocking_search(char *); + int get_search_result(); + unsigned int play(); + bool skip_forward(Uint32 frames_to_skip, Uint32 target_frame); + void pause(); + bool change_speed(unsigned int uNumerator, unsigned int uDenominator); + void think(); +#ifdef DEBUG + unsigned int get_current_frame(); // enable for accuracy testing only +#endif + void request_screenshot(); + void set_search_blanking(bool); + void set_skip_blanking(bool); + void set_seek_frames_per_ms(double value); + void set_min_seek_delay(unsigned int); + void set_framefile(const char *filename); + void set_altaudio(const char *audio_suffix); + void set_vertical_stretch(unsigned int); + + void test_helper(unsigned uIterations); + + // runs through a bunch of tests and returns results in 'lstrPassed' and 'lstrFailed' + void run_tests(list &lstrPassed, list &lstrFailed); + + bool handle_cmdline_arg(const char *arg); + bool lock_overlay(Uint32); + bool unlock_overlay(Uint32); + + // parses framefile (contained in pszInBuf) and returns the absolute/relative path to the mpegs in 'sMpegPath', + // and populates 'pFrames' until it runs out of data, or hits the 'max_frames' limit. + // 'pszFramefileFullPath' is the relative/absolute path to the framefile including the filename. This is to make + // automatic testing easier, and to calculate sMpegPath correctly. + // Returns true if parsing succeeded, or false if framefile is invalid. If returning false, 'err_msg' will have + // a description of the error. + // NOTE : this function is public so that 'releasetest' can do some framefile parse tests. + bool parse_framefile(const char *pszInBuf, const char *pszFramefileFullPath, string &sMpegPath, + struct fileframes *pFrames, unsigned int &frame_index, unsigned int max_frames, string &err_msg); + +private: + bool load_vldp_lib(); + void free_vldp_lib(); + bool read_frame_conversions(); + bool first_video_file_exists(); + bool last_video_file_parsed(); + void parse_all_video(); + + // Attempts to precache all video, returns false if there isn't enough RAM and we aren't overriding the safety check + bool precache_all_video(); + + // Gets the position in the audio stream to seak (in samples), using the + // target mpeg frame as input. (The target mpeg frame is relative to the beginning + // of the mpeg, which is not necessarily the same as the laserdisc frame) + Uint64 get_audio_sample_position(unsigned int uTargetMpegFrame); + + // NOTE : 'filename' does not include the prefix path + Uint32 mpeg_info (string &filename, Uint32 ld_frame); + + Sint32 m_target_mpegframe; // mpeg frame # we are seeking to + Sint32 m_cur_ldframe_offset; // which laserdisc frame corresponds to the first frame in current mpeg file + + // strings + string m_cur_mpeg_filename; // name of the mpeg file we currently have open + string m_mpeg_path; // location of mpeg file(s) to play + string m_framefile; // name of the framefile we load to get the names of the mpeg files and their frame #'s + string m_altaudio_suffix; //adds a suffix to the ogg filename, to support alternate soundtracks + + struct fileframes m_mpeginfo[MAX_MPEG_FILES]; // names of mpeg files + unsigned int m_file_index; // # of mpeg files in our list + DLL_INSTANCE m_dll_instance; // pointer to DLL we load + + bool m_bFramefileSet; // whether m_framefile was set via commandline or if it's just the default from the constructor + bool m_audio_file_opened; // whether we have audio to accompany the video + bool m_blank_on_searches; // should we blank while searching? + bool m_blank_on_skips; // should we blank while skipping? + unsigned int m_vertical_stretch; // vertically stretch video (value of 24 to remove letterboxing for Cliffhanger) + double m_seek_frames_per_ms; // max # of frames that VLDP will seek per millisecond (0 = no limit) + unsigned int m_min_seek_delay; // min # of milliseconds to force seek to last + bool m_testing; // should we do a few simple tests to make sure VLDP is functioning robustly? + bool m_bPreCache; // should we precache all video? + bool m_bPreCacheForce; // should we still precache all video even if we don't have enough RAM? + + unsigned int m_uSoundChipID; // so we can delete the soundchip once we're finished + + // holds a record of all precached files (and their associated indices) + map m_mPreCachedFiles; + +////////////////////////////////////////////////// + + // stuff inside ldp-vldp-audio.cpp +public: + void enable_audio1(); + void enable_audio2(); + void disable_audio1(); + void disable_audio2(); +private: + void set_audiocopy_callback(); + void oggize_path(string &, string); + bool audio_init(); + void audio_shutdown(); + void close_audio_stream(); + bool open_audio_stream(const string &strFilename); + bool seek_audio(Uint64 u64Samples); + void audio_play(Uint32); + void audio_pause(); +}; + +// functions that cannot be part of the class because we may need to use them as function pointers +int prepare_frame_callback_with_overlay(struct yuv_buf *buf); +int prepare_frame_callback_without_overlay(struct yuv_buf *buf); +void display_frame_callback(struct yuv_buf *buf); +void set_blend_fields(bool val); +void buf2overlay(SDL_Overlay *dst, struct yuv_buf *src); +void buf2overlay_YUY2(SDL_Overlay *dst, struct yuv_buf *src); +void update_parse_meter(); +void report_parse_progress_callback(double percent_complete); +void report_mpeg_dimensions_callback(int, int); +void free_yuv_overlay(); +void blank_overlay(); +void ldp_vldp_audio_callback(Uint8 *stream, int len, int unused); // declaration for callback in other function + +#endif diff --git a/ldp-out/ldp.cpp b/ldp-out/ldp.cpp new file mode 100644 index 000000000..924c2e882 --- /dev/null +++ b/ldp-out/ldp.cpp @@ -0,0 +1,1156 @@ + +/* + * ldp.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// LDP.CPP +// by Matt Ownby + +// The code in this file translates general LDP functions into LDP-specific functions +// Part of the Daphne emulator + +#ifdef DEBUG +#include +#include "../io/numstr.h" +//#include "../cpu/cpu-debug.h" +#endif + +#include +#include +#include +//#include "../io/serial.h" +#include "../io/my_stdio.h" +#include "ldp.h" +#include "../timer/timer.h" +#include "../io/conout.h" +#include "framemod.h" +#include "../game/game.h" +#include "../daphne.h" // for get_quitflag, set_quitflag +//#include "../game/boardinfo.h" +//#include "../cpu/cpu.h" +//#include "../cpu/generic_z80.h" + +// How many milliseconds the CPU emulation is lagging behind. +// So that OpenGL mode knows when to drop frames to get back up to speed (vsync-enabled only) +unsigned int g_uCPUMsBehind = 0; + +#ifdef WIN32 +#pragma warning (disable:4100) // disable the warning about unreferenced parameters +#endif + +// generic ldp constructor +ldp::ldp() : + need_serial(false), + serial_initialized(false), + player_initialized(false), + m_bIsVLDP(false), + blitting_allowed(true), + skipping_supported(false), + skip_instead_of_search(false), + max_skippable_frames(0), + m_last_try_frame(0), + m_last_seeked_frame(0), +// m_play_cycles(0), + m_play_time(0), + m_start_time(-1), // set to something invalid to force us to call pre_init + m_status(LDP_STOPPED), + search_latency(0), + m_stop_on_quit(false), + m_discvideo_width(640), + m_discvideo_height(480), + m_use_nonblocking_searching(true), + m_dont_get_search_result(false), + m_sram_continuous_update(false), + m_noldp_timer(0), + m_uCurrentFrame(0), + m_uCurrentOffsetFrame(0), + m_uElapsedMsSincePlay(0), + m_uBlockedMsSincePlay(0), + m_bWaitingForVblankToPlay(false), + m_iSkipOffsetSincePlay(0), + m_uMsFrameBoundary(0), + m_uElapsedMsSinceStart(0), + m_uVblankCount(0), + m_uVblankMiniCount(0), + m_uMsVblankBoundary(0), + m_uFramesToSkipPerFrame(0), + m_uFramesToStallPerFrame(0), + m_uStallFrames(0), + m_bPreInitCalled(false) +{ + m_bug_log.clear(); // probably redundant, but what the heck.. + + // NOTE : GET_TICKS must not be called in this constructor because on the gp2x, get ticks isn't available until video is initialized +} + +ldp::~ldp() +{ + pre_shutdown(); +} + +// Initializes and "pings" the LDP/VLDP and returns true if the player is online and detected +// or false if the LDP could not be initialized +bool ldp::pre_init() +{ + + bool result = true; // assume everything works until we find out otherwise + bool temp = true; // needed to make && work the way we want below + + // If we are controlling a real LDP, + // or if we are controlling a combo and DVD initialized properly, + // then initialize the serial port here + /* + if (need_serial) + { + printline("NOTE : You are attempting to use DAPHNE with a real laserdisc player!"); + printline("If you don't have DAPHNE plugged into a real laserdisc player,"); + printline("you should be using VLDP instead."); + serial_initialized = serial_init(get_serial_port(), get_baud_rate()); + temp = serial_initialized; + } + */ + player_initialized = init_player(); + result = temp && player_initialized; + m_start_time = GET_TICKS(); + m_uElapsedMsSincePlay = 0; + m_uBlockedMsSincePlay = 0; + m_uElapsedMsSinceStart = 0; + m_uMsVblankBoundary = 0; + m_bPreInitCalled = true; + m_bWaitingForVblankToPlay = false; + m_iSkipOffsetSincePlay = 0; + m_uMsFrameBoundary = 0; + m_uVblankCount = 0; + m_uVblankMiniCount = 0; + m_uFramesToSkipPerFrame = 0; + m_uFramesToStallPerFrame = 0; + m_uStallFrames = 0; + m_bVerbose = true; + + return(result); + +} + +// initializes the player after serial has been initialized +// this is so that the main init function can initialize the serial without having each LDP +// initialize its own serial +bool ldp::init_player() +{ + return(true); +} + +// may stop the player, shuts down the serial if it's open, then calls shutdown_player for player-specific stuff +void ldp::pre_shutdown() +{ + if (player_initialized) + { + // if stop on quit has been requested stop the player from playing + if (m_stop_on_quit) + { + pre_stop(); + } + + // if serial has been initialized, shut it down now + if (serial_initialized) + { +// serial_close(); + serial_initialized = false; + } + + shutdown_player(); + player_initialized = false; + } + // else we were never initialized +} + +// does any player specific stuff +void ldp::shutdown_player() +{ +} + +// see .h file for usage +bool ldp::pre_search(const char* pszFrame, bool block_until_search_finishes) +{ + char frame[FRAME_ARRAY_SIZE] = { 0 }; + Uint32 frame_number = 0; // frame to search to + bool result = false; + char s1[81] = { 0 }; + + // safety check, if they try to search without checking the search result ... + if (m_status == LDP_SEARCHING) + { + if (m_bVerbose) printline("LDP : tried to search without checking for search result first! that's bad!"); + if (m_bVerbose) printline(frame); + + // this is definitely a Daphne bug if this happens, so log it! + m_bug_log.push_back("LDP.CPP, pre_search() : tried to search without checking for search result first!"); + return false; + } + // end safety check + + // Get the frame that we are on now, before we do the seek + // This is needed in order to calculate artificial seek delay + // We must do this before we change 'm_status' due to the way get_current_frame is designed + m_last_seeked_frame = m_uCurrentFrame; + + // we copy here so that we can safely null-terminate + strncpy(frame, pszFrame, 6); + frame[6] = 0; // terminate the string ... + frame_number = (Uint32) atoi(frame); + + // If we're seeking to the frame we're already on, then don't seek + // This optimizes performance for many games and especially improves the coin insert delay + // for Dragon's Lair 2. + if ((m_status == LDP_PAUSED) && (frame_number == m_uCurrentFrame)) + { + if (m_bVerbose) printline("LDP NOTE: ignoring seek because we're already on that frame"); + m_status = LDP_PAUSED; // just to be safe + return true; + } + + m_status = LDP_SEARCHING; // searching can take a while + + // If we need to alter the frame # before searching + if (need_frame_conversion()) + { + Uint32 unadjusted_frame = frame_number; + frame_number = (Uint32) do_frame_conversion(frame_number); + framenum_to_frame(frame_number, frame); + sprintf(s1, "Search to %d (formerly %d) received", frame_number, unadjusted_frame); + } + else + { + sprintf(s1, "Search to %d received", frame_number); + } + + if (m_bVerbose) outstr(s1); + + // notify us if we're still using outdated blocking searching + if (block_until_search_finishes && m_bVerbose ) outstr(" [blocking] "); + + // if it's Dragon's Lair/Space Ace, print the board we are on + if ((g_game->get_game_type() == GAME_LAIR) || (g_game->get_game_type() == GAME_DLE1) + || (g_game->get_game_type() == GAME_DLE2) + || (g_game->get_game_type() == GAME_ACE)) + { + Uint8 *cpumem = NULL; //get_cpu_mem(0); // get the memory for the first (and only) + outstr(" - "); +// print_board_info(cpumem[0xA00E], cpumem[0xA00F], cpumem[Z80_GET_IY]); + } + else + { + if (m_bVerbose) newline(); + } + + // If the user requested a delay before seeking, make it now + if (search_latency > 0) + { +#ifdef DEBUG + // search latency needs to be reworked so that think() is getting called ... + assert(false); +#endif +// make_delay(get_search_latency()); + if (m_bVerbose) printline("WARNING : search latency needs to be redesigned, it is currently disabled"); + } + + m_last_try_frame = (Uint32) atoi(frame); // the last frame we tried to seek to becomes this current one + + // HERE IS WHERE THE SEARCH ACTUALLY TAKES PLACE + + Uint32 difference = frame_number - m_uCurrentFrame; // how many frames we'd have to skip + + // if the player supports skipping AND user has requested the we skip instead of searching when possible + // AND if we can skip forward instead of seeking ... + if (skipping_supported && skip_instead_of_search && ((difference <= max_skippable_frames) && (difference > 1))) + { + result = pre_skip_forward(difference); + } + + // otherwise do a regular search + else + { + result = nonblocking_search(frame); + m_dont_get_search_result = false; // it's now ok to get the search result + + // if search succeeded + if (result) + { + // if we are to block until the search finishes, then wait here (this is bad, don't do this!) + // This is only here for backward compatibility! + if (block_until_search_finishes) + { + unsigned int cur_time = refresh_ms_time(); + unsigned int uLastTime = cur_time; // used to compute m_uBlockedMsSincePlay + int ldp_stat = -1; + + // we know we may be waiting for a while, so we pause the cpu timer to avoid getting a flood after the seek completes +// cpu_pause(); + + // wait for player to change its status or for us to timeout + while (elapsed_ms_time(cur_time) < 7000) + { + ldp_stat = get_status(); // get_status does some stuff that needs to get done, so we don't just read m_status instead + + // if the search is finished + if (ldp_stat != LDP_SEARCHING) + { + break; + } + + // Since the cpu is paused, we should not use think_delay + // Also, blocking seeking may be used for skipping in noldp mode for cpu games like super don, + // so we cannot use think_delay here. + MAKE_DELAY(1); + + // VLDP relies on our timers for its timing, so we need to keep the time moving forward during + // this period where we're paused. (and we can't use think_delay or pre_think because it can + // cause vblank events which can cause irqs while the cpu is supposed to be paused) + unsigned int uCurTimeTmp = refresh_ms_time(); + m_uBlockedMsSincePlay += (uCurTimeTmp - uLastTime); // since we're blocked, the blockmssinceplay must increase + uLastTime = uCurTimeTmp; + think(); + } + +// cpu_unpause(); // done with the delay, so we can unpause + + // if we didn't succeed, then return an error + if (ldp_stat != LDP_PAUSED) + { + if (m_bVerbose) printline("LDP : blocking search didn't succeed"); + result = false; + } + } // end if we were doing a blocking styled search + } // if the initial search command was accepted + + // else if search failed immediately + else + { + if (m_bVerbose) printline("LDP : search failed immediately"); + m_status = LDP_ERROR; + } + + } // end regular search (instead of skipping) + + return(result); +} + +// don't call this function directly, call pre_search instead +bool ldp::nonblocking_search(char *new_frame) +{ + m_noldp_timer = refresh_ms_time(); + return(true); +} + +// don't call this function directly, call get_status() instead +int ldp::get_search_result() +{ + int result = SEARCH_BUSY; + + // stall for a couple of seconds to simulate search delay + if (elapsed_ms_time(m_noldp_timer) > 2000) + { + if (m_bVerbose) printline("Search success!"); + result = SEARCH_SUCCESS; + } + return result; +} + +// prepare to skip forward a certain # of frames and continue playing +// Call this function, do not call skip_forward directly +bool ldp::pre_skip_forward(Uint32 frames_to_skip) +{ + bool result = false; + + // only skip if the LDP is playing + if (m_status == LDP_PLAYING) + { + Uint32 target_frame = (Uint32) (m_uCurrentFrame + frames_to_skip); + unsigned int uOldCurrentFrame = m_uCurrentFrame; + + m_iSkipOffsetSincePlay += frames_to_skip; + + result = skip_forward(frames_to_skip, target_frame); + + char s[160]; + snprintf(s, sizeof(s), "Skipped forward %d frames (from %u to %u)", frames_to_skip, uOldCurrentFrame, target_frame); + if (m_bVerbose) printline(s); + } + else + { + if (m_bVerbose) printline("LDP ERROR: Skip forward command was called when the disc wasn't playing"); + } + + return(result); +} + +// prepare to skip forward a certain # of frames backward and continue playing forward +// do not call skip_backward directly +bool ldp::pre_skip_backward(Uint32 frames_to_skip) +{ + bool result = false; + + // only skip if the LDP is playing + if (m_status == LDP_PLAYING) + { + Uint32 target_frame = (Uint32) (m_uCurrentFrame - frames_to_skip); + unsigned int uOldCurrentFrame = m_uCurrentFrame; + + m_iSkipOffsetSincePlay -= frames_to_skip; + + result = skip_backward(frames_to_skip, target_frame); + + char s[81]; + snprintf(s, sizeof(s), "Skipped backward %d frames (from %u to %u)", frames_to_skip, uOldCurrentFrame, target_frame); + if (m_bVerbose) printline(s); + } + else + { + if (m_bVerbose) printline("LDP ERROR: Skip backward command was called when the disc wasn't playing"); + } + + return(result); +} + +// steps forward 1 frame +void ldp::pre_step_forward() +{ + // NOTE : right now we don't have LDP-specific implementations of this function since it is rarely used + char frame[6]; + Uint32 new_frame = m_uCurrentFrame; + + // bounds check (if we haven't overflowed) + if (new_frame < ((Uint32) -1)) + { + framenum_to_frame(m_uCurrentFrame + 1, frame); + if (m_bVerbose) printline("LDP : Stepping forward one frame"); + g_ldp->pre_search(frame, true); + } + else + { + if (m_bVerbose) printline("LDP: pre_step_forward failed bounds check"); + } +} + +// steps backward 1 frame +void ldp::pre_step_backward() +{ + // NOTE : right now we don't have LDP-specific implementations of this function since it is rarely used + char frame[6]; + Uint32 new_frame = m_uCurrentFrame; + + // don't step backward before the first frame on the disc + if (new_frame > 0) + { + new_frame--; + } + + framenum_to_frame(new_frame, frame); + if (m_bVerbose) printline("LDP : Stepping backward one frame"); + g_ldp->pre_search(frame, true); +} + +// skips forward a certain number of frames and continues playing +// Do not call this function directly! Call pre_skip_forward instead +// NOTE : this function handles skipping for real laserdisc players that don't support it +bool ldp::skip_forward(Uint32 frames_to_skip, Uint32 target_frame) +{ + bool result = false; + + char frame[6] = {0}; + sprintf(frame, "%05d", target_frame); + + result = pre_search(frame, true); + pre_play(); + + return(result); +} + +// DO NOT CALL THIS FUNCTION DIRECTLY +// call pre_skip_backward instead +// NOTE : this function handles skipping for real laserdisc players that don't support it +bool ldp::skip_backward(Uint32 frames_to_skip, Uint32 target_frame) +{ + bool result = false; + + char frame[6] = {0}; + sprintf(frame, "%05d", target_frame); + + result = pre_search(frame, true); + pre_play(); + + return(result); +} + +// prepares to play the disc +void ldp::pre_play() +{ +// Uint32 cpu_hz; // used to calculate elapsed cycles + + // safety check, if they try to play without checking the search result ... + // THIS SAFETY CHECK CAN BE REMOVED ONCE ALL LDP DRIVERS HAVE BEEN CONVERTED OVER TO NON-BLOCKING SEEKING + if (m_status == LDP_SEARCHING) + { + if (m_bVerbose) printline("LDP : tried to play without checking to see if we were still seeking! that's bad!"); + + // if this ever happens, it is a bug in Daphne, so log it + m_bug_log.push_back("LDP.CPP, pre_play() : tried to play without checking to see if we're still seeking!"); + + return; + } + + // we only want to refresh the frame calculation stuff if the disc is + // not already playing + if (m_status != LDP_PLAYING) + { + m_uElapsedMsSincePlay = 0; // by definition, this must be reset since we are playing + m_uBlockedMsSincePlay = 0; // " " " + m_iSkipOffsetSincePlay = 0; // by definition, this must be reset since we are playing + m_uCurrentOffsetFrame = 0; // " " " + m_uMsFrameBoundary = 1000000 / g_game->get_disc_fpks(); // how many ms must elapse before the first frame ends, 2nd frame begins + + // VLDP needs its timer reset with the rest of these timers before its play command is called. + // Otherwise, it will think it's way behind and will try to catch up a bunch of frames. + think(); + + // if the disc may need to take a long time to spin up, then pause the cpu timers while the disc spins up + if (m_status == LDP_STOPPED) + { +// cpu_pause(); + m_play_time = play(); +// cpu_unpause(); + } + else + { + m_play_time = play(); + } + + m_bWaitingForVblankToPlay = true; // don't start counting frames until the next vsync + m_status = LDP_PLAYING; + } + else + { + if (m_bVerbose) printline("LDP : disc is already playing, play command ignored"); + } + + if (m_bVerbose) printline("Play"); // moved to the end of the function so as to not cause lag before play command could be issued +} + +// starts playing the laserdisc +// returns the timer value that indicates when the playback actually started (used to calculate current frame) +unsigned int ldp::play() +{ + return refresh_ms_time(); +} + +// prepares to pause +void ldp::pre_pause() +{ + // only send pause command if disc is playing + // some games (Super Don) repeatedly flood with a pause command and this doesn't work well with the Hitachi + if (m_status == LDP_PLAYING) + { +#ifdef DEBUG + string s = "m_uMsFrameBoundary is " + numstr::ToStr(m_uMsFrameBoundary) + ", elapsed ms is " + + numstr::ToStr(m_uElapsedMsSincePlay); + if (m_bVerbose) printline(s.c_str()); +#endif + m_last_seeked_frame = m_uCurrentFrame; + m_iSkipOffsetSincePlay = m_uCurrentOffsetFrame = m_uMsFrameBoundary = 0; + pause(); + m_status = LDP_PAUSED; + if (m_bVerbose) printline("Pause"); + } + else + { + if (m_bVerbose) printline("LDP : Received pause while disc was not playing, ignoring"); + } +} + +// pauses the disc +void ldp::pause() +{ +} + +// prepares to stop the disc +// "stop" is defined as going to frame 0 and stopping the motor so that +// the player has to spin up again to begin playing +void ldp::pre_stop() +{ + m_last_seeked_frame = m_uCurrentFrame = 0; + stop(); + m_status = LDP_STOPPED; + if (m_bVerbose) printline("Stop"); +} + +// stops the disc +void ldp::stop() +{ +} + +bool ldp::pre_change_speed(unsigned int uNumerator, unsigned int uDenominator) +{ + string strMsg; + + // if this is >= 1X + if (uDenominator == 1) + { + m_uFramesToStallPerFrame = 0; // don't want to stall at all + + // if this isn't 0 ... + if (uNumerator > 0) + { + m_uFramesToSkipPerFrame = uNumerator - 1; // show 1, skip the rest + } + // else it's 0, which is illegal (use pause() instead unless the game driver specifically wants to do this, in which case more coding is needed) + else + { + m_uFramesToSkipPerFrame = 0; + if (m_bVerbose) printline("ERROR : uNumerator of 0 sent to pre_change_speed, this isn't supported, going to 1X"); + } + } + // else if this is < 1X + else if (uNumerator == 1) + { + m_uFramesToSkipPerFrame = 0; // don't want to skip any ... + + // protect against divide by zero + if (uDenominator > 0) + { + m_uFramesToStallPerFrame = uDenominator - 1; // show 1, stall for the rest + } + // divide by zero situation + else + { + m_uFramesToStallPerFrame = 0; + if (m_bVerbose) printline("ERROR : uDenominator of 0 sent to pre_change_speed, this is undefined, going to 1X"); + } + } + // else it's a non-standard speed, so do some kind of error + else + { + strMsg = "ERROR : unsupported speed specified (" + numstr::ToStr(uNumerator) + + "/" + numstr::ToStr(uDenominator) + "), setting to 1X"; + uNumerator = uDenominator = 1; + } + + bool bResult = change_speed(uNumerator, uDenominator); + + if (bResult) strMsg = "Successfully changed "; + else strMsg = "Unable to change "; + strMsg += "speed to " + numstr::ToStr(uNumerator) + "/" + numstr::ToStr(uDenominator) + + "X"; + if (m_bVerbose) printline(strMsg.c_str()); + return bResult; +} + +bool ldp::change_speed(unsigned int uNumerator, unsigned int uDenominator) +{ + return true; +} + +void ldp::think_delay(unsigned int uMsDelay) +{ + bool bEmulatedCpu = 0; //(get_cpu_hz(0) != 0); // whether we've got an emulated cpu + + // safety check: make sure that we're not using an emulated CPU + if (bEmulatedCpu) + { + if (m_bVerbose) printline("think_delay() should not be used with an emulated CPU. Don't use blocking seeking maybe?"); + set_quitflag(); + } + // safety check: make sure pre_init has already been called so that m_start_time has been initialized + else if (!m_bPreInitCalled) + { + if (m_bVerbose) printline("think_delay() should not be called until pre_init() has been called."); + set_quitflag(); + } + + // call pre_think the same # of times that uMsDelay tells us to, + // to ensure that we aren't caught sleeping during an important event + for (unsigned int uMs = 0; uMs < uMsDelay; ++uMs) + { + pre_think(); + + unsigned int uElapsedMs = elapsed_ms_time(m_start_time); + + // if we're ahead of where we need to be, then it's ok to stall ... + if (uElapsedMs < m_uElapsedMsSinceStart) + { + /* + string msg = "uElapsedMs is " + numstr::ToStr(uElapsedMs) + " and m_uElapsedMssinceStart is " + + numstr::ToStr(m_uElapsedMsSinceStart); + printline(msg.c_str()); // REMOVE ME + */ + + MAKE_DELAY(1); + } + // otherwise we're caught up or behind, so just loop so we can make sure we're caught up + } +} + +// TODO: in the future, we may want to support vblank of 50 hz for the PAL laserdisc games +const unsigned int VBLANKS_PER_KILOSECOND = (unsigned int) ((29.97 * 2) * 1000); + +void ldp::pre_think() +{ + // IMPORTANT : By definition, this function must be called every millisecond to update the timer (it is called by our cpu emulation every 1 ms) + // If it cannot be called every 1 ms (if we are not emulating a cpu for example), then ldp::think_delay() can be + // (and should be) used instead of calling this function directly. + // IMPORTANT : this must be updated no matter what because vldp relies on this timer when we're paused + + // START VBLANK COUNT + + // at the end of this function, if vblank gets asserted, we need to call an event handler in the game class, but we + // need to do that after the frame number has been recalculated (if need be), hence the purpose of this variable. + bool bVblankAsserted = false; + + ++m_uElapsedMsSinceStart; + + // if it's time to increase the vblank count + if (m_uElapsedMsSinceStart >= m_uMsVblankBoundary) + { + ++m_uVblankCount; + + // compute the next boundary + m_uMsVblankBoundary = (unsigned int) ((((Uint64) (m_uVblankCount+1)) * 1000000) / VBLANKS_PER_KILOSECOND); + + // only increment the mini count if we aren't waiting for vblank to start counting frames + if (!m_bWaitingForVblankToPlay) + { + ++m_uVblankMiniCount; + } + // else if we have been waiting for vblank to play, then make sure we reset the vblankminicount + else + { + // we want to start at the beginning of a new frame boundary + m_uVblankMiniCount = 0; + + // we just got a vblank, so we're not waiting ... + m_bWaitingForVblankToPlay = false; + } + + bVblankAsserted = true; + } + // END VBLANK COUNT + + // if we're not waiting to sync up with vblank, then increase timer + // (this must be done even if we're paused so VLDP will update our video overlay) + if (!m_bWaitingForVblankToPlay) + { + ++m_uElapsedMsSincePlay; + } + + // If the disc is supposed to be playing then compute which frame # we're on + // IMPORTANT: + // ldp-vldp.cpp's nonblocking_seek() RELIES on this function NOT calling get_status()!!! + // Be very careful about changing this 'm_status' to a get_status() + if (m_status == LDP_PLAYING) + { + unsigned int uDiscFPKS = g_game->get_disc_fpks(); + + // if our frame counter is in sync with vblank, then just increment frame every 2 vblanks ... + if ((uDiscFPKS << 1) == VBLANKS_PER_KILOSECOND) + { + // if we've had 2 vblanks, then 1 frame has elapsed + if (m_uVblankMiniCount > 1) + { + increment_current_frame(); + m_uVblankMiniCount = 0; + } + // else we've not had enough vblanks, so don't do anything ... + } + + // else if we're not in sync with the vblank (for example if we're dragon's lair with a 24 FPS disc), + // then use the elapsed ms since play to determine if the frame has changed + else if (m_uElapsedMsSincePlay >= m_uMsFrameBoundary) + { + increment_current_frame(); + + // compute the next boundary + m_uMsFrameBoundary = (unsigned int) ((((Uint64) (m_uCurrentOffsetFrame+1)) * 1000000) / uDiscFPKS); + } + + // else the current frame has not changed + +#ifdef DEBUG +#ifndef GP2X // GP2X is slow enough that we don't want to do this safety check by default + // SAFETY CHECK + // This ensures that the number that is calculated is not far off what it should be. + // (this test is only meaningful if we are emulating a cpu, because otherwise we may deliberately + // be calling this function slower than every 1 ms, such as ffr() or vldp's internal tests ) + /* if (get_cpu_hz(0)) + { + unsigned int uElapsedMS = elapsed_ms_time(m_play_time); // compute milliseconds + unsigned int time_result = m_last_seeked_frame + m_iSkipOffsetSincePlay + + (unsigned int) ((((Uint64) uElapsedMS) * g_game->get_disc_fpks()) / 1000000); + Uint32 diff = 0; + + // this isn't necessarily the same as m_uCurrentFrame due to potential skips that can occur + // (this is updated immediately, m_uCurrentFrame is updated on a time boundary) + unsigned int uCurrentFrame = m_last_seeked_frame + m_iSkipOffsetSincePlay + m_uCurrentOffsetFrame; + + if (uCurrentFrame > time_result) diff = uCurrentFrame - time_result; + else diff = time_result - uCurrentFrame; + + // if the difference is noticeable, then alert the developer + if (diff > 5) + { + static unsigned int last_warning = 0; + + if (elapsed_ms_time(last_warning) > 1000) + { + string s = "WARNING : cycle frame is "; + s += numstr::ToStr(uCurrentFrame) + " but time frame is "; + s += numstr::ToStr(time_result) + " which has a diff of "; + s += numstr::ToStr(diff); + if (m_bVerbose) printline(s.c_str()); + last_warning = refresh_ms_time(); + } + } + }*/ +#endif // not GP2X +#endif // DEBUG + + } + // otherwise the disc is idle, so we need not change the current frame + + think(); // call implementation-specific function + + // If vblank was asserted, let game know about it... + // NOTE : this should probably come at the end of this function + if (bVblankAsserted) + { + // let game know about vblank ... + g_game->OnVblank(); + } +} + +// DO NOT CALL THIS FUCTION DIRECTLY! THIS FUCTION IS JUST A HELPER FOR PRE_THINK! +void ldp::increment_current_frame() +{ + ++m_uCurrentOffsetFrame; + + // FOR PLAYING AT SLOWER THAN 1X (such as 1/2X) + // if we have no frames to stall, then check to see if we need some frames to stall + if (m_uStallFrames == 0) + { + m_uStallFrames = m_uFramesToStallPerFrame; + } + // otherwise, we do have frames to stall, so adjust the frame number accordingly + else + { + --m_iSkipOffsetSincePlay; + --m_uStallFrames; + } + // END PLAYING AT SLOWER THAN 1X + + // At 1X speed, m_uFramesToSkipPerFrame will be 0. + // If we're playing faster, we need to adjust the current frame accordingly + // I decided to use the m_iSkipOffsetSincePlay because I'm afraid to mess + // up the timing by modifying m_uCurrentOffsetFrame + m_iSkipOffsetSincePlay += m_uFramesToSkipPerFrame; + + // NOTE : This must be re-calculated every time here (instead of just incremented) + // Because if we skipped, we want to finish the current frame we are on and then go immediately + // to the new frame. We do NOT want to change frames immediately when skipping. + m_uCurrentFrame = m_last_seeked_frame + m_iSkipOffsetSincePlay + m_uCurrentOffsetFrame; + +#if 0 + { + static unsigned int uOldFrame = 0; + static unsigned int uOldTime = 0; + + if (m_uCurrentFrame != uOldFrame) + { + unsigned int uTimer = refresh_ms_time(); + unsigned int uDiff = uTimer - uOldTime; + string strMsg = "[" + numstr::ToStr(m_uCurrentFrame) + "] Time since last frame change: " + numstr::ToStr(uDiff) + " ms"; + printline(strMsg.c_str()); + uOldTime = uTimer; + uOldFrame = m_uCurrentFrame; + } + } +#endif +} + +void ldp::think() +{ +} + +// (see .h for description) +unsigned int ldp::get_current_frame() +{ + return m_uCurrentFrame; +} + +unsigned int ldp::get_adjusted_current_frame() +{ +#ifdef DEBUG + // this function assumes that the disc's FPS is in line with vblank + assert((g_game->get_disc_fpks() << 1) == VBLANKS_PER_KILOSECOND); +#endif // DEBUG + + // because get_current_frame() is a virtual function + unsigned int uResult = get_current_frame(); + + // if the disc is playing and we've already displayed the 2nd field of the frame, then advance the current frame + if ((m_status == LDP_PLAYING) && (m_uVblankMiniCount != 0)) + { + ++uResult; + } + + return uResult; +} + +unsigned int ldp::get_vblank_mini_count() +{ + return m_uVblankMiniCount; +} + +bool ldp::is_vldp() +{ + return m_bIsVLDP; +} + +// returns value of blitting_allowed. VLDP does not allow blitting! +bool ldp::is_blitting_allowed() +{ + return (blitting_allowed); +} + +void ldp::set_blitting_allowed(bool bVal) +{ + blitting_allowed = bVal; +} + +// returns the current LDP status +// This should ONLY be called if we are waiting for a search to complete, or +// if we don't have read access to 'm_status' +int ldp::get_status() +{ + // if we are in the middle of a search, find out if the search has completed + if (m_status == LDP_SEARCHING) + { +#ifdef DEBUG + // verify that get_search_result() is not being called when it ought not be + assert(!m_dont_get_search_result); +#endif + int stat = get_search_result(); + + // if the search was successful + if (stat == SEARCH_SUCCESS) + { + m_dont_get_search_result = true; + m_last_seeked_frame = m_uCurrentFrame = m_last_try_frame; + m_status = LDP_PAUSED; + + // Update sram after every search if user desires it + // (so that the DAPHNE can be improperly terminated, if it's inside a cab and powered off, for example) + // This is the best place to do this because it's right after a seek which can take a second or two anyway. + if (m_sram_continuous_update) + { + g_game->save_sram(); + } + + } + + // if the search failed + else if (stat == SEARCH_FAIL) + { + m_status = LDP_ERROR; + } + // else the search is busy and still going, so we needn't act ... + } + + return m_status; +} + +// converts an integer frame number into ASCII (with leading zeroes) +// NOTE : 'f' should be an array of 6 characters (5 numbers plus null terminator) +void ldp::framenum_to_frame(Uint32 num, char *f) +{ + sprintf(f, "%06d", num); +} + +Uint32 ldp::get_search_latency() +{ + return(search_latency); +} + +void ldp::set_search_latency(Uint32 value) +{ + search_latency = value; +} + +void ldp::set_stop_on_quit(bool value) +{ + m_stop_on_quit = value; +} + +// causes LDP to blank video while searching +void ldp::set_search_blanking(bool enabled) +{ + if (m_bVerbose) printline("NOTE : Search blanking cannot be modified with this laserdisc player!"); +} + +// causes LDP to blank video while skipping +void ldp::set_skip_blanking(bool enabled) +{ + if (m_bVerbose) printline("NOTE : Skip blanking cannot be modified with this laserdisc player!"); +} + +void ldp::set_seek_frames_per_ms(double value) +{ + if (m_bVerbose) printline("NOTE : Seek delay is not supported with this laserdisc player!"); +} + +void ldp::set_min_seek_delay(unsigned int value) +{ + if (m_bVerbose) printline("NOTE : Seek delay is not supported with this laserdisc player!"); +} + +// causes sram to be saved after every seek +void ldp::set_sram_continuous_update(bool value) +{ + m_sram_continuous_update = value; +} + +void ldp::enable_audio1() +{ + if (m_bVerbose) printline("Audio1 enable received (ignored)"); +} + +void ldp::enable_audio2() +{ + if (m_bVerbose) printline("Audio2 enable received (ignored)"); +} + +void ldp::disable_audio1() +{ + if (m_bVerbose) printline("Audio1 disable received (ignored)"); +} + +void ldp::disable_audio2() +{ + if (m_bVerbose) printline("Audio2 disable received (ignored)"); +} + +// asks LDP to take a screenshot if that's possible +// it's only possible with VLDP as of this time +void ldp::request_screenshot() +{ + if (m_bVerbose) printline("NOTE: current laserdisc player does not support taking screenshots, sorry"); +} + +// returns the width of the laserdisc video (only meaningful with mpeg) +Uint32 ldp::get_discvideo_width() +{ + return m_discvideo_width; +} + +// returns the height of the laserdisc video (only meaningful with mpeg) +Uint32 ldp::get_discvideo_height() +{ + return m_discvideo_height; +} + +// ordinarily does nothing unless we're VLDP +bool ldp::lock_overlay(Uint32 timeout) +{ + return true; +} + +// does nothing unless we're VLDP +bool ldp::unlock_overlay(Uint32 timeout) +{ + return true; +} + +// sets the value of this boolean +void ldp::set_use_nonblocking_searching(bool val) +{ + m_use_nonblocking_searching = val; +} + +// returns the value of this boolean +bool ldp::get_use_nonblocking_searching() +{ + return m_use_nonblocking_searching; +} + +unsigned int ldp::get_elapsed_ms_since_play() +{ + return m_uElapsedMsSincePlay; +} + +// this is called by cmdline.cpp if it gets any cmdline parameters that it doesn't recognize +// returns true if this argument was recognized and processed, +// or false is this argument wasn't recognized (and therefore the command line is bad on a whole) +bool ldp::handle_cmdline_arg(const char *arg) +{ + return false; +} + +void ldp::get_bug_log(list &log) +{ + log = m_bug_log; + m_bug_log.clear(); +} + +void ldp::print_frame_info() +{ + string s = "Current frame is " + numstr::ToStr(m_uCurrentFrame); + if (m_bVerbose) printline(s.c_str()); + + unsigned int u = m_uMsVblankBoundary - m_uElapsedMsSinceStart; + s = "Virtual milliseconds until next vblank: " + numstr::ToStr(u); + if (m_bVerbose) printline(s.c_str()); + + s = "Vblanks since frame changed: " + numstr::ToStr(m_uVblankMiniCount); + if (m_bVerbose) printline(s.c_str()); +} + +void ldp::setVerbose(bool thisBol) +{ + m_bVerbose = thisBol; +} + +////////////////// + +bool fast_noldp::nonblocking_search(char *new_frame) +{ + return(true); +} + +int fast_noldp::get_search_result() +{ + return SEARCH_SUCCESS; +} + +bool fast_noldp::skip_forward(Uint32 frames_to_skip, Uint32 target_frame) +{ + return true; +} + +bool fast_noldp::skip_backward(Uint32 frames_to_skip, Uint32 target_frame) +{ + return true; +} diff --git a/ldp-out/ldp.h b/ldp-out/ldp.h new file mode 100644 index 000000000..053cde533 --- /dev/null +++ b/ldp-out/ldp.h @@ -0,0 +1,329 @@ +/* + * ldp.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LDP_PRE_H +#define LDP_PRE_H + +// different states that the laserdisc player could be in +enum +{ + LDP_ERROR, LDP_SEARCHING, LDP_STOPPED, LDP_PLAYING, LDP_PAUSED +}; + +// different non-blocking search results +enum +{ + SEARCH_FAIL, // search failed + SEARCH_SUCCESS, // search succeeded + SEARCH_BUSY // search is still taking place, no change yet, my frenid +}; + +#include // needed for datatypes + +// for bug logging +#include +#include + +using namespace std; + +#ifdef WIN32 +#pragma warning (disable:4786) // disable warning about truncating to 255 in debug info +#endif + +#define FRAME_SIZE 7 // rdg2010 + +// the size to make your frame array (the frame + the NULL terminator) +#define FRAME_ARRAY_SIZE FRAME_SIZE + 1 + +class ldp +{ +public: + ldp(); + virtual ~ldp(); + + // Call this function to initialize the ldp (the constructor does _not_ call it). + // It's safe to call this function mulitple times. + bool pre_init(); + + // player-specific init stuff + // NOTE : this function should not be called directly, call pre_init instead + virtual bool init_player(); + + // Call this function to shutdown the ldp (the destructor also calls it). + // It's safe to call this function multiple times. + void pre_shutdown(); + + // player-specific shutdown stuff + // NOTE : this function should not be called directly, call pre_shutdown instead + virtual void shutdown_player(); + + void clear(); // clears any received frames + + // searches to the 5-digit ASCII frame specified by 'pszFrame' + // if 'block_until_search_finished' is true, this function will return after the search has completed and will return + // true if the search was successful or false on error. + // if 'block_until_search_finished' is false, this function will return after the search has _begun_ and will return true + // if the player is currently executing the search or false if there was an error + // Call this instead of calling the search function directly! + // WARNING : if 'block_until_search_finished' is false, then the calling function + // MUST also call get_status() to determine when a seek has finished. + // If you aren't prepared to do this, make 'block_until_search_finished' true. + bool pre_search(const char *, bool block_until_search_finished); + + // does the actual search. This func returns once the search has begun and you need to call get_search_result + // until the search isn't busy anymore. + // This function returns true if the LDP acknowledged the search + virtual bool nonblocking_search(char *); + + // do not call this function directly! (get get_status instead) + // This is the LDP-specific function that checks to see if a search (issued previously) finished + // it returns one of the SEARCH_* enumerations ... + virtual int get_search_result(); + + bool pre_skip_forward(Uint32); + bool pre_skip_backward(Uint32); + + // steps 1 frame forward + void pre_step_forward(); + + // steps 1 frame backward + void pre_step_backward(); + + virtual bool skip_forward(Uint32 frames_to_skip, Uint32 target_frame); + // NOTE : frames_to_skip and target_frame are both included for your convenience + // use frames_to_skip only if you cannot use target_frame (which is more accurate) + + virtual bool skip_backward(Uint32 frames_to_skip, Uint32 target_frame); + // NOTE : frames_to_skip and target_frame are both included for your convenience + // use frames_to_skip only if you cannot use target_frame (which is more accurate) + + void pre_play(); + void pre_pause(); + void pre_stop(); + + // Function all 'ldp-in' drivers should call to change the playback speed + // Input is a fraction (numerator/denominator) to avoid using a floating point value, + // which doesn't work well on the GP2X. + // Common speeds are 1X (1/1), 2X (2/1), 3X (3/1), 4X (4/1), 8X (8/1), + // 1/2X (1/2), 1/3X (1/3), 1/4X (1/4), 1/8X (1/8) + // Any weird speeds such as 7/2 have undefined behavior for now. + // Returns true if the speed has changed or false if the speed cannot be changed + bool pre_change_speed(unsigned int uNumerator, unsigned int uDenominator); + + // LASERDISC-PLAYER-SPECIFIC IMPLEMENTATIONS OF VARIOUS FUNCTIONALITY + virtual unsigned int play(); + virtual void pause(); + virtual void stop(); + + // Implementation-specific version of pre_change_speed + // Returns true if the speed has changed or false if the speed cannot be changed + virtual bool change_speed(unsigned int uNumerator, unsigned int uDenominator); + + // function that can replace make_delay when no cpu is present and thinking is required + void think_delay(unsigned int); + + // When emulating a cpu, this function MUST be called EVERY 1 ms (according to cpu's reckoning) to keep us in sync w/ the cpu. + // This allows the cpu to do all timing calculations, which saves us from redundantly doing them again. + // (when not emulating a cpu, this function can be called less often, every frame for example, and we will do the calculations ourselves) + // This function updates the current frame so you cannot rely on get_current_frame to know when to call this function!!! + void pre_think(); + + // pre_think() calls think() for ldp-specific stuff + virtual void think(); + + // returns the current frame number that the disc is on + // this is a generic function which computes the current frame number using the elapsed time + // and the framerate of the disc. Obviously querying the laserdisc player would be preferable + // if possible (some laserdisc players don't like to be queried too often) + // SEEKING NOTES: + // if get_current_frames() is called during a NON-BLOCKING seek, + // it returns the frame the LDP was at right + // when seek was begun. It DOES NOT check to see if a seek is finished, which + // means that any driver that uses non-blocking seeking MUST also call get_status() + // to check for the completion of that seek. + // A laserdisc driver that supports non-blocking seeking (LD-V1000) SHOULD call + // get_status() to check to see if a search is complete. If an LDP isn't designed + // to return its status (ie the PR-8210) then either blocking seeking must be used + // or each game driver which uses this player must call get_status(). + virtual unsigned int get_current_frame(); + + // returns m_uCurrentFrame or m_uCurrentFrame+1 if the disc is playing and we've already displayed the 2nd field of the frame + // (this is in an effort to fix overrun problems on super don) + unsigned int get_adjusted_current_frame(); + + // returns 0 if this is the first vblank of the frame (assuming vblanks and frames line up), + // or 1 if it's the second vblank of the frame + unsigned int get_vblank_mini_count(); + + // causes sram to be saved after every seek + virtual void set_sram_continuous_update(bool value); + + virtual void enable_audio1(); + virtual void enable_audio2(); + virtual void disable_audio1(); + virtual void disable_audio2(); + virtual void request_screenshot(); + virtual void set_search_blanking(bool enabled); + virtual void set_skip_blanking(bool enabled); + virtual void set_seek_frames_per_ms(double value); + virtual void set_min_seek_delay(unsigned int value); + + // END LDP-SPECIFIC SECTION + + bool is_vldp(); // returns true if our ldp type is VLDP + bool is_blitting_allowed(); // returns value of blitting_allowed + void set_blitting_allowed(bool bVal); + int get_status(); // returns status of laserdisc player + void framenum_to_frame(Uint32, char *); // converts int to 5-digit string + Uint32 get_search_latency(); + void set_search_latency(unsigned int); + void set_stop_on_quit(bool); // enables the stop_on_quit bool flag + + Uint32 get_discvideo_height(); // gets the height of the laserdisc video (only meaningful with mpeg) + Uint32 get_discvideo_width(); // gets the width of the laserdisc video (only meaningful with mpeg) + virtual bool lock_overlay(Uint32); // prevents yuv callback from being called (only meaningful with mpeg) + virtual bool unlock_overlay(Uint32); + + // sets the value of this boolean + void set_use_nonblocking_searching(bool); + + // returns the value of this boolean + bool get_use_nonblocking_searching(); + + unsigned int get_elapsed_ms_since_play(); + + // handles LDP-specific command-line arguments + virtual bool handle_cmdline_arg(const char *arg); + + // Copies m_bug_log into 'log' and clears m_bug_log. + // Used by releasetest. + void get_bug_log(list &log); + + // debug function used by the cpu debugger + void print_frame_info(); + + void setVerbose(bool); // rdg2010 + +protected: + // helper function, shouldn't be called directly + void increment_current_frame(); + + bool need_serial; // whether this LDP driver needs the serial port initialized + bool serial_initialized; // whether serial has been initialized + bool player_initialized; // whether the LDP has been properly initialized + bool m_bIsVLDP; // this is true if our LDP type is VLDP + bool blitting_allowed; // whether it's ok to blit directly to the screen (SMPEG forbids this) + bool skipping_supported; // whether the laserdisc player supports skipping + bool skip_instead_of_search; // whether we should skip instead of search if searching forward a short distance + Uint32 max_skippable_frames; // maximum # of frames that player can skip (if skipping is supported) + Uint32 m_last_try_frame; // the last frame we _tried_ to seek to + Uint32 m_last_seeked_frame; // the last frame we successfully seeked to (used with m_play_time to calculate current frame) +// UPDATE : we aren't using cycles anymore (see pre_think()) +// Uint64 m_play_cycles; // # of elapsed cpu cycles from when we last issued a play command + Uint32 m_play_time; // current time when we last issued a play command + unsigned int m_start_time; // time when ldp() class was instantiated (only used when not using a cpu) + int m_status; // the current status of the laserdisc player + Uint32 search_latency; // how many ms to stall before searching (to simulate slow laserdisc players) + bool m_stop_on_quit; // should the LDP stop when it quits? + Uint32 m_discvideo_width; // width of laserdisc video (only meaningful with mpeg) + Uint32 m_discvideo_height; // height of laserdisc video (only meaningful with mpeg) + bool m_use_nonblocking_searching; // true if ldp-in drivers should use pre_search in non-blocking mode (as of now, blocking mode is more stable but non-blocking mode is more accurate) + bool m_dont_get_search_result; // if we should not be calling get_search_result() + bool m_sram_continuous_update; // if sram is to be updated on a regular basis + + // timer to be used to simulate search delay when in 'noldp' mode (for debugging) + Uint32 m_noldp_timer; + + // used by 'releasetest' to do automatic self-testing + list m_bug_log; + + unsigned int m_uCurrentFrame; // the current frame, as calculated by pre_think(), returned by get_current_frame() + + // current frame - m_last_seeked_frame (for VLDP's usage) + // For example, the first frame displayed after playing is 0. + unsigned int m_uCurrentOffsetFrame; + + // How many milliseconds have elapsed since we started playing the disc. + // This value is changed by pre_think(), which must get called every 1 ms by the cpu loop + // This allows us to keep in sync w/ the cpu w/o doing extra expensive calculations. + unsigned int m_uElapsedMsSincePlay; + + // how many milliseconds have elapsed while we've been stuck doing blocking seeking + // (blocking seeking is discouraged because it isn't proper emulation, but some real laserdisc players + // need to use it for skipping, and a few functions like step-forward use it, + // and it's probably not worth it to change that behavior as those functions are very rarely used) + unsigned int m_uBlockedMsSincePlay; + + // if this is true, we won't increment m_uElapsedMsSincePlay until we get a vblank + bool m_bWaitingForVblankToPlay; + + // the total offset of all frames we've skipped since play + // (for example if I skipped +5 and then -10, this number would be -5) + int m_iSkipOffsetSincePlay; + + // how many ms we have to surpass before increasing m_uCurrentOffsetFrame and m_uCurrentFrame + unsigned int m_uMsFrameBoundary; + + // How many milliseconds have elapsed since Daphne started + // This value is changed by pre_think() which is called every 1 ms by the cpu loop + // This value is used to calculate how many emulated vblanks have occurred. + unsigned int m_uElapsedMsSinceStart; + + // how many vblanks have occurred since Daphne started, as calculated by pre_think() + unsigned int m_uVblankCount; + + // how many vblanks have occurred since last frame changed + // (used if laserdisc FPS is half of vblank rate which is usually true) + unsigned int m_uVblankMiniCount; + + // how many ms we have to surpass before increasing m_uVblankCount + unsigned int m_uMsVblankBoundary; + + // How many frames to skip after displaying 1 frame (for playing at faster than 1X) + unsigned int m_uFramesToSkipPerFrame; + + // How many frames to stall for after displaying 1 frame (for playing at slower than 1X) + unsigned int m_uFramesToStallPerFrame; + + // State variable to keep track of whether we're stalling (according to m_uFramesToStallPerFrame) + unsigned int m_uStallFrames; + +private: + // set to true if pre_init has been called (used to error checking) + bool m_bPreInitCalled; + bool m_bVerbose; // Control message displays on daphne_log.txt -- rdg2010 + +}; + +// same as regular ldp class but has no seek or skip delay (testing skipping games with skip delay is super annoying) +class fast_noldp : public ldp +{ + // see ldp.h for comments on how to use these functions + bool nonblocking_search(char *); + int get_search_result(); + bool skip_forward(Uint32 frames_to_skip, Uint32 target_frame); + bool skip_backward(Uint32 frames_to_skip, Uint32 target_frame); +}; + +extern ldp *g_ldp; // our global ldp class. Defined here so that every .cpp file doesn't have to define it. + +#endif diff --git a/macosx/Daphne Icon.icns b/macosx/Daphne Icon.icns new file mode 100644 index 000000000..e77e7131e Binary files /dev/null and b/macosx/Daphne Icon.icns differ diff --git a/macosx/Daphne.xcodeproj/project.pbxproj b/macosx/Daphne.xcodeproj/project.pbxproj new file mode 100644 index 000000000..159ed7f43 --- /dev/null +++ b/macosx/Daphne.xcodeproj/project.pbxproj @@ -0,0 +1,2821 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 44; + objects = { + +/* Begin PBXBuildFile section */ + 9414C1B60A9104C800F8A711 /* config.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9414C1B50A9104C800F8A711 /* config.h */; }; + 9414C1CD0A9106C900F8A711 /* video_out_dx.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1C90A9106C900F8A711 /* video_out_dx.c */; }; + 9414C1CE0A9106C900F8A711 /* video_out_null.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CA0A9106C900F8A711 /* video_out_null.c */; }; + 9414C1CF0A9106C900F8A711 /* video_out_pgm.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CB0A9106C900F8A711 /* video_out_pgm.c */; }; + 9414C1D00A9106C900F8A711 /* video_out_x11.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CC0A9106C900F8A711 /* video_out_x11.c */; }; + 943DBCFE0CBB47CA00525DD9 /* GLExtensionWrangler.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 943DBCF80CBB47CA00525DD9 /* GLExtensionWrangler.framework */; }; + 943DBCFF0CBB47CA00525DD9 /* GLExtensionWrangler.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 943DBCF80CBB47CA00525DD9 /* GLExtensionWrangler.framework */; }; + 943DBEEE0CBB49CD00525DD9 /* GLExtensionWrangler.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 943DBCF80CBB47CA00525DD9 /* GLExtensionWrangler.framework */; }; + 94465BBB0A90072F006FD484 /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B7E0A90072F006FD484 /* Ogg.framework */; }; + 94465BBD0A90072F006FD484 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B800A90072F006FD484 /* SDL.framework */; }; + 94465BBE0A90072F006FD484 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B810A90072F006FD484 /* Vorbis.framework */; }; + 94465BBF0A90074C006FD484 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B7E0A90072F006FD484 /* Ogg.framework */; }; + 94465BC10A90074C006FD484 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B800A90072F006FD484 /* SDL.framework */; }; + 94465BC20A90074C006FD484 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B810A90072F006FD484 /* Vorbis.framework */; }; + 9453E3370C10C64E000EFDC2 /* mix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9453E3350C10C64E000EFDC2 /* mix.cpp */; }; + 9453E3380C10C64E000EFDC2 /* mix.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9453E3360C10C64E000EFDC2 /* mix.h */; }; + 946EB6B60CB83D8C003FE54F /* yuv2rgb_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 946EB6B50CB83D8C003FE54F /* yuv2rgb_mmx.c */; }; + 946EB6B70CB83D8C003FE54F /* yuv2rgb_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 946EB6B50CB83D8C003FE54F /* yuv2rgb_mmx.c */; }; + 948856880A8FDE65000B5138 /* ConsoleFont.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856260A8FDE14000B5138 /* ConsoleFont.bmp */; }; + 948856890A8FDE65000B5138 /* credits.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856270A8FDE14000B5138 /* credits.bmp */; }; + 9488568A0A8FDE65000B5138 /* gamenowook.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856280A8FDE14000B5138 /* gamenowook.bmp */; }; + 9488568B0A8FDE65000B5138 /* ldp1450font.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856290A8FDE14000B5138 /* ldp1450font.bmp */; }; + 9488568C0A8FDE65000B5138 /* led0.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562A0A8FDE14000B5138 /* led0.bmp */; }; + 9488568D0A8FDE65000B5138 /* led1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562B0A8FDE14000B5138 /* led1.bmp */; }; + 9488568E0A8FDE65000B5138 /* led10.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562C0A8FDE14000B5138 /* led10.bmp */; }; + 9488568F0A8FDE65000B5138 /* led11.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562D0A8FDE14000B5138 /* led11.bmp */; }; + 948856900A8FDE65000B5138 /* led12.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562E0A8FDE14000B5138 /* led12.bmp */; }; + 948856910A8FDE65000B5138 /* led13.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562F0A8FDE14000B5138 /* led13.bmp */; }; + 948856920A8FDE65000B5138 /* led14.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856300A8FDE14000B5138 /* led14.bmp */; }; + 948856930A8FDE65000B5138 /* led15.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856310A8FDE14000B5138 /* led15.bmp */; }; + 948856940A8FDE65000B5138 /* led16.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856320A8FDE14000B5138 /* led16.bmp */; }; + 948856950A8FDE65000B5138 /* led2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856330A8FDE14000B5138 /* led2.bmp */; }; + 948856960A8FDE65000B5138 /* led3.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856340A8FDE14000B5138 /* led3.bmp */; }; + 948856970A8FDE65000B5138 /* led4.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856350A8FDE14000B5138 /* led4.bmp */; }; + 948856980A8FDE65000B5138 /* led5.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856360A8FDE14000B5138 /* led5.bmp */; }; + 948856990A8FDE65000B5138 /* led6.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856370A8FDE14000B5138 /* led6.bmp */; }; + 9488569A0A8FDE65000B5138 /* led7.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856380A8FDE14000B5138 /* led7.bmp */; }; + 9488569B0A8FDE65000B5138 /* led8.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856390A8FDE14000B5138 /* led8.bmp */; }; + 9488569C0A8FDE65000B5138 /* led9.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563A0A8FDE14000B5138 /* led9.bmp */; }; + 9488569D0A8FDE65000B5138 /* lives.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563B0A8FDE14000B5138 /* lives.bmp */; }; + 9488569E0A8FDE65000B5138 /* overlayleds1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563E0A8FDE14000B5138 /* overlayleds1.bmp */; }; + 9488569F0A8FDE65000B5138 /* overlayleds2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563F0A8FDE14000B5138 /* overlayleds2.bmp */; }; + 948856A00A8FDE65000B5138 /* player1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856400A8FDE14000B5138 /* player1.bmp */; }; + 948856A10A8FDE65000B5138 /* player2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856410A8FDE14000B5138 /* player2.bmp */; }; + 948856A20A8FDE65000B5138 /* saveme.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856420A8FDE14000B5138 /* saveme.bmp */; }; + 948856A30A8FDE71000B5138 /* ab_alarm1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856440A8FDE2D000B5138 /* ab_alarm1.wav */; }; + 948856A40A8FDE71000B5138 /* ab_alarm2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856450A8FDE2D000B5138 /* ab_alarm2.wav */; }; + 948856A50A8FDE71000B5138 /* ab_alarm3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856460A8FDE2D000B5138 /* ab_alarm3.wav */; }; + 948856A60A8FDE71000B5138 /* ab_alarm4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856470A8FDE2D000B5138 /* ab_alarm4.wav */; }; + 948856A70A8FDE71000B5138 /* ab_enemy.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856480A8FDE2D000B5138 /* ab_enemy.wav */; }; + 948856A80A8FDE71000B5138 /* ab_fire.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856490A8FDE2D000B5138 /* ab_fire.wav */; }; + 948856A90A8FDE71000B5138 /* ab_ship.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564A0A8FDE2D000B5138 /* ab_ship.wav */; }; + 948856AA0A8FDE71000B5138 /* bl_shot.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564B0A8FDE2D000B5138 /* bl_shot.wav */; }; + 948856AB0A8FDE71000B5138 /* cliff_correct.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564C0A8FDE2D000B5138 /* cliff_correct.wav */; }; + 948856AC0A8FDE71000B5138 /* cliff_startup.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564D0A8FDE2D000B5138 /* cliff_startup.wav */; }; + 948856AD0A8FDE71000B5138 /* cliff_wrong.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564E0A8FDE2D000B5138 /* cliff_wrong.wav */; }; + 948856AE0A8FDE71000B5138 /* dl2_bad.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564F0A8FDE2D000B5138 /* dl2_bad.wav */; }; + 948856AF0A8FDE71000B5138 /* dl2_coin1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856500A8FDE2D000B5138 /* dl2_coin1.wav */; }; + 948856B00A8FDE71000B5138 /* dl2_coin2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856510A8FDE2D000B5138 /* dl2_coin2.wav */; }; + 948856B10A8FDE71000B5138 /* dl2_coin3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856520A8FDE2D000B5138 /* dl2_coin3.wav */; }; + 948856B20A8FDE71000B5138 /* dl2_coin4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856530A8FDE2D000B5138 /* dl2_coin4.wav */; }; + 948856B30A8FDE71000B5138 /* dl2_error.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856540A8FDE2D000B5138 /* dl2_error.wav */; }; + 948856B40A8FDE71000B5138 /* dl2_good.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856550A8FDE2D000B5138 /* dl2_good.wav */; }; + 948856B50A8FDE71000B5138 /* dl2_tic.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856560A8FDE2D000B5138 /* dl2_tic.wav */; }; + 948856B60A8FDE71000B5138 /* dl2_toc.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856570A8FDE2D000B5138 /* dl2_toc.wav */; }; + 948856B70A8FDE71000B5138 /* dl2_warble.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856580A8FDE2D000B5138 /* dl2_warble.wav */; }; + 948856B80A8FDE71000B5138 /* dl2_warn.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856590A8FDE2D000B5138 /* dl2_warn.wav */; }; + 948856B90A8FDE71000B5138 /* dl_accept.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565A0A8FDE2D000B5138 /* dl_accept.wav */; }; + 948856BA0A8FDE71000B5138 /* dl_buzz.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565B0A8FDE2D000B5138 /* dl_buzz.wav */; }; + 948856BB0A8FDE71000B5138 /* dl_credit.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565C0A8FDE2D000B5138 /* dl_credit.wav */; }; + 948856BC0A8FDE71000B5138 /* esh_beep.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565D0A8FDE2D000B5138 /* esh_beep.wav */; }; + 948856BD0A8FDE71000B5138 /* gr_alarm1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565E0A8FDE2D000B5138 /* gr_alarm1.wav */; }; + 948856BE0A8FDE71000B5138 /* gr_alarm2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565F0A8FDE2D000B5138 /* gr_alarm2.wav */; }; + 948856BF0A8FDE71000B5138 /* gr_alarm3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856600A8FDE2D000B5138 /* gr_alarm3.wav */; }; + 948856C00A8FDE71000B5138 /* gr_alarm4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856610A8FDE2D000B5138 /* gr_alarm4.wav */; }; + 948856C10A8FDE71000B5138 /* gr_attack.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856620A8FDE2D000B5138 /* gr_attack.wav */; }; + 948856C20A8FDE71000B5138 /* gr_cannon.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856630A8FDE2D000B5138 /* gr_cannon.wav */; }; + 948856C30A8FDE71000B5138 /* gr_fire.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856640A8FDE2D000B5138 /* gr_fire.wav */; }; + 948856C40A8FDE71000B5138 /* gr_mineon.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856650A8FDE2D000B5138 /* gr_mineon.wav */; }; + 948856C50A8FDE71000B5138 /* mach3-01.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856660A8FDE2D000B5138 /* mach3-01.ogg */; }; + 948856C60A8FDE71000B5138 /* mach3-02.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856670A8FDE2D000B5138 /* mach3-02.ogg */; }; + 948856C70A8FDE71000B5138 /* mach3-03.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856680A8FDE2D000B5138 /* mach3-03.ogg */; }; + 948856C80A8FDE71000B5138 /* mach3-04.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856690A8FDE2D000B5138 /* mach3-04.ogg */; }; + 948856C90A8FDE71000B5138 /* mach3-05.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566A0A8FDE2D000B5138 /* mach3-05.ogg */; }; + 948856CA0A8FDE71000B5138 /* mach3-06.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566B0A8FDE2D000B5138 /* mach3-06.ogg */; }; + 948856CB0A8FDE71000B5138 /* mach3-07.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566C0A8FDE2D000B5138 /* mach3-07.ogg */; }; + 948856CC0A8FDE71000B5138 /* mach3-08.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566D0A8FDE2D000B5138 /* mach3-08.ogg */; }; + 948856CD0A8FDE71000B5138 /* mach3-09.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566E0A8FDE2D000B5138 /* mach3-09.ogg */; }; + 948856CE0A8FDE71000B5138 /* mach3-11.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566F0A8FDE2D000B5138 /* mach3-11.ogg */; }; + 948856CF0A8FDE71000B5138 /* mach3-13.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856700A8FDE2D000B5138 /* mach3-13.ogg */; }; + 948856D00A8FDE71000B5138 /* mach3-15.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856710A8FDE2D000B5138 /* mach3-15.ogg */; }; + 948856D10A8FDE71000B5138 /* mach3-19.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856720A8FDE2D000B5138 /* mach3-19.ogg */; }; + 948856D20A8FDE71000B5138 /* mach3-20.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856730A8FDE2D000B5138 /* mach3-20.ogg */; }; + 948856D30A8FDE71000B5138 /* mach3-22.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856740A8FDE2D000B5138 /* mach3-22.ogg */; }; + 948856D40A8FDE71000B5138 /* mach3-33.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856750A8FDE2D000B5138 /* mach3-33.ogg */; }; + 948856D50A8FDE71000B5138 /* mach3-34.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856760A8FDE2D000B5138 /* mach3-34.ogg */; }; + 948856D60A8FDE71000B5138 /* mach3-35.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856770A8FDE2D000B5138 /* mach3-35.ogg */; }; + 948856D70A8FDE71000B5138 /* mach3-36.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856780A8FDE2D000B5138 /* mach3-36.ogg */; }; + 948856D80A8FDE71000B5138 /* mach3-37.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856790A8FDE2D000B5138 /* mach3-37.ogg */; }; + 948856D90A8FDE71000B5138 /* mach3-39.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567A0A8FDE2D000B5138 /* mach3-39.ogg */; }; + 948856DA0A8FDE71000B5138 /* mach3-40.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567B0A8FDE2D000B5138 /* mach3-40.ogg */; }; + 948856DB0A8FDE71000B5138 /* mach3-41.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567C0A8FDE2D000B5138 /* mach3-41.ogg */; }; + 948856DC0A8FDE71000B5138 /* mach3-42.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567D0A8FDE2D000B5138 /* mach3-42.ogg */; }; + 948856DD0A8FDE71000B5138 /* mach3-43.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567E0A8FDE2D000B5138 /* mach3-43.ogg */; }; + 948856DE0A8FDE71000B5138 /* mach3-45.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567F0A8FDE2D000B5138 /* mach3-45.ogg */; }; + 948856DF0A8FDE71000B5138 /* mach3-49.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856800A8FDE2D000B5138 /* mach3-49.ogg */; }; + 948856E00A8FDE71000B5138 /* mach3-null.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856810A8FDE2D000B5138 /* mach3-null.ogg */; }; + 948856E10A8FDE71000B5138 /* saveme.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856820A8FDE2D000B5138 /* saveme.wav */; }; + 948856E20A8FDE71000B5138 /* sd_coin.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856830A8FDE2D000B5138 /* sd_coin.wav */; }; + 948856E30A8FDE71000B5138 /* sd_fail.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856840A8FDE2D000B5138 /* sd_fail.wav */; }; + 948856E40A8FDE71000B5138 /* sd_succeed.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856850A8FDE2D000B5138 /* sd_succeed.wav */; }; + 948856E50A8FDE71000B5138 /* sda_success_hi.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856860A8FDE2D000B5138 /* sda_success_hi.wav */; }; + 948856E60A8FDE71000B5138 /* sda_success_lo.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856870A8FDE2D000B5138 /* sda_success_lo.wav */; }; + 948858410A8FE2FC000B5138 /* convert_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858290A8FE2FB000B5138 /* convert_internal.h */; }; + 948858420A8FE2FC000B5138 /* hw_bes.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488582A0A8FE2FB000B5138 /* hw_bes.h */; }; + 948858460A8FE2FC000B5138 /* video_out.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488582E0A8FE2FB000B5138 /* video_out.c */; }; + 9488584A0A8FE2FC000B5138 /* video_out_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858320A8FE2FB000B5138 /* video_out_sdl.c */; }; + 9488584C0A8FE2FC000B5138 /* yuv2rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858340A8FE2FB000B5138 /* yuv2rgb.c */; }; + 9488584D0A8FE2FC000B5138 /* yuv2rgb_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858350A8FE2FB000B5138 /* yuv2rgb_mlib.c */; }; + 9488585D0A8FE316000B5138 /* alpha_asm.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858500A8FE316000B5138 /* alpha_asm.h */; }; + 9488585E0A8FE316000B5138 /* attributes.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858510A8FE316000B5138 /* attributes.h */; }; + 948858610A8FE316000B5138 /* convert.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858540A8FE316000B5138 /* convert.h */; }; + 948858650A8FE316000B5138 /* mmx.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858580A8FE316000B5138 /* mmx.h */; }; + 948858660A8FE316000B5138 /* mpeg2.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858590A8FE316000B5138 /* mpeg2.h */; }; + 948858680A8FE316000B5138 /* tendra.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488585B0A8FE316000B5138 /* tendra.h */; }; + 948858690A8FE316000B5138 /* video_out.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488585C0A8FE316000B5138 /* video_out.h */; }; + 948858C40A8FE345000B5138 /* mpegscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858BD0A8FE345000B5138 /* mpegscan.c */; }; + 948858C50A8FE345000B5138 /* mpegscan.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858BE0A8FE345000B5138 /* mpegscan.h */; }; + 948858C60A8FE345000B5138 /* vldp.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858BF0A8FE345000B5138 /* vldp.c */; }; + 948858C70A8FE345000B5138 /* vldp.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C00A8FE345000B5138 /* vldp.h */; }; + 948858C80A8FE345000B5138 /* vldp_common.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C10A8FE345000B5138 /* vldp_common.h */; }; + 948858C90A8FE345000B5138 /* vldp_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858C20A8FE345000B5138 /* vldp_internal.c */; }; + 948858CA0A8FE345000B5138 /* vldp_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C30A8FE345000B5138 /* vldp_internal.h */; }; + 9488593E0A8FE5D5000B5138 /* alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859160A8FE5D5000B5138 /* alloc.c */; }; + 948859400A8FE5D5000B5138 /* cpu_accel.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859180A8FE5D5000B5138 /* cpu_accel.c */; }; + 948859410A8FE5D5000B5138 /* cpu_state.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859190A8FE5D5000B5138 /* cpu_state.c */; }; + 948859420A8FE5D5000B5138 /* decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591A0A8FE5D5000B5138 /* decode.c */; }; + 948859430A8FE5D5000B5138 /* header.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591B0A8FE5D5000B5138 /* header.c */; }; + 948859440A8FE5D5000B5138 /* idct.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591C0A8FE5D5000B5138 /* idct.c */; }; + 948859450A8FE5D5000B5138 /* idct_alpha.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591D0A8FE5D5000B5138 /* idct_alpha.c */; }; + 948859460A8FE5D5000B5138 /* idct_altivec.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591E0A8FE5D5000B5138 /* idct_altivec.c */; }; + 948859470A8FE5D5000B5138 /* idct_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591F0A8FE5D5000B5138 /* idct_mlib.c */; }; + 948859480A8FE5D5000B5138 /* idct_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859200A8FE5D5000B5138 /* idct_mmx.c */; }; + 9488594E0A8FE5D5000B5138 /* motion_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859260A8FE5D5000B5138 /* motion_comp.c */; }; + 9488594F0A8FE5D5000B5138 /* motion_comp_alpha.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859270A8FE5D5000B5138 /* motion_comp_alpha.c */; }; + 948859500A8FE5D5000B5138 /* motion_comp_altivec.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859280A8FE5D5000B5138 /* motion_comp_altivec.c */; }; + 948859510A8FE5D5000B5138 /* motion_comp_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859290A8FE5D5000B5138 /* motion_comp_mlib.c */; }; + 948859520A8FE5D5000B5138 /* motion_comp_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488592A0A8FE5D5000B5138 /* motion_comp_mmx.c */; }; + 948859530A8FE5D5000B5138 /* mpeg2_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488592B0A8FE5D5000B5138 /* mpeg2_internal.h */; }; + 948859540A8FE5D5000B5138 /* slice.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488592C0A8FE5D5000B5138 /* slice.c */; }; + 948859550A8FE5D5000B5138 /* vlc.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488592D0A8FE5D5000B5138 /* vlc.h */; }; + 94885A660A8FF28A000B5138 /* ldp-vldp-audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94885A650A8FF28A000B5138 /* ldp-vldp-audio.cpp */; }; + 94936AE20A8E88F400BDCACE /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 94936AE00A8E88F400BDCACE /* SDLMain.m */; }; + 94936AE30A8E88F400BDCACE /* SDLMain.nib in Resources */ = {isa = PBXBuildFile; fileRef = 94936AE10A8E88F400BDCACE /* SDLMain.nib */; }; + 94936B4E0A8E8D4600BDCACE /* daphne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B4C0A8E8D4600BDCACE /* daphne.cpp */; }; + 94936B900A8E8DF900BDCACE /* 6809infc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B5F0A8E8DF900BDCACE /* 6809infc.cpp */; }; + 94936B910A8E8DF900BDCACE /* cop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B610A8E8DF900BDCACE /* cop.cpp */; }; + 94936B920A8E8DF900BDCACE /* copintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B630A8E8DF900BDCACE /* copintf.cpp */; }; + 94936B930A8E8DF900BDCACE /* cpu-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B650A8E8DF900BDCACE /* cpu-debug.cpp */; }; + 94936B940A8E8DF900BDCACE /* cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B670A8E8DF900BDCACE /* cpu.cpp */; }; + 94936B960A8E8DF900BDCACE /* m80.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B6D0A8E8DF900BDCACE /* m80.cpp */; }; + 94936B990A8E8DF900BDCACE /* mamewrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B730A8E8DF900BDCACE /* mamewrap.cpp */; }; + 94936B9A0A8E8DF900BDCACE /* mc6809.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B750A8E8DF900BDCACE /* mc6809.cpp */; }; + 94936B9B0A8E8DF900BDCACE /* nes_6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B770A8E8DF900BDCACE /* nes_6502.cpp */; }; + 94936B9C0A8E8DF900BDCACE /* nes6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B790A8E8DF900BDCACE /* nes6502.cpp */; }; + 94936B9F0A8E8DF900BDCACE /* z80dasm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B8E0A8E8DF900BDCACE /* z80dasm.cpp */; }; + 94936BE80A8E8E5700BDCACE /* astron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BAF0A8E8E5700BDCACE /* astron.cpp */; }; + 94936BE90A8E8E5700BDCACE /* badlands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB10A8E8E5700BDCACE /* badlands.cpp */; }; + 94936BEA0A8E8E5700BDCACE /* bega.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB30A8E8E5700BDCACE /* bega.cpp */; }; + 94936BEB0A8E8E5700BDCACE /* benchmark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB50A8E8E5700BDCACE /* benchmark.cpp */; }; + 94936BEC0A8E8E5700BDCACE /* boardinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB70A8E8E5700BDCACE /* boardinfo.cpp */; }; + 94936BED0A8E8E5700BDCACE /* cliff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB90A8E8E5700BDCACE /* cliff.cpp */; }; + 94936BEE0A8E8E5700BDCACE /* cobraconv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BBB0A8E8E5700BDCACE /* cobraconv.cpp */; }; + 94936BEF0A8E8E5700BDCACE /* cputest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BBD0A8E8E5700BDCACE /* cputest.cpp */; }; + 94936BF10A8E8E5700BDCACE /* esh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC10A8E8E5700BDCACE /* esh.cpp */; }; + 94936BF20A8E8E5700BDCACE /* ffr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC30A8E8E5700BDCACE /* ffr.cpp */; }; + 94936BF30A8E8E5700BDCACE /* firefox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC50A8E8E5700BDCACE /* firefox.cpp */; }; + 94936BF40A8E8E5700BDCACE /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC70A8E8E5700BDCACE /* game.cpp */; }; + 94936BF50A8E8E5700BDCACE /* gpworld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC90A8E8E5700BDCACE /* gpworld.cpp */; }; + 94936BF60A8E8E5700BDCACE /* interstellar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCB0A8E8E5700BDCACE /* interstellar.cpp */; }; + 94936BF70A8E8E5700BDCACE /* lair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCD0A8E8E5700BDCACE /* lair.cpp */; }; + 94936BF80A8E8E5700BDCACE /* lair2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCF0A8E8E5700BDCACE /* lair2.cpp */; }; + 94936BF90A8E8E5700BDCACE /* laireuro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD10A8E8E5700BDCACE /* laireuro.cpp */; }; + 94936BFA0A8E8E5700BDCACE /* lgp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD30A8E8E5700BDCACE /* lgp.cpp */; }; + 94936BFB0A8E8E5700BDCACE /* mach3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD50A8E8E5700BDCACE /* mach3.cpp */; }; + 94936BFD0A8E8E5700BDCACE /* multicputest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD80A8E8E5700BDCACE /* multicputest.cpp */; }; + 94936BFE0A8E8E5700BDCACE /* releasetest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDA0A8E8E5700BDCACE /* releasetest.cpp */; }; + 94936BFF0A8E8E5700BDCACE /* seektest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDC0A8E8E5700BDCACE /* seektest.cpp */; }; + 94936C000A8E8E5700BDCACE /* speedtest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDE0A8E8E5700BDCACE /* speedtest.cpp */; }; + 94936C010A8E8E5700BDCACE /* starrider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE00A8E8E5700BDCACE /* starrider.cpp */; }; + 94936C020A8E8E5700BDCACE /* superd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE20A8E8E5700BDCACE /* superd.cpp */; }; + 94936C030A8E8E5700BDCACE /* thayers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE40A8E8E5700BDCACE /* thayers.cpp */; }; + 94936C040A8E8E5700BDCACE /* timetrav.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE60A8E8E5700BDCACE /* timetrav.cpp */; }; + 94936C280A8E8E7100BDCACE /* cmdline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C060A8E8E7100BDCACE /* cmdline.cpp */; }; + 94936C290A8E8E7100BDCACE /* conin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C080A8E8E7100BDCACE /* conin.cpp */; }; + 94936C2A0A8E8E7100BDCACE /* conout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0A0A8E8E7100BDCACE /* conout.cpp */; }; + 94936C2B0A8E8E7100BDCACE /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0D0A8E8E7100BDCACE /* error.cpp */; }; + 94936C2C0A8E8E7100BDCACE /* fileparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0F0A8E8E7100BDCACE /* fileparse.cpp */; }; + 94936C2D0A8E8E7100BDCACE /* homedir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C110A8E8E7100BDCACE /* homedir.cpp */; }; + 94936C2E0A8E8E7100BDCACE /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C130A8E8E7100BDCACE /* input.cpp */; }; + 94936C300A8E8E7100BDCACE /* mpo_fileio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C160A8E8E7100BDCACE /* mpo_fileio.cpp */; }; + 94936C310A8E8E7100BDCACE /* network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C1A0A8E8E7100BDCACE /* network.cpp */; }; + 94936C320A8E8E7100BDCACE /* numstr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C1C0A8E8E7100BDCACE /* numstr.cpp */; }; + 94936C340A8E8E7100BDCACE /* parallel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C200A8E8E7100BDCACE /* parallel.cpp */; }; + 94936C350A8E8E7100BDCACE /* serial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C220A8E8E7100BDCACE /* serial.cpp */; }; + 94936C360A8E8E7100BDCACE /* sram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C240A8E8E7100BDCACE /* sram.cpp */; }; + 94936C370A8E8E7100BDCACE /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C260A8E8E7100BDCACE /* unzip.cpp */; }; + 94936C4A0A8E8E9C00BDCACE /* ldp1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C390A8E8E9C00BDCACE /* ldp1000.cpp */; }; + 94936C4B0A8E8E9C00BDCACE /* ldv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C3B0A8E8E9C00BDCACE /* ldv1000.cpp */; }; + 94936C4D0A8E8E9C00BDCACE /* pr7820.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C3E0A8E8E9C00BDCACE /* pr7820.cpp */; }; + 94936C4E0A8E8E9C00BDCACE /* pr8210.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C400A8E8E9C00BDCACE /* pr8210.cpp */; }; + 94936C4F0A8E8E9C00BDCACE /* vip9500sg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C420A8E8E9C00BDCACE /* vip9500sg.cpp */; }; + 94936C500A8E8E9C00BDCACE /* vp380.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C440A8E8E9C00BDCACE /* vp380.cpp */; }; + 94936C510A8E8E9C00BDCACE /* vp931.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C460A8E8E9C00BDCACE /* vp931.cpp */; }; + 94936C520A8E8E9C00BDCACE /* vp932.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C480A8E8E9C00BDCACE /* vp932.cpp */; }; + 94936C6A0A8E8EAB00BDCACE /* framemod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C540A8E8EAB00BDCACE /* framemod.cpp */; }; + 94936C6B0A8E8EAB00BDCACE /* hitachi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C560A8E8EAB00BDCACE /* hitachi.cpp */; }; + 94936C6C0A8E8EAB00BDCACE /* ld-v6000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C580A8E8EAB00BDCACE /* ld-v6000.cpp */; }; + 94936C6D0A8E8EAB00BDCACE /* ldp-combo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5A0A8E8EAB00BDCACE /* ldp-combo.cpp */; }; + 94936C6F0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5D0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp */; }; + 94936C700A8E8EAB00BDCACE /* ldp-vldp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5F0A8E8EAB00BDCACE /* ldp-vldp.cpp */; }; + 94936C710A8E8EAB00BDCACE /* ldp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C610A8E8EAB00BDCACE /* ldp.cpp */; }; + 94936C730A8E8EAB00BDCACE /* philips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C640A8E8EAB00BDCACE /* philips.cpp */; }; + 94936C740A8E8EAB00BDCACE /* pioneer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C660A8E8EAB00BDCACE /* pioneer.cpp */; }; + 94936C750A8E8EAB00BDCACE /* sony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C680A8E8EAB00BDCACE /* sony.cpp */; }; + 94936C8C0A8E8EBF00BDCACE /* dac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C770A8E8EBF00BDCACE /* dac.cpp */; }; + 94936C8D0A8E8EBF00BDCACE /* gisound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C790A8E8EBF00BDCACE /* gisound.cpp */; }; + 94936C8F0A8E8EBF00BDCACE /* pc_beeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C7C0A8E8EBF00BDCACE /* pc_beeper.cpp */; }; + 94936C900A8E8EBF00BDCACE /* sn_intf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C7E0A8E8EBF00BDCACE /* sn_intf.cpp */; }; + 94936C910A8E8EBF00BDCACE /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C800A8E8EBF00BDCACE /* sound.cpp */; }; + 94936C920A8E8EBF00BDCACE /* ssi263.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C820A8E8EBF00BDCACE /* ssi263.cpp */; }; + 94936C930A8E8EBF00BDCACE /* tms9919-sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C840A8E8EBF00BDCACE /* tms9919-sdl.cpp */; }; + 94936C940A8E8EBF00BDCACE /* tms9919.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C860A8E8EBF00BDCACE /* tms9919.cpp */; }; + 94936C950A8E8EBF00BDCACE /* tonegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C880A8E8EBF00BDCACE /* tonegen.cpp */; }; + 94936C960A8E8EBF00BDCACE /* tqsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C8A0A8E8EBF00BDCACE /* tqsynth.cpp */; }; + 94936CBC0A8E8EE200BDCACE /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C990A8E8EE200BDCACE /* timer.cpp */; }; + 94936CBD0A8E8EE200BDCACE /* blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C9C0A8E8EE200BDCACE /* blend.cpp */; }; + 94936CC00A8E8EE200BDCACE /* led.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA00A8E8EE200BDCACE /* led.cpp */; }; + 94936CC30A8E8EE200BDCACE /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA40A8E8EE200BDCACE /* palette.cpp */; }; + 94936CC60A8E8EE200BDCACE /* rgb2yuv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA80A8E8EE200BDCACE /* rgb2yuv.cpp */; }; + 94936CC80A8E8EE200BDCACE /* SDL_Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CAC0A8E8EE200BDCACE /* SDL_Console.cpp */; }; + 94936CC90A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CAE0A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp */; }; + 94936CCA0A8E8EE200BDCACE /* SDL_DrawText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB00A8E8EE200BDCACE /* SDL_DrawText.cpp */; }; + 94936CCC0A8E8EE200BDCACE /* tms9128nl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB30A8E8EE200BDCACE /* tms9128nl.cpp */; }; + 94936CCD0A8E8EE200BDCACE /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB50A8E8EE200BDCACE /* video.cpp */; }; + 94936CCE0A8E8EE200BDCACE /* yuv2rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB70A8E8EE200BDCACE /* yuv2rgb.c */; }; + 94936DEE0A8E99C300BDCACE /* i86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936DE40A8E99C300BDCACE /* i86.cpp */; }; + 94936DEF0A8E99C300BDCACE /* i86dasm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936DE60A8E99C300BDCACE /* i86dasm.cpp */; }; + 94A366140CADA86700667ABE /* hw_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366050CADA86700667ABE /* hw_scoreboard.cpp */; }; + 94A366150CADA86700667ABE /* hw_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366060CADA86700667ABE /* hw_scoreboard.h */; }; + 94A366160CADA86700667ABE /* img_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366070CADA86700667ABE /* img_scoreboard.cpp */; }; + 94A366170CADA86700667ABE /* img_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366080CADA86700667ABE /* img_scoreboard.h */; }; + 94A366180CADA86700667ABE /* null_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366090CADA86700667ABE /* null_scoreboard.cpp */; }; + 94A366190CADA86700667ABE /* null_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660A0CADA86700667ABE /* null_scoreboard.h */; }; + 94A3661A0CADA86700667ABE /* overlay_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660B0CADA86700667ABE /* overlay_scoreboard.cpp */; }; + 94A3661B0CADA86700667ABE /* overlay_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660C0CADA86700667ABE /* overlay_scoreboard.h */; }; + 94A3661C0CADA86700667ABE /* scoreboard_collection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660D0CADA86700667ABE /* scoreboard_collection.cpp */; }; + 94A3661D0CADA86700667ABE /* scoreboard_collection.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660E0CADA86700667ABE /* scoreboard_collection.h */; }; + 94A3661E0CADA86700667ABE /* scoreboard_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660F0CADA86700667ABE /* scoreboard_factory.cpp */; }; + 94A3661F0CADA86700667ABE /* scoreboard_factory.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366100CADA86700667ABE /* scoreboard_factory.h */; }; + 94A366200CADA86700667ABE /* scoreboard_howto.txt in Resources */ = {isa = PBXBuildFile; fileRef = 94A366110CADA86700667ABE /* scoreboard_howto.txt */; }; + 94A366210CADA86700667ABE /* scoreboard_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366120CADA86700667ABE /* scoreboard_interface.cpp */; }; + 94A366220CADA86700667ABE /* scoreboard_interface.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366130CADA86700667ABE /* scoreboard_interface.h */; }; + 94A366230CADA86700667ABE /* hw_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366050CADA86700667ABE /* hw_scoreboard.cpp */; }; + 94A366240CADA86700667ABE /* hw_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366060CADA86700667ABE /* hw_scoreboard.h */; }; + 94A366250CADA86700667ABE /* img_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366070CADA86700667ABE /* img_scoreboard.cpp */; }; + 94A366260CADA86700667ABE /* img_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366080CADA86700667ABE /* img_scoreboard.h */; }; + 94A366270CADA86700667ABE /* null_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366090CADA86700667ABE /* null_scoreboard.cpp */; }; + 94A366280CADA86700667ABE /* null_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660A0CADA86700667ABE /* null_scoreboard.h */; }; + 94A366290CADA86700667ABE /* overlay_scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660B0CADA86700667ABE /* overlay_scoreboard.cpp */; }; + 94A3662A0CADA86700667ABE /* overlay_scoreboard.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660C0CADA86700667ABE /* overlay_scoreboard.h */; }; + 94A3662B0CADA86700667ABE /* scoreboard_collection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660D0CADA86700667ABE /* scoreboard_collection.cpp */; }; + 94A3662C0CADA86700667ABE /* scoreboard_collection.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3660E0CADA86700667ABE /* scoreboard_collection.h */; }; + 94A3662D0CADA86700667ABE /* scoreboard_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3660F0CADA86700667ABE /* scoreboard_factory.cpp */; }; + 94A3662E0CADA86700667ABE /* scoreboard_factory.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366100CADA86700667ABE /* scoreboard_factory.h */; }; + 94A3662F0CADA86700667ABE /* scoreboard_howto.txt in Resources */ = {isa = PBXBuildFile; fileRef = 94A366110CADA86700667ABE /* scoreboard_howto.txt */; }; + 94A366300CADA86700667ABE /* scoreboard_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366120CADA86700667ABE /* scoreboard_interface.cpp */; }; + 94A366310CADA86700667ABE /* scoreboard_interface.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366130CADA86700667ABE /* scoreboard_interface.h */; }; + 94A366540CADAB1900667ABE /* logger_console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3664E0CADAB1900667ABE /* logger_console.cpp */; }; + 94A366550CADAB1900667ABE /* logger_console.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3664F0CADAB1900667ABE /* logger_console.h */; }; + 94A366560CADAB1900667ABE /* logger_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366500CADAB1900667ABE /* logger_factory.cpp */; }; + 94A366570CADAB1900667ABE /* logger_factory.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366510CADAB1900667ABE /* logger_factory.h */; }; + 94A366580CADAB1900667ABE /* logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366520CADAB1900667ABE /* logger.cpp */; }; + 94A366590CADAB1900667ABE /* logger.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366530CADAB1900667ABE /* logger.h */; }; + 94A3665A0CADAB1900667ABE /* logger_console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3664E0CADAB1900667ABE /* logger_console.cpp */; }; + 94A3665B0CADAB1900667ABE /* logger_console.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3664F0CADAB1900667ABE /* logger_console.h */; }; + 94A3665C0CADAB1900667ABE /* logger_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366500CADAB1900667ABE /* logger_factory.cpp */; }; + 94A3665D0CADAB1900667ABE /* logger_factory.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366510CADAB1900667ABE /* logger_factory.h */; }; + 94A3665E0CADAB1900667ABE /* logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A366520CADAB1900667ABE /* logger.cpp */; }; + 94A3665F0CADAB1900667ABE /* logger.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A366530CADAB1900667ABE /* logger.h */; }; + 94A366900CADAC7000667ABE /* test_sb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3668E0CADAC7000667ABE /* test_sb.cpp */; }; + 94A366910CADAC7000667ABE /* test_sb.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3668F0CADAC7000667ABE /* test_sb.h */; }; + 94A366920CADAC7000667ABE /* test_sb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A3668E0CADAC7000667ABE /* test_sb.cpp */; }; + 94A366930CADAC7000667ABE /* test_sb.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A3668F0CADAC7000667ABE /* test_sb.h */; }; + 94A98F5C0C16FC770072471F /* SDLMain.nib in Resources */ = {isa = PBXBuildFile; fileRef = 94936AE10A8E88F400BDCACE /* SDLMain.nib */; }; + 94A98F5D0C16FC770072471F /* Daphne Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 94AD92670AA00B7000C9CDC4 /* Daphne Icon.icns */; }; + 94A98F5E0C16FC770072471F /* DaphneManifest.xml in Resources */ = {isa = PBXBuildFile; fileRef = 94F97A390B39B16300F29536 /* DaphneManifest.xml */; }; + 94A98F600C16FC770072471F /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 94936AE00A8E88F400BDCACE /* SDLMain.m */; }; + 94A98F610C16FC770072471F /* daphne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B4C0A8E8D4600BDCACE /* daphne.cpp */; }; + 94A98F620C16FC770072471F /* 6809infc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B5F0A8E8DF900BDCACE /* 6809infc.cpp */; }; + 94A98F630C16FC770072471F /* cop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B610A8E8DF900BDCACE /* cop.cpp */; }; + 94A98F640C16FC770072471F /* copintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B630A8E8DF900BDCACE /* copintf.cpp */; }; + 94A98F650C16FC770072471F /* cpu-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B650A8E8DF900BDCACE /* cpu-debug.cpp */; }; + 94A98F660C16FC770072471F /* cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B670A8E8DF900BDCACE /* cpu.cpp */; }; + 94A98F670C16FC770072471F /* m80.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B6D0A8E8DF900BDCACE /* m80.cpp */; }; + 94A98F680C16FC770072471F /* mamewrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B730A8E8DF900BDCACE /* mamewrap.cpp */; }; + 94A98F690C16FC770072471F /* mc6809.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B750A8E8DF900BDCACE /* mc6809.cpp */; }; + 94A98F6A0C16FC770072471F /* nes_6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B770A8E8DF900BDCACE /* nes_6502.cpp */; }; + 94A98F6B0C16FC770072471F /* nes6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B790A8E8DF900BDCACE /* nes6502.cpp */; }; + 94A98F6C0C16FC770072471F /* z80dasm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936B8E0A8E8DF900BDCACE /* z80dasm.cpp */; }; + 94A98F6D0C16FC770072471F /* astron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BAF0A8E8E5700BDCACE /* astron.cpp */; }; + 94A98F6E0C16FC770072471F /* badlands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB10A8E8E5700BDCACE /* badlands.cpp */; }; + 94A98F6F0C16FC770072471F /* bega.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB30A8E8E5700BDCACE /* bega.cpp */; }; + 94A98F700C16FC770072471F /* benchmark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB50A8E8E5700BDCACE /* benchmark.cpp */; }; + 94A98F710C16FC770072471F /* boardinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB70A8E8E5700BDCACE /* boardinfo.cpp */; }; + 94A98F720C16FC770072471F /* cliff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BB90A8E8E5700BDCACE /* cliff.cpp */; }; + 94A98F730C16FC770072471F /* cobraconv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BBB0A8E8E5700BDCACE /* cobraconv.cpp */; }; + 94A98F740C16FC770072471F /* cputest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BBD0A8E8E5700BDCACE /* cputest.cpp */; }; + 94A98F750C16FC770072471F /* esh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC10A8E8E5700BDCACE /* esh.cpp */; }; + 94A98F760C16FC770072471F /* ffr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC30A8E8E5700BDCACE /* ffr.cpp */; }; + 94A98F770C16FC770072471F /* firefox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC50A8E8E5700BDCACE /* firefox.cpp */; }; + 94A98F780C16FC770072471F /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC70A8E8E5700BDCACE /* game.cpp */; }; + 94A98F790C16FC770072471F /* gpworld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BC90A8E8E5700BDCACE /* gpworld.cpp */; }; + 94A98F7A0C16FC770072471F /* interstellar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCB0A8E8E5700BDCACE /* interstellar.cpp */; }; + 94A98F7B0C16FC770072471F /* lair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCD0A8E8E5700BDCACE /* lair.cpp */; }; + 94A98F7C0C16FC770072471F /* lair2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BCF0A8E8E5700BDCACE /* lair2.cpp */; }; + 94A98F7D0C16FC770072471F /* laireuro.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD10A8E8E5700BDCACE /* laireuro.cpp */; }; + 94A98F7E0C16FC770072471F /* lgp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD30A8E8E5700BDCACE /* lgp.cpp */; }; + 94A98F7F0C16FC770072471F /* mach3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD50A8E8E5700BDCACE /* mach3.cpp */; }; + 94A98F800C16FC770072471F /* multicputest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BD80A8E8E5700BDCACE /* multicputest.cpp */; }; + 94A98F810C16FC770072471F /* releasetest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDA0A8E8E5700BDCACE /* releasetest.cpp */; }; + 94A98F820C16FC770072471F /* seektest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDC0A8E8E5700BDCACE /* seektest.cpp */; }; + 94A98F830C16FC770072471F /* speedtest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BDE0A8E8E5700BDCACE /* speedtest.cpp */; }; + 94A98F840C16FC770072471F /* starrider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE00A8E8E5700BDCACE /* starrider.cpp */; }; + 94A98F850C16FC770072471F /* superd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE20A8E8E5700BDCACE /* superd.cpp */; }; + 94A98F860C16FC770072471F /* thayers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE40A8E8E5700BDCACE /* thayers.cpp */; }; + 94A98F870C16FC780072471F /* timetrav.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936BE60A8E8E5700BDCACE /* timetrav.cpp */; }; + 94A98F880C16FC780072471F /* cmdline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C060A8E8E7100BDCACE /* cmdline.cpp */; }; + 94A98F890C16FC780072471F /* conin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C080A8E8E7100BDCACE /* conin.cpp */; }; + 94A98F8A0C16FC780072471F /* conout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0A0A8E8E7100BDCACE /* conout.cpp */; }; + 94A98F8B0C16FC780072471F /* error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0D0A8E8E7100BDCACE /* error.cpp */; }; + 94A98F8C0C16FC780072471F /* fileparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C0F0A8E8E7100BDCACE /* fileparse.cpp */; }; + 94A98F8D0C16FC780072471F /* homedir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C110A8E8E7100BDCACE /* homedir.cpp */; }; + 94A98F8E0C16FC780072471F /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C130A8E8E7100BDCACE /* input.cpp */; }; + 94A98F8F0C16FC780072471F /* mpo_fileio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C160A8E8E7100BDCACE /* mpo_fileio.cpp */; }; + 94A98F900C16FC780072471F /* network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C1A0A8E8E7100BDCACE /* network.cpp */; }; + 94A98F910C16FC780072471F /* numstr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C1C0A8E8E7100BDCACE /* numstr.cpp */; }; + 94A98F920C16FC780072471F /* parallel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C200A8E8E7100BDCACE /* parallel.cpp */; }; + 94A98F930C16FC780072471F /* serial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C220A8E8E7100BDCACE /* serial.cpp */; }; + 94A98F940C16FC780072471F /* sram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C240A8E8E7100BDCACE /* sram.cpp */; }; + 94A98F950C16FC780072471F /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C260A8E8E7100BDCACE /* unzip.cpp */; }; + 94A98F960C16FC780072471F /* ldp1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C390A8E8E9C00BDCACE /* ldp1000.cpp */; }; + 94A98F970C16FC780072471F /* ldv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C3B0A8E8E9C00BDCACE /* ldv1000.cpp */; }; + 94A98F980C16FC780072471F /* pr7820.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C3E0A8E8E9C00BDCACE /* pr7820.cpp */; }; + 94A98F990C16FC780072471F /* pr8210.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C400A8E8E9C00BDCACE /* pr8210.cpp */; }; + 94A98F9A0C16FC780072471F /* vip9500sg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C420A8E8E9C00BDCACE /* vip9500sg.cpp */; }; + 94A98F9B0C16FC780072471F /* vp380.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C440A8E8E9C00BDCACE /* vp380.cpp */; }; + 94A98F9C0C16FC780072471F /* vp931.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C460A8E8E9C00BDCACE /* vp931.cpp */; }; + 94A98F9D0C16FC780072471F /* vp932.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C480A8E8E9C00BDCACE /* vp932.cpp */; }; + 94A98F9E0C16FC780072471F /* framemod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C540A8E8EAB00BDCACE /* framemod.cpp */; }; + 94A98F9F0C16FC780072471F /* hitachi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C560A8E8EAB00BDCACE /* hitachi.cpp */; }; + 94A98FA00C16FC780072471F /* ld-v6000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C580A8E8EAB00BDCACE /* ld-v6000.cpp */; }; + 94A98FA10C16FC780072471F /* ldp-combo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5A0A8E8EAB00BDCACE /* ldp-combo.cpp */; }; + 94A98FA20C16FC780072471F /* ldp-vldp-gl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5D0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp */; }; + 94A98FA30C16FC780072471F /* ldp-vldp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C5F0A8E8EAB00BDCACE /* ldp-vldp.cpp */; }; + 94A98FA40C16FC780072471F /* ldp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C610A8E8EAB00BDCACE /* ldp.cpp */; }; + 94A98FA50C16FC780072471F /* philips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C640A8E8EAB00BDCACE /* philips.cpp */; }; + 94A98FA60C16FC780072471F /* pioneer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C660A8E8EAB00BDCACE /* pioneer.cpp */; }; + 94A98FA70C16FC780072471F /* sony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C680A8E8EAB00BDCACE /* sony.cpp */; }; + 94A98FA80C16FC780072471F /* dac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C770A8E8EBF00BDCACE /* dac.cpp */; }; + 94A98FA90C16FC780072471F /* gisound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C790A8E8EBF00BDCACE /* gisound.cpp */; }; + 94A98FAA0C16FC780072471F /* pc_beeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C7C0A8E8EBF00BDCACE /* pc_beeper.cpp */; }; + 94A98FAB0C16FC780072471F /* sn_intf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C7E0A8E8EBF00BDCACE /* sn_intf.cpp */; }; + 94A98FAC0C16FC780072471F /* sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C800A8E8EBF00BDCACE /* sound.cpp */; }; + 94A98FAD0C16FC780072471F /* ssi263.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C820A8E8EBF00BDCACE /* ssi263.cpp */; }; + 94A98FAE0C16FC780072471F /* tms9919-sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C840A8E8EBF00BDCACE /* tms9919-sdl.cpp */; }; + 94A98FAF0C16FC780072471F /* tms9919.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C860A8E8EBF00BDCACE /* tms9919.cpp */; }; + 94A98FB00C16FC780072471F /* tonegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C880A8E8EBF00BDCACE /* tonegen.cpp */; }; + 94A98FB10C16FC780072471F /* tqsynth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C8A0A8E8EBF00BDCACE /* tqsynth.cpp */; }; + 94A98FB20C16FC780072471F /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C990A8E8EE200BDCACE /* timer.cpp */; }; + 94A98FB30C16FC780072471F /* blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936C9C0A8E8EE200BDCACE /* blend.cpp */; }; + 94A98FB40C16FC780072471F /* led.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA00A8E8EE200BDCACE /* led.cpp */; }; + 94A98FB50C16FC780072471F /* palette.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA40A8E8EE200BDCACE /* palette.cpp */; }; + 94A98FB60C16FC780072471F /* rgb2yuv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CA80A8E8EE200BDCACE /* rgb2yuv.cpp */; }; + 94A98FB80C16FC780072471F /* SDL_Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CAC0A8E8EE200BDCACE /* SDL_Console.cpp */; }; + 94A98FB90C16FC780072471F /* SDL_ConsoleCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CAE0A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp */; }; + 94A98FBA0C16FC780072471F /* SDL_DrawText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB00A8E8EE200BDCACE /* SDL_DrawText.cpp */; }; + 94A98FBB0C16FC780072471F /* tms9128nl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB30A8E8EE200BDCACE /* tms9128nl.cpp */; }; + 94A98FBC0C16FC780072471F /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB50A8E8EE200BDCACE /* video.cpp */; }; + 94A98FBD0C16FC780072471F /* yuv2rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = 94936CB70A8E8EE200BDCACE /* yuv2rgb.c */; }; + 94A98FBE0C16FC780072471F /* i86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936DE40A8E99C300BDCACE /* i86.cpp */; }; + 94A98FBF0C16FC780072471F /* i86dasm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94936DE60A8E99C300BDCACE /* i86dasm.cpp */; }; + 94A98FC00C16FC780072471F /* video_out.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488582E0A8FE2FB000B5138 /* video_out.c */; }; + 94A98FC10C16FC780072471F /* video_out_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858320A8FE2FB000B5138 /* video_out_sdl.c */; }; + 94A98FC20C16FC780072471F /* yuv2rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858340A8FE2FB000B5138 /* yuv2rgb.c */; }; + 94A98FC30C16FC780072471F /* yuv2rgb_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858350A8FE2FB000B5138 /* yuv2rgb_mlib.c */; }; + 94A98FC50C16FC780072471F /* mpegscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858BD0A8FE345000B5138 /* mpegscan.c */; }; + 94A98FC60C16FC780072471F /* vldp.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858BF0A8FE345000B5138 /* vldp.c */; }; + 94A98FC70C16FC780072471F /* vldp_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = 948858C20A8FE345000B5138 /* vldp_internal.c */; }; + 94A98FC80C16FC780072471F /* alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859160A8FE5D5000B5138 /* alloc.c */; }; + 94A98FC90C16FC780072471F /* cpu_accel.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859180A8FE5D5000B5138 /* cpu_accel.c */; }; + 94A98FCA0C16FC780072471F /* cpu_state.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859190A8FE5D5000B5138 /* cpu_state.c */; }; + 94A98FCB0C16FC780072471F /* decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591A0A8FE5D5000B5138 /* decode.c */; }; + 94A98FCC0C16FC780072471F /* header.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591B0A8FE5D5000B5138 /* header.c */; }; + 94A98FCD0C16FC780072471F /* idct.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591C0A8FE5D5000B5138 /* idct.c */; }; + 94A98FCE0C16FC780072471F /* idct_alpha.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591D0A8FE5D5000B5138 /* idct_alpha.c */; }; + 94A98FCF0C16FC780072471F /* idct_altivec.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591E0A8FE5D5000B5138 /* idct_altivec.c */; }; + 94A98FD00C16FC780072471F /* idct_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488591F0A8FE5D5000B5138 /* idct_mlib.c */; }; + 94A98FD10C16FC780072471F /* idct_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859200A8FE5D5000B5138 /* idct_mmx.c */; }; + 94A98FD20C16FC780072471F /* motion_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859260A8FE5D5000B5138 /* motion_comp.c */; }; + 94A98FD30C16FC780072471F /* motion_comp_alpha.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859270A8FE5D5000B5138 /* motion_comp_alpha.c */; }; + 94A98FD40C16FC780072471F /* motion_comp_altivec.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859280A8FE5D5000B5138 /* motion_comp_altivec.c */; }; + 94A98FD50C16FC780072471F /* motion_comp_mlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 948859290A8FE5D5000B5138 /* motion_comp_mlib.c */; }; + 94A98FD60C16FC780072471F /* motion_comp_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488592A0A8FE5D5000B5138 /* motion_comp_mmx.c */; }; + 94A98FD70C16FC780072471F /* slice.c in Sources */ = {isa = PBXBuildFile; fileRef = 9488592C0A8FE5D5000B5138 /* slice.c */; }; + 94A98FD80C16FC780072471F /* ldp-vldp-audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94885A650A8FF28A000B5138 /* ldp-vldp-audio.cpp */; }; + 94A98FD90C16FC780072471F /* video_out_dx.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1C90A9106C900F8A711 /* video_out_dx.c */; }; + 94A98FDA0C16FC780072471F /* video_out_null.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CA0A9106C900F8A711 /* video_out_null.c */; }; + 94A98FDB0C16FC780072471F /* video_out_pgm.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CB0A9106C900F8A711 /* video_out_pgm.c */; }; + 94A98FDC0C16FC780072471F /* video_out_x11.c in Sources */ = {isa = PBXBuildFile; fileRef = 9414C1CC0A9106C900F8A711 /* video_out_x11.c */; }; + 94A98FDD0C16FC780072471F /* samples.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94E91AED0B23463200B51FA6 /* samples.cpp */; }; + 94A98FDE0C16FC780072471F /* mix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9453E3350C10C64E000EFDC2 /* mix.cpp */; }; + 94A98FE00C16FC780072471F /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B7E0A90072F006FD484 /* Ogg.framework */; }; + 94A98FE10C16FC780072471F /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B800A90072F006FD484 /* SDL.framework */; }; + 94A98FE20C16FC780072471F /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B810A90072F006FD484 /* Vorbis.framework */; }; + 94A98FE40C16FC780072471F /* ConsoleFont.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856260A8FDE14000B5138 /* ConsoleFont.bmp */; }; + 94A98FE50C16FC780072471F /* credits.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856270A8FDE14000B5138 /* credits.bmp */; }; + 94A98FE60C16FC780072471F /* gamenowook.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856280A8FDE14000B5138 /* gamenowook.bmp */; }; + 94A98FE70C16FC780072471F /* ldp1450font.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856290A8FDE14000B5138 /* ldp1450font.bmp */; }; + 94A98FE80C16FC780072471F /* led0.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562A0A8FDE14000B5138 /* led0.bmp */; }; + 94A98FE90C16FC780072471F /* led1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562B0A8FDE14000B5138 /* led1.bmp */; }; + 94A98FEA0C16FC780072471F /* led10.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562C0A8FDE14000B5138 /* led10.bmp */; }; + 94A98FEB0C16FC780072471F /* led11.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562D0A8FDE14000B5138 /* led11.bmp */; }; + 94A98FEC0C16FC780072471F /* led12.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562E0A8FDE14000B5138 /* led12.bmp */; }; + 94A98FED0C16FC780072471F /* led13.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488562F0A8FDE14000B5138 /* led13.bmp */; }; + 94A98FEE0C16FC780072471F /* led14.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856300A8FDE14000B5138 /* led14.bmp */; }; + 94A98FEF0C16FC780072471F /* led15.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856310A8FDE14000B5138 /* led15.bmp */; }; + 94A98FF00C16FC780072471F /* led16.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856320A8FDE14000B5138 /* led16.bmp */; }; + 94A98FF10C16FC780072471F /* led2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856330A8FDE14000B5138 /* led2.bmp */; }; + 94A98FF20C16FC780072471F /* led3.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856340A8FDE14000B5138 /* led3.bmp */; }; + 94A98FF30C16FC780072471F /* led4.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856350A8FDE14000B5138 /* led4.bmp */; }; + 94A98FF40C16FC780072471F /* led5.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856360A8FDE14000B5138 /* led5.bmp */; }; + 94A98FF50C16FC780072471F /* led6.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856370A8FDE14000B5138 /* led6.bmp */; }; + 94A98FF60C16FC780072471F /* led7.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856380A8FDE14000B5138 /* led7.bmp */; }; + 94A98FF70C16FC780072471F /* led8.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856390A8FDE14000B5138 /* led8.bmp */; }; + 94A98FF80C16FC780072471F /* led9.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563A0A8FDE14000B5138 /* led9.bmp */; }; + 94A98FF90C16FC780072471F /* lives.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563B0A8FDE14000B5138 /* lives.bmp */; }; + 94A98FFA0C16FC780072471F /* overlayleds1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563E0A8FDE14000B5138 /* overlayleds1.bmp */; }; + 94A98FFB0C16FC780072471F /* overlayleds2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488563F0A8FDE14000B5138 /* overlayleds2.bmp */; }; + 94A98FFC0C16FC780072471F /* player1.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856400A8FDE14000B5138 /* player1.bmp */; }; + 94A98FFD0C16FC780072471F /* player2.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856410A8FDE14000B5138 /* player2.bmp */; }; + 94A98FFE0C16FC780072471F /* saveme.bmp in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948856420A8FDE14000B5138 /* saveme.bmp */; }; + 94A98FFF0C16FC780072471F /* convert_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858290A8FE2FB000B5138 /* convert_internal.h */; }; + 94A990000C16FC780072471F /* hw_bes.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488582A0A8FE2FB000B5138 /* hw_bes.h */; }; + 94A990010C16FC780072471F /* alpha_asm.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858500A8FE316000B5138 /* alpha_asm.h */; }; + 94A990020C16FC780072471F /* attributes.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858510A8FE316000B5138 /* attributes.h */; }; + 94A990030C16FC780072471F /* convert.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858540A8FE316000B5138 /* convert.h */; }; + 94A990040C16FC780072471F /* mmx.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858580A8FE316000B5138 /* mmx.h */; }; + 94A990050C16FC780072471F /* mpeg2.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858590A8FE316000B5138 /* mpeg2.h */; }; + 94A990060C16FC780072471F /* tendra.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488585B0A8FE316000B5138 /* tendra.h */; }; + 94A990070C16FC780072471F /* video_out.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488585C0A8FE316000B5138 /* video_out.h */; }; + 94A990080C16FC780072471F /* mpegscan.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858BE0A8FE345000B5138 /* mpegscan.h */; }; + 94A990090C16FC780072471F /* vldp.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C00A8FE345000B5138 /* vldp.h */; }; + 94A9900A0C16FC780072471F /* vldp_common.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C10A8FE345000B5138 /* vldp_common.h */; }; + 94A9900B0C16FC780072471F /* vldp_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 948858C30A8FE345000B5138 /* vldp_internal.h */; }; + 94A9900C0C16FC780072471F /* mpeg2_internal.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488592B0A8FE5D5000B5138 /* mpeg2_internal.h */; }; + 94A9900D0C16FC780072471F /* vlc.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9488592D0A8FE5D5000B5138 /* vlc.h */; }; + 94A9900E0C16FC780072471F /* config.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9414C1B50A9104C800F8A711 /* config.h */; }; + 94A9900F0C16FC780072471F /* samples.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94E91AEE0B23463200B51FA6 /* samples.h */; }; + 94A990100C16FC780072471F /* mix.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 9453E3360C10C64E000EFDC2 /* mix.h */; }; + 94A990120C16FC780072471F /* ab_alarm1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856440A8FDE2D000B5138 /* ab_alarm1.wav */; }; + 94A990130C16FC780072471F /* ab_alarm2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856450A8FDE2D000B5138 /* ab_alarm2.wav */; }; + 94A990140C16FC780072471F /* ab_alarm3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856460A8FDE2D000B5138 /* ab_alarm3.wav */; }; + 94A990150C16FC780072471F /* ab_alarm4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856470A8FDE2D000B5138 /* ab_alarm4.wav */; }; + 94A990160C16FC780072471F /* ab_enemy.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856480A8FDE2D000B5138 /* ab_enemy.wav */; }; + 94A990170C16FC780072471F /* ab_fire.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856490A8FDE2D000B5138 /* ab_fire.wav */; }; + 94A990180C16FC780072471F /* ab_ship.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564A0A8FDE2D000B5138 /* ab_ship.wav */; }; + 94A990190C16FC780072471F /* bl_shot.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564B0A8FDE2D000B5138 /* bl_shot.wav */; }; + 94A9901A0C16FC780072471F /* cliff_correct.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564C0A8FDE2D000B5138 /* cliff_correct.wav */; }; + 94A9901B0C16FC780072471F /* cliff_startup.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564D0A8FDE2D000B5138 /* cliff_startup.wav */; }; + 94A9901C0C16FC780072471F /* cliff_wrong.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564E0A8FDE2D000B5138 /* cliff_wrong.wav */; }; + 94A9901D0C16FC780072471F /* dl2_bad.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488564F0A8FDE2D000B5138 /* dl2_bad.wav */; }; + 94A9901E0C16FC780072471F /* dl2_coin1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856500A8FDE2D000B5138 /* dl2_coin1.wav */; }; + 94A9901F0C16FC780072471F /* dl2_coin2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856510A8FDE2D000B5138 /* dl2_coin2.wav */; }; + 94A990200C16FC780072471F /* dl2_coin3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856520A8FDE2D000B5138 /* dl2_coin3.wav */; }; + 94A990210C16FC780072471F /* dl2_coin4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856530A8FDE2D000B5138 /* dl2_coin4.wav */; }; + 94A990220C16FC780072471F /* dl2_error.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856540A8FDE2D000B5138 /* dl2_error.wav */; }; + 94A990230C16FC780072471F /* dl2_good.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856550A8FDE2D000B5138 /* dl2_good.wav */; }; + 94A990240C16FC780072471F /* dl2_tic.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856560A8FDE2D000B5138 /* dl2_tic.wav */; }; + 94A990250C16FC780072471F /* dl2_toc.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856570A8FDE2D000B5138 /* dl2_toc.wav */; }; + 94A990260C16FC780072471F /* dl2_warble.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856580A8FDE2D000B5138 /* dl2_warble.wav */; }; + 94A990270C16FC780072471F /* dl2_warn.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856590A8FDE2D000B5138 /* dl2_warn.wav */; }; + 94A990280C16FC780072471F /* dl_accept.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565A0A8FDE2D000B5138 /* dl_accept.wav */; }; + 94A990290C16FC780072471F /* dl_buzz.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565B0A8FDE2D000B5138 /* dl_buzz.wav */; }; + 94A9902A0C16FC780072471F /* dl_credit.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565C0A8FDE2D000B5138 /* dl_credit.wav */; }; + 94A9902B0C16FC780072471F /* esh_beep.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565D0A8FDE2D000B5138 /* esh_beep.wav */; }; + 94A9902C0C16FC780072471F /* gr_alarm1.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565E0A8FDE2D000B5138 /* gr_alarm1.wav */; }; + 94A9902D0C16FC780072471F /* gr_alarm2.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488565F0A8FDE2D000B5138 /* gr_alarm2.wav */; }; + 94A9902E0C16FC780072471F /* gr_alarm3.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856600A8FDE2D000B5138 /* gr_alarm3.wav */; }; + 94A9902F0C16FC780072471F /* gr_alarm4.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856610A8FDE2D000B5138 /* gr_alarm4.wav */; }; + 94A990300C16FC780072471F /* gr_attack.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856620A8FDE2D000B5138 /* gr_attack.wav */; }; + 94A990310C16FC780072471F /* gr_cannon.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856630A8FDE2D000B5138 /* gr_cannon.wav */; }; + 94A990320C16FC780072471F /* gr_fire.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856640A8FDE2D000B5138 /* gr_fire.wav */; }; + 94A990330C16FC780072471F /* gr_mineon.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856650A8FDE2D000B5138 /* gr_mineon.wav */; }; + 94A990340C16FC780072471F /* mach3-01.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856660A8FDE2D000B5138 /* mach3-01.ogg */; }; + 94A990350C16FC780072471F /* mach3-02.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856670A8FDE2D000B5138 /* mach3-02.ogg */; }; + 94A990360C16FC780072471F /* mach3-03.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856680A8FDE2D000B5138 /* mach3-03.ogg */; }; + 94A990370C16FC780072471F /* mach3-04.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856690A8FDE2D000B5138 /* mach3-04.ogg */; }; + 94A990380C16FC780072471F /* mach3-05.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566A0A8FDE2D000B5138 /* mach3-05.ogg */; }; + 94A990390C16FC780072471F /* mach3-06.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566B0A8FDE2D000B5138 /* mach3-06.ogg */; }; + 94A9903A0C16FC780072471F /* mach3-07.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566C0A8FDE2D000B5138 /* mach3-07.ogg */; }; + 94A9903B0C16FC780072471F /* mach3-08.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566D0A8FDE2D000B5138 /* mach3-08.ogg */; }; + 94A9903C0C16FC780072471F /* mach3-09.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566E0A8FDE2D000B5138 /* mach3-09.ogg */; }; + 94A9903D0C16FC780072471F /* mach3-11.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488566F0A8FDE2D000B5138 /* mach3-11.ogg */; }; + 94A9903E0C16FC780072471F /* mach3-13.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856700A8FDE2D000B5138 /* mach3-13.ogg */; }; + 94A9903F0C16FC780072471F /* mach3-15.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856710A8FDE2D000B5138 /* mach3-15.ogg */; }; + 94A990400C16FC780072471F /* mach3-19.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856720A8FDE2D000B5138 /* mach3-19.ogg */; }; + 94A990410C16FC780072471F /* mach3-20.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856730A8FDE2D000B5138 /* mach3-20.ogg */; }; + 94A990420C16FC780072471F /* mach3-22.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856740A8FDE2D000B5138 /* mach3-22.ogg */; }; + 94A990430C16FC780072471F /* mach3-33.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856750A8FDE2D000B5138 /* mach3-33.ogg */; }; + 94A990440C16FC780072471F /* mach3-34.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856760A8FDE2D000B5138 /* mach3-34.ogg */; }; + 94A990450C16FC780072471F /* mach3-35.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856770A8FDE2D000B5138 /* mach3-35.ogg */; }; + 94A990460C16FC780072471F /* mach3-36.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856780A8FDE2D000B5138 /* mach3-36.ogg */; }; + 94A990470C16FC780072471F /* mach3-37.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856790A8FDE2D000B5138 /* mach3-37.ogg */; }; + 94A990480C16FC780072471F /* mach3-39.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567A0A8FDE2D000B5138 /* mach3-39.ogg */; }; + 94A990490C16FC780072471F /* mach3-40.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567B0A8FDE2D000B5138 /* mach3-40.ogg */; }; + 94A9904A0C16FC780072471F /* mach3-41.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567C0A8FDE2D000B5138 /* mach3-41.ogg */; }; + 94A9904B0C16FC780072471F /* mach3-42.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567D0A8FDE2D000B5138 /* mach3-42.ogg */; }; + 94A9904C0C16FC780072471F /* mach3-43.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567E0A8FDE2D000B5138 /* mach3-43.ogg */; }; + 94A9904D0C16FC780072471F /* mach3-45.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 9488567F0A8FDE2D000B5138 /* mach3-45.ogg */; }; + 94A9904E0C16FC780072471F /* mach3-49.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856800A8FDE2D000B5138 /* mach3-49.ogg */; }; + 94A9904F0C16FC780072471F /* mach3-null.ogg in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856810A8FDE2D000B5138 /* mach3-null.ogg */; }; + 94A990500C16FC780072471F /* saveme.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856820A8FDE2D000B5138 /* saveme.wav */; }; + 94A990510C16FC780072471F /* sd_coin.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856830A8FDE2D000B5138 /* sd_coin.wav */; }; + 94A990520C16FC780072471F /* sd_fail.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856840A8FDE2D000B5138 /* sd_fail.wav */; }; + 94A990530C16FC780072471F /* sd_succeed.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856850A8FDE2D000B5138 /* sd_succeed.wav */; }; + 94A990540C16FC780072471F /* sda_success_hi.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856860A8FDE2D000B5138 /* sda_success_hi.wav */; }; + 94A990550C16FC780072471F /* sda_success_lo.wav in Copy Sounds */ = {isa = PBXBuildFile; fileRef = 948856870A8FDE2D000B5138 /* sda_success_lo.wav */; }; + 94A990570C16FC780072471F /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B7E0A90072F006FD484 /* Ogg.framework */; }; + 94A990580C16FC780072471F /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B800A90072F006FD484 /* SDL.framework */; }; + 94A990590C16FC780072471F /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94465B810A90072F006FD484 /* Vorbis.framework */; }; + 94A9905B0C16FC780072471F /* DaphneManifest.xml in Copy Manifest */ = {isa = PBXBuildFile; fileRef = 94F97A390B39B16300F29536 /* DaphneManifest.xml */; }; + 94A990620C16FC8D0072471F /* lapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE00C16FBA40072471F /* lapi.c */; }; + 94A990630C16FC8D0072471F /* lapi.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EE10C16FBA40072471F /* lapi.h */; }; + 94A990640C16FC8D0072471F /* lauxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE20C16FBA40072471F /* lauxlib.c */; }; + 94A990650C16FC8D0072471F /* lauxlib.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EE30C16FBA40072471F /* lauxlib.h */; }; + 94A990660C16FC8D0072471F /* lbaselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE40C16FBA40072471F /* lbaselib.c */; }; + 94A990670C16FC8D0072471F /* lcode.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE50C16FBA40072471F /* lcode.c */; }; + 94A990680C16FC8D0072471F /* lcode.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EE60C16FBA40072471F /* lcode.h */; }; + 94A990690C16FC8D0072471F /* ldblib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE70C16FBA40072471F /* ldblib.c */; }; + 94A9906A0C16FC8D0072471F /* ldebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EE80C16FBA40072471F /* ldebug.c */; }; + 94A9906B0C16FC8D0072471F /* ldebug.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EE90C16FBA40072471F /* ldebug.h */; }; + 94A9906C0C16FC8D0072471F /* ldo.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EEA0C16FBA40072471F /* ldo.c */; }; + 94A9906D0C16FC8D0072471F /* ldo.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EEB0C16FBA40072471F /* ldo.h */; }; + 94A9906E0C16FC8D0072471F /* ldump.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EEC0C16FBA40072471F /* ldump.c */; }; + 94A9906F0C16FC8D0072471F /* lfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EED0C16FBA40072471F /* lfunc.c */; }; + 94A990700C16FC8D0072471F /* lfunc.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EEE0C16FBA40072471F /* lfunc.h */; }; + 94A990710C16FC8D0072471F /* lgc.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EEF0C16FBA40072471F /* lgc.c */; }; + 94A990720C16FC8D0072471F /* lgc.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EF00C16FBA40072471F /* lgc.h */; }; + 94A990730C16FC8D0072471F /* linit.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF10C16FBA40072471F /* linit.c */; }; + 94A990740C16FC8D0072471F /* liolib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF20C16FBA40072471F /* liolib.c */; }; + 94A990750C16FC8D0072471F /* llex.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF30C16FBA40072471F /* llex.c */; }; + 94A990760C16FC8D0072471F /* llex.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EF40C16FBA40072471F /* llex.h */; }; + 94A990770C16FC8D0072471F /* llimits.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EF50C16FBA40072471F /* llimits.h */; }; + 94A990780C16FC8D0072471F /* lmathlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF60C16FBA40072471F /* lmathlib.c */; }; + 94A990790C16FC8D0072471F /* lmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF70C16FBA40072471F /* lmem.c */; }; + 94A9907A0C16FC8D0072471F /* lmem.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EF80C16FBA40072471F /* lmem.h */; }; + 94A9907B0C16FC8D0072471F /* loadlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EF90C16FBA40072471F /* loadlib.c */; }; + 94A9907C0C16FC8D0072471F /* lobject.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EFA0C16FBA40072471F /* lobject.c */; }; + 94A9907D0C16FC8D0072471F /* lobject.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EFB0C16FBA40072471F /* lobject.h */; }; + 94A9907E0C16FC8D0072471F /* lopcodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EFC0C16FBA40072471F /* lopcodes.c */; }; + 94A9907F0C16FC8D0072471F /* lopcodes.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EFD0C16FBA40072471F /* lopcodes.h */; }; + 94A990800C16FC8D0072471F /* loslib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EFE0C16FBA40072471F /* loslib.c */; }; + 94A990810C16FC8D0072471F /* lparser.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EFF0C16FBA40072471F /* lparser.c */; }; + 94A990820C16FC8D0072471F /* lparser.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F000C16FBA40072471F /* lparser.h */; }; + 94A990830C16FC8D0072471F /* lstate.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F010C16FBA40072471F /* lstate.c */; }; + 94A990840C16FC8D0072471F /* lstate.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F020C16FBA40072471F /* lstate.h */; }; + 94A990850C16FC8D0072471F /* lstring.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F030C16FBA40072471F /* lstring.c */; }; + 94A990860C16FC8D0072471F /* lstring.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F040C16FBA40072471F /* lstring.h */; }; + 94A990870C16FC8D0072471F /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F050C16FBA40072471F /* lstrlib.c */; }; + 94A990880C16FC8D0072471F /* ltable.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F060C16FBA40072471F /* ltable.c */; }; + 94A990890C16FC8D0072471F /* ltable.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F070C16FBA40072471F /* ltable.h */; }; + 94A9908A0C16FC8D0072471F /* ltablib.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F080C16FBA40072471F /* ltablib.c */; }; + 94A9908B0C16FC8D0072471F /* ltm.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F090C16FBA40072471F /* ltm.c */; }; + 94A9908C0C16FC8D0072471F /* ltm.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F0A0C16FBA40072471F /* ltm.h */; }; + 94A9908D0C16FC8D0072471F /* lua.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F0B0C16FBA40072471F /* lua.h */; }; + 94A9908E0C16FC8D0072471F /* luaconf.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F0C0C16FBA40072471F /* luaconf.h */; }; + 94A9908F0C16FC8D0072471F /* lualib.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F0D0C16FBA40072471F /* lualib.h */; }; + 94A990900C16FC8D0072471F /* lundump.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F0E0C16FBA40072471F /* lundump.c */; }; + 94A990910C16FC8D0072471F /* lundump.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F0F0C16FBA40072471F /* lundump.h */; }; + 94A990920C16FC8D0072471F /* lvm.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F100C16FBA40072471F /* lvm.c */; }; + 94A990930C16FC8D0072471F /* lvm.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F110C16FBA40072471F /* lvm.h */; }; + 94A990940C16FC8D0072471F /* lzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F120C16FBA40072471F /* lzio.c */; }; + 94A990950C16FC8D0072471F /* lzio.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F130C16FBA40072471F /* lzio.h */; }; + 94A990960C16FC8D0072471F /* print.c in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F140C16FBA40072471F /* print.c */; }; + 94A990970C16FC8D0072471F /* singe_interface.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F150C16FBA40072471F /* singe_interface.h */; }; + 94A990980C16FC8D0072471F /* singeproxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A98F160C16FBA40072471F /* singeproxy.cpp */; }; + 94A990990C16FC8D0072471F /* singeproxy.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98F170C16FBA40072471F /* singeproxy.h */; }; + 94A9909A0C16FC8D0072471F /* singe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A98EDC0C16FB8E0072471F /* singe.cpp */; }; + 94A9909B0C16FC8D0072471F /* singe.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94A98EDD0C16FB8E0072471F /* singe.h */; }; + 94A990FA0C16FF870072471F /* SDL_image.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94A990F00C16FF870072471F /* SDL_image.framework */; }; + 94A990FB0C16FF870072471F /* SDL_ttf.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94A990F10C16FF870072471F /* SDL_ttf.framework */; }; + 94A991060C16FFF50072471F /* SDL_image.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 94A990F00C16FF870072471F /* SDL_image.framework */; }; + 94A991070C16FFFD0072471F /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94A990F10C16FF870072471F /* SDL_ttf.framework */; }; + 94AD92680AA00B7000C9CDC4 /* Daphne Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 94AD92670AA00B7000C9CDC4 /* Daphne Icon.icns */; }; + 94B1CF780CB56E5B00A2DB19 /* daphne-changelog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 94B1CF770CB56E5B00A2DB19 /* daphne-changelog.txt */; }; + 94B1CF790CB56E5B00A2DB19 /* daphne-changelog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 94B1CF770CB56E5B00A2DB19 /* daphne-changelog.txt */; }; + 94B1CF7A0CB56E6000A2DB19 /* daphne-changelog.txt in Copy Manifest */ = {isa = PBXBuildFile; fileRef = 94B1CF770CB56E5B00A2DB19 /* daphne-changelog.txt */; }; + 94E91AEF0B23463200B51FA6 /* samples.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94E91AED0B23463200B51FA6 /* samples.cpp */; }; + 94E91AF00B23463200B51FA6 /* samples.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94E91AEE0B23463200B51FA6 /* samples.h */; }; + 94F97A3A0B39B16300F29536 /* DaphneManifest.xml in Resources */ = {isa = PBXBuildFile; fileRef = 94F97A390B39B16300F29536 /* DaphneManifest.xml */; }; + 94F97A5A0B39B2B200F29536 /* DaphneManifest.xml in Copy Manifest */ = {isa = PBXBuildFile; fileRef = 94F97A390B39B16300F29536 /* DaphneManifest.xml */; }; + 94FD7FFB0CBA97FC0023EF96 /* mmxdefs.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94FD7FFA0CBA97FC0023EF96 /* mmxdefs.h */; }; + 94FD7FFC0CBA97FC0023EF96 /* mmxdefs.h in Copy Bitmaps */ = {isa = PBXBuildFile; fileRef = 94FD7FFA0CBA97FC0023EF96 /* mmxdefs.h */; }; + 94FD806A0CBA9ACF0023EF96 /* mix_mmx-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD80680CBA9ACF0023EF96 /* mix_mmx-gas.s */; }; + 94FD806D0CBA9AE00023EF96 /* rgb2yuv-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD806B0CBA9AE00023EF96 /* rgb2yuv-gas.s */; }; + 94FD80F60CBA9DDA0023EF96 /* blend_mmx-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD80F40CBA9DDA0023EF96 /* blend_mmx-gas.s */; }; + 94FD81240CBAA10A0023EF96 /* blend_mmx-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD80F40CBA9DDA0023EF96 /* blend_mmx-gas.s */; }; + 94FD81250CBAA10A0023EF96 /* rgb2yuv-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD806B0CBA9AE00023EF96 /* rgb2yuv-gas.s */; }; + 94FD81260CBAA10A0023EF96 /* mix_mmx-gas.s in Sources */ = {isa = PBXBuildFile; fileRef = 94FD80680CBA9ACF0023EF96 /* mix_mmx-gas.s */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildRule section */ + 94E82BC70CBAAFB000B799C1 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.proxy.script; + fileType = sourcecode.asm; + isEditable = 1; + outputFiles = ( + "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o", + ); + script = "as ${INPUT_FILE_PATH} -o ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o"; + }; + 94FD81FD0CBAA7860023EF96 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc; + filePatterns = "*.foo"; + fileType = sourcecode.asm.asm; + isEditable = 1; + outputFiles = ( + ); + script = "as ${INPUT_FILE_PATH} -o ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.o"; + }; +/* End PBXBuildRule section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 94465B7B0A900708006FD484 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 943DBEEE0CBB49CD00525DD9 /* GLExtensionWrangler.framework in Copy Frameworks */, + 94465BBF0A90074C006FD484 /* Ogg.framework in Copy Frameworks */, + 94465BC10A90074C006FD484 /* SDL.framework in Copy Frameworks */, + 94465BC20A90074C006FD484 /* Vorbis.framework in Copy Frameworks */, + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94862D5E0A8EB56000AA9A46 /* Copy Bitmaps */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = pics; + dstSubfolderSpec = 6; + files = ( + 948856880A8FDE65000B5138 /* ConsoleFont.bmp in Copy Bitmaps */, + 948856890A8FDE65000B5138 /* credits.bmp in Copy Bitmaps */, + 9488568A0A8FDE65000B5138 /* gamenowook.bmp in Copy Bitmaps */, + 9488568B0A8FDE65000B5138 /* ldp1450font.bmp in Copy Bitmaps */, + 9488568C0A8FDE65000B5138 /* led0.bmp in Copy Bitmaps */, + 9488568D0A8FDE65000B5138 /* led1.bmp in Copy Bitmaps */, + 9488568E0A8FDE65000B5138 /* led10.bmp in Copy Bitmaps */, + 9488568F0A8FDE65000B5138 /* led11.bmp in Copy Bitmaps */, + 948856900A8FDE65000B5138 /* led12.bmp in Copy Bitmaps */, + 948856910A8FDE65000B5138 /* led13.bmp in Copy Bitmaps */, + 948856920A8FDE65000B5138 /* led14.bmp in Copy Bitmaps */, + 948856930A8FDE65000B5138 /* led15.bmp in Copy Bitmaps */, + 948856940A8FDE65000B5138 /* led16.bmp in Copy Bitmaps */, + 948856950A8FDE65000B5138 /* led2.bmp in Copy Bitmaps */, + 948856960A8FDE65000B5138 /* led3.bmp in Copy Bitmaps */, + 948856970A8FDE65000B5138 /* led4.bmp in Copy Bitmaps */, + 948856980A8FDE65000B5138 /* led5.bmp in Copy Bitmaps */, + 948856990A8FDE65000B5138 /* led6.bmp in Copy Bitmaps */, + 9488569A0A8FDE65000B5138 /* led7.bmp in Copy Bitmaps */, + 9488569B0A8FDE65000B5138 /* led8.bmp in Copy Bitmaps */, + 9488569C0A8FDE65000B5138 /* led9.bmp in Copy Bitmaps */, + 9488569D0A8FDE65000B5138 /* lives.bmp in Copy Bitmaps */, + 9488569E0A8FDE65000B5138 /* overlayleds1.bmp in Copy Bitmaps */, + 9488569F0A8FDE65000B5138 /* overlayleds2.bmp in Copy Bitmaps */, + 948856A00A8FDE65000B5138 /* player1.bmp in Copy Bitmaps */, + 948856A10A8FDE65000B5138 /* player2.bmp in Copy Bitmaps */, + 948856A20A8FDE65000B5138 /* saveme.bmp in Copy Bitmaps */, + 948858410A8FE2FC000B5138 /* convert_internal.h in Copy Bitmaps */, + 948858420A8FE2FC000B5138 /* hw_bes.h in Copy Bitmaps */, + 9488585D0A8FE316000B5138 /* alpha_asm.h in Copy Bitmaps */, + 9488585E0A8FE316000B5138 /* attributes.h in Copy Bitmaps */, + 948858610A8FE316000B5138 /* convert.h in Copy Bitmaps */, + 948858650A8FE316000B5138 /* mmx.h in Copy Bitmaps */, + 948858660A8FE316000B5138 /* mpeg2.h in Copy Bitmaps */, + 948858680A8FE316000B5138 /* tendra.h in Copy Bitmaps */, + 948858690A8FE316000B5138 /* video_out.h in Copy Bitmaps */, + 948858C50A8FE345000B5138 /* mpegscan.h in Copy Bitmaps */, + 948858C70A8FE345000B5138 /* vldp.h in Copy Bitmaps */, + 948858C80A8FE345000B5138 /* vldp_common.h in Copy Bitmaps */, + 948858CA0A8FE345000B5138 /* vldp_internal.h in Copy Bitmaps */, + 948859530A8FE5D5000B5138 /* mpeg2_internal.h in Copy Bitmaps */, + 948859550A8FE5D5000B5138 /* vlc.h in Copy Bitmaps */, + 9414C1B60A9104C800F8A711 /* config.h in Copy Bitmaps */, + 94E91AF00B23463200B51FA6 /* samples.h in Copy Bitmaps */, + 9453E3380C10C64E000EFDC2 /* mix.h in Copy Bitmaps */, + 94A366240CADA86700667ABE /* hw_scoreboard.h in Copy Bitmaps */, + 94A366260CADA86700667ABE /* img_scoreboard.h in Copy Bitmaps */, + 94A366280CADA86700667ABE /* null_scoreboard.h in Copy Bitmaps */, + 94A3662A0CADA86700667ABE /* overlay_scoreboard.h in Copy Bitmaps */, + 94A3662C0CADA86700667ABE /* scoreboard_collection.h in Copy Bitmaps */, + 94A3662E0CADA86700667ABE /* scoreboard_factory.h in Copy Bitmaps */, + 94A366310CADA86700667ABE /* scoreboard_interface.h in Copy Bitmaps */, + 94A3665B0CADAB1900667ABE /* logger_console.h in Copy Bitmaps */, + 94A3665D0CADAB1900667ABE /* logger_factory.h in Copy Bitmaps */, + 94A3665F0CADAB1900667ABE /* logger.h in Copy Bitmaps */, + 94A366930CADAC7000667ABE /* test_sb.h in Copy Bitmaps */, + 94FD7FFB0CBA97FC0023EF96 /* mmxdefs.h in Copy Bitmaps */, + ); + name = "Copy Bitmaps"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94862DCD0A8EB78300AA9A46 /* Copy Sounds */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = sound; + dstSubfolderSpec = 6; + files = ( + 948856A30A8FDE71000B5138 /* ab_alarm1.wav in Copy Sounds */, + 948856A40A8FDE71000B5138 /* ab_alarm2.wav in Copy Sounds */, + 948856A50A8FDE71000B5138 /* ab_alarm3.wav in Copy Sounds */, + 948856A60A8FDE71000B5138 /* ab_alarm4.wav in Copy Sounds */, + 948856A70A8FDE71000B5138 /* ab_enemy.wav in Copy Sounds */, + 948856A80A8FDE71000B5138 /* ab_fire.wav in Copy Sounds */, + 948856A90A8FDE71000B5138 /* ab_ship.wav in Copy Sounds */, + 948856AA0A8FDE71000B5138 /* bl_shot.wav in Copy Sounds */, + 948856AB0A8FDE71000B5138 /* cliff_correct.wav in Copy Sounds */, + 948856AC0A8FDE71000B5138 /* cliff_startup.wav in Copy Sounds */, + 948856AD0A8FDE71000B5138 /* cliff_wrong.wav in Copy Sounds */, + 948856AE0A8FDE71000B5138 /* dl2_bad.wav in Copy Sounds */, + 948856AF0A8FDE71000B5138 /* dl2_coin1.wav in Copy Sounds */, + 948856B00A8FDE71000B5138 /* dl2_coin2.wav in Copy Sounds */, + 948856B10A8FDE71000B5138 /* dl2_coin3.wav in Copy Sounds */, + 948856B20A8FDE71000B5138 /* dl2_coin4.wav in Copy Sounds */, + 948856B30A8FDE71000B5138 /* dl2_error.wav in Copy Sounds */, + 948856B40A8FDE71000B5138 /* dl2_good.wav in Copy Sounds */, + 948856B50A8FDE71000B5138 /* dl2_tic.wav in Copy Sounds */, + 948856B60A8FDE71000B5138 /* dl2_toc.wav in Copy Sounds */, + 948856B70A8FDE71000B5138 /* dl2_warble.wav in Copy Sounds */, + 948856B80A8FDE71000B5138 /* dl2_warn.wav in Copy Sounds */, + 948856B90A8FDE71000B5138 /* dl_accept.wav in Copy Sounds */, + 948856BA0A8FDE71000B5138 /* dl_buzz.wav in Copy Sounds */, + 948856BB0A8FDE71000B5138 /* dl_credit.wav in Copy Sounds */, + 948856BC0A8FDE71000B5138 /* esh_beep.wav in Copy Sounds */, + 948856BD0A8FDE71000B5138 /* gr_alarm1.wav in Copy Sounds */, + 948856BE0A8FDE71000B5138 /* gr_alarm2.wav in Copy Sounds */, + 948856BF0A8FDE71000B5138 /* gr_alarm3.wav in Copy Sounds */, + 948856C00A8FDE71000B5138 /* gr_alarm4.wav in Copy Sounds */, + 948856C10A8FDE71000B5138 /* gr_attack.wav in Copy Sounds */, + 948856C20A8FDE71000B5138 /* gr_cannon.wav in Copy Sounds */, + 948856C30A8FDE71000B5138 /* gr_fire.wav in Copy Sounds */, + 948856C40A8FDE71000B5138 /* gr_mineon.wav in Copy Sounds */, + 948856C50A8FDE71000B5138 /* mach3-01.ogg in Copy Sounds */, + 948856C60A8FDE71000B5138 /* mach3-02.ogg in Copy Sounds */, + 948856C70A8FDE71000B5138 /* mach3-03.ogg in Copy Sounds */, + 948856C80A8FDE71000B5138 /* mach3-04.ogg in Copy Sounds */, + 948856C90A8FDE71000B5138 /* mach3-05.ogg in Copy Sounds */, + 948856CA0A8FDE71000B5138 /* mach3-06.ogg in Copy Sounds */, + 948856CB0A8FDE71000B5138 /* mach3-07.ogg in Copy Sounds */, + 948856CC0A8FDE71000B5138 /* mach3-08.ogg in Copy Sounds */, + 948856CD0A8FDE71000B5138 /* mach3-09.ogg in Copy Sounds */, + 948856CE0A8FDE71000B5138 /* mach3-11.ogg in Copy Sounds */, + 948856CF0A8FDE71000B5138 /* mach3-13.ogg in Copy Sounds */, + 948856D00A8FDE71000B5138 /* mach3-15.ogg in Copy Sounds */, + 948856D10A8FDE71000B5138 /* mach3-19.ogg in Copy Sounds */, + 948856D20A8FDE71000B5138 /* mach3-20.ogg in Copy Sounds */, + 948856D30A8FDE71000B5138 /* mach3-22.ogg in Copy Sounds */, + 948856D40A8FDE71000B5138 /* mach3-33.ogg in Copy Sounds */, + 948856D50A8FDE71000B5138 /* mach3-34.ogg in Copy Sounds */, + 948856D60A8FDE71000B5138 /* mach3-35.ogg in Copy Sounds */, + 948856D70A8FDE71000B5138 /* mach3-36.ogg in Copy Sounds */, + 948856D80A8FDE71000B5138 /* mach3-37.ogg in Copy Sounds */, + 948856D90A8FDE71000B5138 /* mach3-39.ogg in Copy Sounds */, + 948856DA0A8FDE71000B5138 /* mach3-40.ogg in Copy Sounds */, + 948856DB0A8FDE71000B5138 /* mach3-41.ogg in Copy Sounds */, + 948856DC0A8FDE71000B5138 /* mach3-42.ogg in Copy Sounds */, + 948856DD0A8FDE71000B5138 /* mach3-43.ogg in Copy Sounds */, + 948856DE0A8FDE71000B5138 /* mach3-45.ogg in Copy Sounds */, + 948856DF0A8FDE71000B5138 /* mach3-49.ogg in Copy Sounds */, + 948856E00A8FDE71000B5138 /* mach3-null.ogg in Copy Sounds */, + 948856E10A8FDE71000B5138 /* saveme.wav in Copy Sounds */, + 948856E20A8FDE71000B5138 /* sd_coin.wav in Copy Sounds */, + 948856E30A8FDE71000B5138 /* sd_fail.wav in Copy Sounds */, + 948856E40A8FDE71000B5138 /* sd_succeed.wav in Copy Sounds */, + 948856E50A8FDE71000B5138 /* sda_success_hi.wav in Copy Sounds */, + 948856E60A8FDE71000B5138 /* sda_success_lo.wav in Copy Sounds */, + ); + name = "Copy Sounds"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94A98FE30C16FC780072471F /* Copy Bitmaps */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = pics; + dstSubfolderSpec = 6; + files = ( + 94A98FE40C16FC780072471F /* ConsoleFont.bmp in Copy Bitmaps */, + 94A98FE50C16FC780072471F /* credits.bmp in Copy Bitmaps */, + 94A98FE60C16FC780072471F /* gamenowook.bmp in Copy Bitmaps */, + 94A98FE70C16FC780072471F /* ldp1450font.bmp in Copy Bitmaps */, + 94A98FE80C16FC780072471F /* led0.bmp in Copy Bitmaps */, + 94A98FE90C16FC780072471F /* led1.bmp in Copy Bitmaps */, + 94A98FEA0C16FC780072471F /* led10.bmp in Copy Bitmaps */, + 94A98FEB0C16FC780072471F /* led11.bmp in Copy Bitmaps */, + 94A98FEC0C16FC780072471F /* led12.bmp in Copy Bitmaps */, + 94A98FED0C16FC780072471F /* led13.bmp in Copy Bitmaps */, + 94A98FEE0C16FC780072471F /* led14.bmp in Copy Bitmaps */, + 94A98FEF0C16FC780072471F /* led15.bmp in Copy Bitmaps */, + 94A98FF00C16FC780072471F /* led16.bmp in Copy Bitmaps */, + 94A98FF10C16FC780072471F /* led2.bmp in Copy Bitmaps */, + 94A98FF20C16FC780072471F /* led3.bmp in Copy Bitmaps */, + 94A98FF30C16FC780072471F /* led4.bmp in Copy Bitmaps */, + 94A98FF40C16FC780072471F /* led5.bmp in Copy Bitmaps */, + 94A98FF50C16FC780072471F /* led6.bmp in Copy Bitmaps */, + 94A98FF60C16FC780072471F /* led7.bmp in Copy Bitmaps */, + 94A98FF70C16FC780072471F /* led8.bmp in Copy Bitmaps */, + 94A98FF80C16FC780072471F /* led9.bmp in Copy Bitmaps */, + 94A98FF90C16FC780072471F /* lives.bmp in Copy Bitmaps */, + 94A98FFA0C16FC780072471F /* overlayleds1.bmp in Copy Bitmaps */, + 94A98FFB0C16FC780072471F /* overlayleds2.bmp in Copy Bitmaps */, + 94A98FFC0C16FC780072471F /* player1.bmp in Copy Bitmaps */, + 94A98FFD0C16FC780072471F /* player2.bmp in Copy Bitmaps */, + 94A98FFE0C16FC780072471F /* saveme.bmp in Copy Bitmaps */, + 94A98FFF0C16FC780072471F /* convert_internal.h in Copy Bitmaps */, + 94A990000C16FC780072471F /* hw_bes.h in Copy Bitmaps */, + 94A990010C16FC780072471F /* alpha_asm.h in Copy Bitmaps */, + 94A990020C16FC780072471F /* attributes.h in Copy Bitmaps */, + 94A990030C16FC780072471F /* convert.h in Copy Bitmaps */, + 94A990040C16FC780072471F /* mmx.h in Copy Bitmaps */, + 94A990050C16FC780072471F /* mpeg2.h in Copy Bitmaps */, + 94A990060C16FC780072471F /* tendra.h in Copy Bitmaps */, + 94A990070C16FC780072471F /* video_out.h in Copy Bitmaps */, + 94A990080C16FC780072471F /* mpegscan.h in Copy Bitmaps */, + 94A990090C16FC780072471F /* vldp.h in Copy Bitmaps */, + 94A9900A0C16FC780072471F /* vldp_common.h in Copy Bitmaps */, + 94A9900B0C16FC780072471F /* vldp_internal.h in Copy Bitmaps */, + 94A9900C0C16FC780072471F /* mpeg2_internal.h in Copy Bitmaps */, + 94A9900D0C16FC780072471F /* vlc.h in Copy Bitmaps */, + 94A9900E0C16FC780072471F /* config.h in Copy Bitmaps */, + 94A9900F0C16FC780072471F /* samples.h in Copy Bitmaps */, + 94A990100C16FC780072471F /* mix.h in Copy Bitmaps */, + 94A990630C16FC8D0072471F /* lapi.h in Copy Bitmaps */, + 94A990650C16FC8D0072471F /* lauxlib.h in Copy Bitmaps */, + 94A990680C16FC8D0072471F /* lcode.h in Copy Bitmaps */, + 94A9906B0C16FC8D0072471F /* ldebug.h in Copy Bitmaps */, + 94A9906D0C16FC8D0072471F /* ldo.h in Copy Bitmaps */, + 94A990700C16FC8D0072471F /* lfunc.h in Copy Bitmaps */, + 94A990720C16FC8D0072471F /* lgc.h in Copy Bitmaps */, + 94A990760C16FC8D0072471F /* llex.h in Copy Bitmaps */, + 94A990770C16FC8D0072471F /* llimits.h in Copy Bitmaps */, + 94A9907A0C16FC8D0072471F /* lmem.h in Copy Bitmaps */, + 94A9907D0C16FC8D0072471F /* lobject.h in Copy Bitmaps */, + 94A9907F0C16FC8D0072471F /* lopcodes.h in Copy Bitmaps */, + 94A990820C16FC8D0072471F /* lparser.h in Copy Bitmaps */, + 94A990840C16FC8D0072471F /* lstate.h in Copy Bitmaps */, + 94A990860C16FC8D0072471F /* lstring.h in Copy Bitmaps */, + 94A990890C16FC8D0072471F /* ltable.h in Copy Bitmaps */, + 94A9908C0C16FC8D0072471F /* ltm.h in Copy Bitmaps */, + 94A9908D0C16FC8D0072471F /* lua.h in Copy Bitmaps */, + 94A9908E0C16FC8D0072471F /* luaconf.h in Copy Bitmaps */, + 94A9908F0C16FC8D0072471F /* lualib.h in Copy Bitmaps */, + 94A990910C16FC8D0072471F /* lundump.h in Copy Bitmaps */, + 94A990930C16FC8D0072471F /* lvm.h in Copy Bitmaps */, + 94A990950C16FC8D0072471F /* lzio.h in Copy Bitmaps */, + 94A990970C16FC8D0072471F /* singe_interface.h in Copy Bitmaps */, + 94A990990C16FC8D0072471F /* singeproxy.h in Copy Bitmaps */, + 94A9909B0C16FC8D0072471F /* singe.h in Copy Bitmaps */, + 94A366150CADA86700667ABE /* hw_scoreboard.h in Copy Bitmaps */, + 94A366170CADA86700667ABE /* img_scoreboard.h in Copy Bitmaps */, + 94A366190CADA86700667ABE /* null_scoreboard.h in Copy Bitmaps */, + 94A3661B0CADA86700667ABE /* overlay_scoreboard.h in Copy Bitmaps */, + 94A3661D0CADA86700667ABE /* scoreboard_collection.h in Copy Bitmaps */, + 94A3661F0CADA86700667ABE /* scoreboard_factory.h in Copy Bitmaps */, + 94A366220CADA86700667ABE /* scoreboard_interface.h in Copy Bitmaps */, + 94A366550CADAB1900667ABE /* logger_console.h in Copy Bitmaps */, + 94A366570CADAB1900667ABE /* logger_factory.h in Copy Bitmaps */, + 94A366590CADAB1900667ABE /* logger.h in Copy Bitmaps */, + 94A366910CADAC7000667ABE /* test_sb.h in Copy Bitmaps */, + 94FD7FFC0CBA97FC0023EF96 /* mmxdefs.h in Copy Bitmaps */, + ); + name = "Copy Bitmaps"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94A990110C16FC780072471F /* Copy Sounds */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = sound; + dstSubfolderSpec = 6; + files = ( + 94A990120C16FC780072471F /* ab_alarm1.wav in Copy Sounds */, + 94A990130C16FC780072471F /* ab_alarm2.wav in Copy Sounds */, + 94A990140C16FC780072471F /* ab_alarm3.wav in Copy Sounds */, + 94A990150C16FC780072471F /* ab_alarm4.wav in Copy Sounds */, + 94A990160C16FC780072471F /* ab_enemy.wav in Copy Sounds */, + 94A990170C16FC780072471F /* ab_fire.wav in Copy Sounds */, + 94A990180C16FC780072471F /* ab_ship.wav in Copy Sounds */, + 94A990190C16FC780072471F /* bl_shot.wav in Copy Sounds */, + 94A9901A0C16FC780072471F /* cliff_correct.wav in Copy Sounds */, + 94A9901B0C16FC780072471F /* cliff_startup.wav in Copy Sounds */, + 94A9901C0C16FC780072471F /* cliff_wrong.wav in Copy Sounds */, + 94A9901D0C16FC780072471F /* dl2_bad.wav in Copy Sounds */, + 94A9901E0C16FC780072471F /* dl2_coin1.wav in Copy Sounds */, + 94A9901F0C16FC780072471F /* dl2_coin2.wav in Copy Sounds */, + 94A990200C16FC780072471F /* dl2_coin3.wav in Copy Sounds */, + 94A990210C16FC780072471F /* dl2_coin4.wav in Copy Sounds */, + 94A990220C16FC780072471F /* dl2_error.wav in Copy Sounds */, + 94A990230C16FC780072471F /* dl2_good.wav in Copy Sounds */, + 94A990240C16FC780072471F /* dl2_tic.wav in Copy Sounds */, + 94A990250C16FC780072471F /* dl2_toc.wav in Copy Sounds */, + 94A990260C16FC780072471F /* dl2_warble.wav in Copy Sounds */, + 94A990270C16FC780072471F /* dl2_warn.wav in Copy Sounds */, + 94A990280C16FC780072471F /* dl_accept.wav in Copy Sounds */, + 94A990290C16FC780072471F /* dl_buzz.wav in Copy Sounds */, + 94A9902A0C16FC780072471F /* dl_credit.wav in Copy Sounds */, + 94A9902B0C16FC780072471F /* esh_beep.wav in Copy Sounds */, + 94A9902C0C16FC780072471F /* gr_alarm1.wav in Copy Sounds */, + 94A9902D0C16FC780072471F /* gr_alarm2.wav in Copy Sounds */, + 94A9902E0C16FC780072471F /* gr_alarm3.wav in Copy Sounds */, + 94A9902F0C16FC780072471F /* gr_alarm4.wav in Copy Sounds */, + 94A990300C16FC780072471F /* gr_attack.wav in Copy Sounds */, + 94A990310C16FC780072471F /* gr_cannon.wav in Copy Sounds */, + 94A990320C16FC780072471F /* gr_fire.wav in Copy Sounds */, + 94A990330C16FC780072471F /* gr_mineon.wav in Copy Sounds */, + 94A990340C16FC780072471F /* mach3-01.ogg in Copy Sounds */, + 94A990350C16FC780072471F /* mach3-02.ogg in Copy Sounds */, + 94A990360C16FC780072471F /* mach3-03.ogg in Copy Sounds */, + 94A990370C16FC780072471F /* mach3-04.ogg in Copy Sounds */, + 94A990380C16FC780072471F /* mach3-05.ogg in Copy Sounds */, + 94A990390C16FC780072471F /* mach3-06.ogg in Copy Sounds */, + 94A9903A0C16FC780072471F /* mach3-07.ogg in Copy Sounds */, + 94A9903B0C16FC780072471F /* mach3-08.ogg in Copy Sounds */, + 94A9903C0C16FC780072471F /* mach3-09.ogg in Copy Sounds */, + 94A9903D0C16FC780072471F /* mach3-11.ogg in Copy Sounds */, + 94A9903E0C16FC780072471F /* mach3-13.ogg in Copy Sounds */, + 94A9903F0C16FC780072471F /* mach3-15.ogg in Copy Sounds */, + 94A990400C16FC780072471F /* mach3-19.ogg in Copy Sounds */, + 94A990410C16FC780072471F /* mach3-20.ogg in Copy Sounds */, + 94A990420C16FC780072471F /* mach3-22.ogg in Copy Sounds */, + 94A990430C16FC780072471F /* mach3-33.ogg in Copy Sounds */, + 94A990440C16FC780072471F /* mach3-34.ogg in Copy Sounds */, + 94A990450C16FC780072471F /* mach3-35.ogg in Copy Sounds */, + 94A990460C16FC780072471F /* mach3-36.ogg in Copy Sounds */, + 94A990470C16FC780072471F /* mach3-37.ogg in Copy Sounds */, + 94A990480C16FC780072471F /* mach3-39.ogg in Copy Sounds */, + 94A990490C16FC780072471F /* mach3-40.ogg in Copy Sounds */, + 94A9904A0C16FC780072471F /* mach3-41.ogg in Copy Sounds */, + 94A9904B0C16FC780072471F /* mach3-42.ogg in Copy Sounds */, + 94A9904C0C16FC780072471F /* mach3-43.ogg in Copy Sounds */, + 94A9904D0C16FC780072471F /* mach3-45.ogg in Copy Sounds */, + 94A9904E0C16FC780072471F /* mach3-49.ogg in Copy Sounds */, + 94A9904F0C16FC780072471F /* mach3-null.ogg in Copy Sounds */, + 94A990500C16FC780072471F /* saveme.wav in Copy Sounds */, + 94A990510C16FC780072471F /* sd_coin.wav in Copy Sounds */, + 94A990520C16FC780072471F /* sd_fail.wav in Copy Sounds */, + 94A990530C16FC780072471F /* sd_succeed.wav in Copy Sounds */, + 94A990540C16FC780072471F /* sda_success_hi.wav in Copy Sounds */, + 94A990550C16FC780072471F /* sda_success_lo.wav in Copy Sounds */, + ); + name = "Copy Sounds"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94A990560C16FC780072471F /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 94A991060C16FFF50072471F /* SDL_image.framework in Copy Frameworks */, + 94A990FB0C16FF870072471F /* SDL_ttf.framework in Copy Frameworks */, + 94A990570C16FC780072471F /* Ogg.framework in Copy Frameworks */, + 94A990580C16FC780072471F /* SDL.framework in Copy Frameworks */, + 94A990590C16FC780072471F /* Vorbis.framework in Copy Frameworks */, + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94A9905A0C16FC780072471F /* Copy Manifest */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 6; + files = ( + 94A9905B0C16FC780072471F /* DaphneManifest.xml in Copy Manifest */, + ); + name = "Copy Manifest"; + runOnlyForDeploymentPostprocessing = 0; + }; + 94F97A580B39B2A000F29536 /* Copy Manifest */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 6; + files = ( + 94B1CF7A0CB56E6000A2DB19 /* daphne-changelog.txt in Copy Manifest */, + 94F97A5A0B39B2B200F29536 /* DaphneManifest.xml in Copy Manifest */, + ); + name = "Copy Manifest"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 8D1107320486CEB800E47090 /* Daphne.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Daphne.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9414C1B50A9104C800F8A711 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; }; + 9414C1C90A9106C900F8A711 /* video_out_dx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out_dx.c; sourceTree = ""; }; + 9414C1CA0A9106C900F8A711 /* video_out_null.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out_null.c; sourceTree = ""; }; + 9414C1CB0A9106C900F8A711 /* video_out_pgm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out_pgm.c; sourceTree = ""; }; + 9414C1CC0A9106C900F8A711 /* video_out_x11.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out_x11.c; sourceTree = ""; }; + 943DBCF80CBB47CA00525DD9 /* GLExtensionWrangler.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLExtensionWrangler.framework; path = /Library/Frameworks/GLExtensionWrangler.framework; sourceTree = ""; }; + 94465B7E0A90072F006FD484 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; + 94465B800A90072F006FD484 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; + 94465B810A90072F006FD484 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; + 9453E3350C10C64E000EFDC2 /* mix.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mix.cpp; sourceTree = ""; }; + 9453E3360C10C64E000EFDC2 /* mix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mix.h; sourceTree = ""; }; + 946EB6B50CB83D8C003FE54F /* yuv2rgb_mmx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = yuv2rgb_mmx.c; sourceTree = ""; }; + 948856260A8FDE14000B5138 /* ConsoleFont.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = ConsoleFont.bmp; sourceTree = ""; }; + 948856270A8FDE14000B5138 /* credits.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = credits.bmp; sourceTree = ""; }; + 948856280A8FDE14000B5138 /* gamenowook.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = gamenowook.bmp; sourceTree = ""; }; + 948856290A8FDE14000B5138 /* ldp1450font.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = ldp1450font.bmp; sourceTree = ""; }; + 9488562A0A8FDE14000B5138 /* led0.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led0.bmp; sourceTree = ""; }; + 9488562B0A8FDE14000B5138 /* led1.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led1.bmp; sourceTree = ""; }; + 9488562C0A8FDE14000B5138 /* led10.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led10.bmp; sourceTree = ""; }; + 9488562D0A8FDE14000B5138 /* led11.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led11.bmp; sourceTree = ""; }; + 9488562E0A8FDE14000B5138 /* led12.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led12.bmp; sourceTree = ""; }; + 9488562F0A8FDE14000B5138 /* led13.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led13.bmp; sourceTree = ""; }; + 948856300A8FDE14000B5138 /* led14.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led14.bmp; sourceTree = ""; }; + 948856310A8FDE14000B5138 /* led15.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led15.bmp; sourceTree = ""; }; + 948856320A8FDE14000B5138 /* led16.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led16.bmp; sourceTree = ""; }; + 948856330A8FDE14000B5138 /* led2.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led2.bmp; sourceTree = ""; }; + 948856340A8FDE14000B5138 /* led3.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led3.bmp; sourceTree = ""; }; + 948856350A8FDE14000B5138 /* led4.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led4.bmp; sourceTree = ""; }; + 948856360A8FDE14000B5138 /* led5.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led5.bmp; sourceTree = ""; }; + 948856370A8FDE14000B5138 /* led6.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led6.bmp; sourceTree = ""; }; + 948856380A8FDE14000B5138 /* led7.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led7.bmp; sourceTree = ""; }; + 948856390A8FDE14000B5138 /* led8.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led8.bmp; sourceTree = ""; }; + 9488563A0A8FDE14000B5138 /* led9.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = led9.bmp; sourceTree = ""; }; + 9488563B0A8FDE14000B5138 /* lives.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = lives.bmp; sourceTree = ""; }; + 9488563E0A8FDE14000B5138 /* overlayleds1.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = overlayleds1.bmp; sourceTree = ""; }; + 9488563F0A8FDE14000B5138 /* overlayleds2.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = overlayleds2.bmp; sourceTree = ""; }; + 948856400A8FDE14000B5138 /* player1.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = player1.bmp; sourceTree = ""; }; + 948856410A8FDE14000B5138 /* player2.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = player2.bmp; sourceTree = ""; }; + 948856420A8FDE14000B5138 /* saveme.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = saveme.bmp; sourceTree = ""; }; + 948856440A8FDE2D000B5138 /* ab_alarm1.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_alarm1.wav; sourceTree = ""; }; + 948856450A8FDE2D000B5138 /* ab_alarm2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_alarm2.wav; sourceTree = ""; }; + 948856460A8FDE2D000B5138 /* ab_alarm3.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_alarm3.wav; sourceTree = ""; }; + 948856470A8FDE2D000B5138 /* ab_alarm4.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_alarm4.wav; sourceTree = ""; }; + 948856480A8FDE2D000B5138 /* ab_enemy.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_enemy.wav; sourceTree = ""; }; + 948856490A8FDE2D000B5138 /* ab_fire.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_fire.wav; sourceTree = ""; }; + 9488564A0A8FDE2D000B5138 /* ab_ship.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ab_ship.wav; sourceTree = ""; }; + 9488564B0A8FDE2D000B5138 /* bl_shot.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = bl_shot.wav; sourceTree = ""; }; + 9488564C0A8FDE2D000B5138 /* cliff_correct.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = cliff_correct.wav; sourceTree = ""; }; + 9488564D0A8FDE2D000B5138 /* cliff_startup.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = cliff_startup.wav; sourceTree = ""; }; + 9488564E0A8FDE2D000B5138 /* cliff_wrong.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = cliff_wrong.wav; sourceTree = ""; }; + 9488564F0A8FDE2D000B5138 /* dl2_bad.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_bad.wav; sourceTree = ""; }; + 948856500A8FDE2D000B5138 /* dl2_coin1.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_coin1.wav; sourceTree = ""; }; + 948856510A8FDE2D000B5138 /* dl2_coin2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_coin2.wav; sourceTree = ""; }; + 948856520A8FDE2D000B5138 /* dl2_coin3.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_coin3.wav; sourceTree = ""; }; + 948856530A8FDE2D000B5138 /* dl2_coin4.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_coin4.wav; sourceTree = ""; }; + 948856540A8FDE2D000B5138 /* dl2_error.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_error.wav; sourceTree = ""; }; + 948856550A8FDE2D000B5138 /* dl2_good.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_good.wav; sourceTree = ""; }; + 948856560A8FDE2D000B5138 /* dl2_tic.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_tic.wav; sourceTree = ""; }; + 948856570A8FDE2D000B5138 /* dl2_toc.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_toc.wav; sourceTree = ""; }; + 948856580A8FDE2D000B5138 /* dl2_warble.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_warble.wav; sourceTree = ""; }; + 948856590A8FDE2D000B5138 /* dl2_warn.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl2_warn.wav; sourceTree = ""; }; + 9488565A0A8FDE2D000B5138 /* dl_accept.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl_accept.wav; sourceTree = ""; }; + 9488565B0A8FDE2D000B5138 /* dl_buzz.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl_buzz.wav; sourceTree = ""; }; + 9488565C0A8FDE2D000B5138 /* dl_credit.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = dl_credit.wav; sourceTree = ""; }; + 9488565D0A8FDE2D000B5138 /* esh_beep.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = esh_beep.wav; sourceTree = ""; }; + 9488565E0A8FDE2D000B5138 /* gr_alarm1.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_alarm1.wav; sourceTree = ""; }; + 9488565F0A8FDE2D000B5138 /* gr_alarm2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_alarm2.wav; sourceTree = ""; }; + 948856600A8FDE2D000B5138 /* gr_alarm3.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_alarm3.wav; sourceTree = ""; }; + 948856610A8FDE2D000B5138 /* gr_alarm4.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_alarm4.wav; sourceTree = ""; }; + 948856620A8FDE2D000B5138 /* gr_attack.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_attack.wav; sourceTree = ""; }; + 948856630A8FDE2D000B5138 /* gr_cannon.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_cannon.wav; sourceTree = ""; }; + 948856640A8FDE2D000B5138 /* gr_fire.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_fire.wav; sourceTree = ""; }; + 948856650A8FDE2D000B5138 /* gr_mineon.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = gr_mineon.wav; sourceTree = ""; }; + 948856660A8FDE2D000B5138 /* mach3-01.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-01.ogg"; sourceTree = ""; }; + 948856670A8FDE2D000B5138 /* mach3-02.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-02.ogg"; sourceTree = ""; }; + 948856680A8FDE2D000B5138 /* mach3-03.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-03.ogg"; sourceTree = ""; }; + 948856690A8FDE2D000B5138 /* mach3-04.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-04.ogg"; sourceTree = ""; }; + 9488566A0A8FDE2D000B5138 /* mach3-05.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-05.ogg"; sourceTree = ""; }; + 9488566B0A8FDE2D000B5138 /* mach3-06.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-06.ogg"; sourceTree = ""; }; + 9488566C0A8FDE2D000B5138 /* mach3-07.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-07.ogg"; sourceTree = ""; }; + 9488566D0A8FDE2D000B5138 /* mach3-08.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-08.ogg"; sourceTree = ""; }; + 9488566E0A8FDE2D000B5138 /* mach3-09.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-09.ogg"; sourceTree = ""; }; + 9488566F0A8FDE2D000B5138 /* mach3-11.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-11.ogg"; sourceTree = ""; }; + 948856700A8FDE2D000B5138 /* mach3-13.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-13.ogg"; sourceTree = ""; }; + 948856710A8FDE2D000B5138 /* mach3-15.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-15.ogg"; sourceTree = ""; }; + 948856720A8FDE2D000B5138 /* mach3-19.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-19.ogg"; sourceTree = ""; }; + 948856730A8FDE2D000B5138 /* mach3-20.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-20.ogg"; sourceTree = ""; }; + 948856740A8FDE2D000B5138 /* mach3-22.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-22.ogg"; sourceTree = ""; }; + 948856750A8FDE2D000B5138 /* mach3-33.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-33.ogg"; sourceTree = ""; }; + 948856760A8FDE2D000B5138 /* mach3-34.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-34.ogg"; sourceTree = ""; }; + 948856770A8FDE2D000B5138 /* mach3-35.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-35.ogg"; sourceTree = ""; }; + 948856780A8FDE2D000B5138 /* mach3-36.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-36.ogg"; sourceTree = ""; }; + 948856790A8FDE2D000B5138 /* mach3-37.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-37.ogg"; sourceTree = ""; }; + 9488567A0A8FDE2D000B5138 /* mach3-39.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-39.ogg"; sourceTree = ""; }; + 9488567B0A8FDE2D000B5138 /* mach3-40.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-40.ogg"; sourceTree = ""; }; + 9488567C0A8FDE2D000B5138 /* mach3-41.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-41.ogg"; sourceTree = ""; }; + 9488567D0A8FDE2D000B5138 /* mach3-42.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-42.ogg"; sourceTree = ""; }; + 9488567E0A8FDE2D000B5138 /* mach3-43.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-43.ogg"; sourceTree = ""; }; + 9488567F0A8FDE2D000B5138 /* mach3-45.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-45.ogg"; sourceTree = ""; }; + 948856800A8FDE2D000B5138 /* mach3-49.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-49.ogg"; sourceTree = ""; }; + 948856810A8FDE2D000B5138 /* mach3-null.ogg */ = {isa = PBXFileReference; lastKnownFileType = file; path = "mach3-null.ogg"; sourceTree = ""; }; + 948856820A8FDE2D000B5138 /* saveme.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = saveme.wav; sourceTree = ""; }; + 948856830A8FDE2D000B5138 /* sd_coin.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = sd_coin.wav; sourceTree = ""; }; + 948856840A8FDE2D000B5138 /* sd_fail.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = sd_fail.wav; sourceTree = ""; }; + 948856850A8FDE2D000B5138 /* sd_succeed.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = sd_succeed.wav; sourceTree = ""; }; + 948856860A8FDE2D000B5138 /* sda_success_hi.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = sda_success_hi.wav; sourceTree = ""; }; + 948856870A8FDE2D000B5138 /* sda_success_lo.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = sda_success_lo.wav; sourceTree = ""; }; + 948858290A8FE2FB000B5138 /* convert_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = convert_internal.h; sourceTree = ""; }; + 9488582A0A8FE2FB000B5138 /* hw_bes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = hw_bes.h; sourceTree = ""; }; + 9488582E0A8FE2FB000B5138 /* video_out.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out.c; sourceTree = ""; }; + 948858320A8FE2FB000B5138 /* video_out_sdl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = video_out_sdl.c; sourceTree = ""; }; + 948858340A8FE2FB000B5138 /* yuv2rgb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = yuv2rgb.c; sourceTree = ""; }; + 948858350A8FE2FB000B5138 /* yuv2rgb_mlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = yuv2rgb_mlib.c; sourceTree = ""; }; + 948858500A8FE316000B5138 /* alpha_asm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = alpha_asm.h; sourceTree = ""; }; + 948858510A8FE316000B5138 /* attributes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = attributes.h; sourceTree = ""; }; + 948858540A8FE316000B5138 /* convert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = convert.h; sourceTree = ""; }; + 948858580A8FE316000B5138 /* mmx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mmx.h; sourceTree = ""; }; + 948858590A8FE316000B5138 /* mpeg2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpeg2.h; sourceTree = ""; }; + 9488585B0A8FE316000B5138 /* tendra.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tendra.h; sourceTree = ""; }; + 9488585C0A8FE316000B5138 /* video_out.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = video_out.h; sourceTree = ""; }; + 948858BD0A8FE345000B5138 /* mpegscan.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mpegscan.c; sourceTree = ""; }; + 948858BE0A8FE345000B5138 /* mpegscan.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpegscan.h; sourceTree = ""; }; + 948858BF0A8FE345000B5138 /* vldp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = vldp.c; sourceTree = ""; }; + 948858C00A8FE345000B5138 /* vldp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vldp.h; sourceTree = ""; }; + 948858C10A8FE345000B5138 /* vldp_common.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vldp_common.h; sourceTree = ""; }; + 948858C20A8FE345000B5138 /* vldp_internal.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = vldp_internal.c; sourceTree = ""; }; + 948858C30A8FE345000B5138 /* vldp_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vldp_internal.h; sourceTree = ""; }; + 948859160A8FE5D5000B5138 /* alloc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = alloc.c; sourceTree = ""; }; + 948859180A8FE5D5000B5138 /* cpu_accel.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cpu_accel.c; sourceTree = ""; }; + 948859190A8FE5D5000B5138 /* cpu_state.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cpu_state.c; sourceTree = ""; }; + 9488591A0A8FE5D5000B5138 /* decode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = decode.c; sourceTree = ""; }; + 9488591B0A8FE5D5000B5138 /* header.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = header.c; sourceTree = ""; }; + 9488591C0A8FE5D5000B5138 /* idct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = idct.c; sourceTree = ""; }; + 9488591D0A8FE5D5000B5138 /* idct_alpha.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = idct_alpha.c; sourceTree = ""; }; + 9488591E0A8FE5D5000B5138 /* idct_altivec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = idct_altivec.c; sourceTree = ""; }; + 9488591F0A8FE5D5000B5138 /* idct_mlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = idct_mlib.c; sourceTree = ""; }; + 948859200A8FE5D5000B5138 /* idct_mmx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = idct_mmx.c; sourceTree = ""; }; + 948859260A8FE5D5000B5138 /* motion_comp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = motion_comp.c; sourceTree = ""; }; + 948859270A8FE5D5000B5138 /* motion_comp_alpha.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = motion_comp_alpha.c; sourceTree = ""; }; + 948859280A8FE5D5000B5138 /* motion_comp_altivec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = motion_comp_altivec.c; sourceTree = ""; }; + 948859290A8FE5D5000B5138 /* motion_comp_mlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = motion_comp_mlib.c; sourceTree = ""; }; + 9488592A0A8FE5D5000B5138 /* motion_comp_mmx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = motion_comp_mmx.c; sourceTree = ""; }; + 9488592B0A8FE5D5000B5138 /* mpeg2_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpeg2_internal.h; sourceTree = ""; }; + 9488592C0A8FE5D5000B5138 /* slice.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = slice.c; sourceTree = ""; }; + 9488592D0A8FE5D5000B5138 /* vlc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vlc.h; sourceTree = ""; }; + 94885A650A8FF28A000B5138 /* ldp-vldp-audio.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "ldp-vldp-audio.cpp"; sourceTree = ""; }; + 94936ADF0A8E88F400BDCACE /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; + 94936AE00A8E88F400BDCACE /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; + 94936AE10A8E88F400BDCACE /* SDLMain.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = SDLMain.nib; sourceTree = ""; }; + 94936B4C0A8E8D4600BDCACE /* daphne.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = daphne.cpp; path = ../daphne.cpp; sourceTree = ""; }; + 94936B4D0A8E8D4600BDCACE /* daphne.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = daphne.h; path = ../daphne.h; sourceTree = ""; }; + 94936B5E0A8E8DC700BDCACE /* globals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = globals.h; path = ../globals.h; sourceTree = ""; }; + 94936B5F0A8E8DF900BDCACE /* 6809infc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = 6809infc.cpp; path = ../cpu/6809infc.cpp; sourceTree = ""; }; + 94936B600A8E8DF900BDCACE /* 6809infc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = 6809infc.h; path = ../cpu/6809infc.h; sourceTree = ""; }; + 94936B610A8E8DF900BDCACE /* cop.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = cop.cpp; path = ../cpu/cop.cpp; sourceTree = ""; }; + 94936B620A8E8DF900BDCACE /* cop.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cop.h; path = ../cpu/cop.h; sourceTree = ""; }; + 94936B630A8E8DF900BDCACE /* copintf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = copintf.cpp; path = ../cpu/copintf.cpp; sourceTree = ""; }; + 94936B640A8E8DF900BDCACE /* copintf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = copintf.h; path = ../cpu/copintf.h; sourceTree = ""; }; + 94936B650A8E8DF900BDCACE /* cpu-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = "cpu-debug.cpp"; path = "../cpu/cpu-debug.cpp"; sourceTree = ""; }; + 94936B660A8E8DF900BDCACE /* cpu-debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "cpu-debug.h"; path = "../cpu/cpu-debug.h"; sourceTree = ""; }; + 94936B670A8E8DF900BDCACE /* cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = cpu.cpp; path = ../cpu/cpu.cpp; sourceTree = ""; }; + 94936B680A8E8DF900BDCACE /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cpu.h; path = ../cpu/cpu.h; sourceTree = ""; }; + 94936B690A8E8DF900BDCACE /* generic_z80.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = generic_z80.h; path = ../cpu/generic_z80.h; sourceTree = ""; }; + 94936B6B0A8E8DF900BDCACE /* m80_internal_inline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m80_internal_inline.h; path = ../cpu/m80_internal_inline.h; sourceTree = ""; }; + 94936B6C0A8E8DF900BDCACE /* m80_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m80_internal.h; path = ../cpu/m80_internal.h; sourceTree = ""; }; + 94936B6D0A8E8DF900BDCACE /* m80.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = m80.cpp; path = ../cpu/m80.cpp; sourceTree = ""; }; + 94936B6E0A8E8DF900BDCACE /* m80.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m80.h; path = ../cpu/m80.h; sourceTree = ""; }; + 94936B6F0A8E8DF900BDCACE /* m80daa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m80daa.h; path = ../cpu/m80daa.h; sourceTree = ""; }; + 94936B710A8E8DF900BDCACE /* m80tables.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m80tables.h; path = ../cpu/m80tables.h; sourceTree = ""; }; + 94936B730A8E8DF900BDCACE /* mamewrap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = mamewrap.cpp; path = ../cpu/mamewrap.cpp; sourceTree = ""; }; + 94936B740A8E8DF900BDCACE /* mamewrap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mamewrap.h; path = ../cpu/mamewrap.h; sourceTree = ""; }; + 94936B750A8E8DF900BDCACE /* mc6809.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = mc6809.cpp; path = ../cpu/mc6809.cpp; sourceTree = ""; }; + 94936B760A8E8DF900BDCACE /* mc6809.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mc6809.h; path = ../cpu/mc6809.h; sourceTree = ""; }; + 94936B770A8E8DF900BDCACE /* nes_6502.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = nes_6502.cpp; path = ../cpu/nes_6502.cpp; sourceTree = ""; }; + 94936B780A8E8DF900BDCACE /* nes_6502.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = nes_6502.h; path = ../cpu/nes_6502.h; sourceTree = ""; }; + 94936B790A8E8DF900BDCACE /* nes6502.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = nes6502.cpp; path = ../cpu/nes6502.cpp; sourceTree = ""; }; + 94936B7A0A8E8DF900BDCACE /* nes6502.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = nes6502.h; path = ../cpu/nes6502.h; sourceTree = ""; }; + 94936B7B0A8E8DF900BDCACE /* ppc_intrinsics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ppc_intrinsics.h; path = ../cpu/ppc_intrinsics.h; sourceTree = ""; }; + 94936B7C0A8E8DF900BDCACE /* types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../cpu/types.h; sourceTree = ""; }; + 94936B8B0A8E8DF900BDCACE /* z80_obsolete.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = z80_obsolete.h; path = ../cpu/z80_obsolete.h; sourceTree = ""; }; + 94936B8D0A8E8DF900BDCACE /* z80daa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = z80daa.h; path = ../cpu/z80daa.h; sourceTree = ""; }; + 94936B8E0A8E8DF900BDCACE /* z80dasm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = z80dasm.cpp; path = ../cpu/z80dasm.cpp; sourceTree = ""; }; + 94936B8F0A8E8DF900BDCACE /* z80dasm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = z80dasm.h; path = ../cpu/z80dasm.h; sourceTree = ""; }; + 94936BAF0A8E8E5700BDCACE /* astron.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = astron.cpp; sourceTree = ""; }; + 94936BB00A8E8E5700BDCACE /* astron.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = astron.h; sourceTree = ""; }; + 94936BB10A8E8E5700BDCACE /* badlands.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = badlands.cpp; sourceTree = ""; }; + 94936BB20A8E8E5700BDCACE /* badlands.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = badlands.h; sourceTree = ""; }; + 94936BB30A8E8E5700BDCACE /* bega.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = bega.cpp; sourceTree = ""; }; + 94936BB40A8E8E5700BDCACE /* bega.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = bega.h; sourceTree = ""; }; + 94936BB50A8E8E5700BDCACE /* benchmark.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = benchmark.cpp; sourceTree = ""; }; + 94936BB60A8E8E5700BDCACE /* benchmark.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = benchmark.h; sourceTree = ""; }; + 94936BB70A8E8E5700BDCACE /* boardinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = boardinfo.cpp; sourceTree = ""; }; + 94936BB80A8E8E5700BDCACE /* boardinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = boardinfo.h; sourceTree = ""; }; + 94936BB90A8E8E5700BDCACE /* cliff.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cliff.cpp; sourceTree = ""; }; + 94936BBA0A8E8E5700BDCACE /* cliff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cliff.h; sourceTree = ""; }; + 94936BBB0A8E8E5700BDCACE /* cobraconv.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cobraconv.cpp; sourceTree = ""; }; + 94936BBC0A8E8E5700BDCACE /* cobraconv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cobraconv.h; sourceTree = ""; }; + 94936BBD0A8E8E5700BDCACE /* cputest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cputest.cpp; sourceTree = ""; }; + 94936BBE0A8E8E5700BDCACE /* cputest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cputest.h; sourceTree = ""; }; + 94936BC10A8E8E5700BDCACE /* esh.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = esh.cpp; sourceTree = ""; }; + 94936BC20A8E8E5700BDCACE /* esh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = esh.h; sourceTree = ""; }; + 94936BC30A8E8E5700BDCACE /* ffr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ffr.cpp; sourceTree = ""; }; + 94936BC40A8E8E5700BDCACE /* ffr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ffr.h; sourceTree = ""; }; + 94936BC50A8E8E5700BDCACE /* firefox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = firefox.cpp; sourceTree = ""; }; + 94936BC60A8E8E5700BDCACE /* firefox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = firefox.h; sourceTree = ""; }; + 94936BC70A8E8E5700BDCACE /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = game.cpp; sourceTree = ""; }; + 94936BC80A8E8E5700BDCACE /* game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = ""; }; + 94936BC90A8E8E5700BDCACE /* gpworld.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = gpworld.cpp; sourceTree = ""; }; + 94936BCA0A8E8E5700BDCACE /* gpworld.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gpworld.h; sourceTree = ""; }; + 94936BCB0A8E8E5700BDCACE /* interstellar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = interstellar.cpp; sourceTree = ""; }; + 94936BCC0A8E8E5700BDCACE /* interstellar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = interstellar.h; sourceTree = ""; }; + 94936BCD0A8E8E5700BDCACE /* lair.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lair.cpp; sourceTree = ""; }; + 94936BCE0A8E8E5700BDCACE /* lair.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lair.h; sourceTree = ""; }; + 94936BCF0A8E8E5700BDCACE /* lair2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lair2.cpp; sourceTree = ""; }; + 94936BD00A8E8E5700BDCACE /* lair2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lair2.h; sourceTree = ""; }; + 94936BD10A8E8E5700BDCACE /* laireuro.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = laireuro.cpp; sourceTree = ""; }; + 94936BD20A8E8E5700BDCACE /* laireuro.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = laireuro.h; sourceTree = ""; }; + 94936BD30A8E8E5700BDCACE /* lgp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = lgp.cpp; sourceTree = ""; }; + 94936BD40A8E8E5700BDCACE /* lgp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = lgp.h; sourceTree = ""; }; + 94936BD50A8E8E5700BDCACE /* mach3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mach3.cpp; sourceTree = ""; }; + 94936BD60A8E8E5700BDCACE /* mach3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mach3.h; sourceTree = ""; }; + 94936BD80A8E8E5700BDCACE /* multicputest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = multicputest.cpp; sourceTree = ""; }; + 94936BD90A8E8E5700BDCACE /* multicputest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = multicputest.h; sourceTree = ""; }; + 94936BDA0A8E8E5700BDCACE /* releasetest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = releasetest.cpp; sourceTree = ""; }; + 94936BDB0A8E8E5700BDCACE /* releasetest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = releasetest.h; sourceTree = ""; }; + 94936BDC0A8E8E5700BDCACE /* seektest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = seektest.cpp; sourceTree = ""; }; + 94936BDD0A8E8E5700BDCACE /* seektest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = seektest.h; sourceTree = ""; }; + 94936BDE0A8E8E5700BDCACE /* speedtest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = speedtest.cpp; sourceTree = ""; }; + 94936BDF0A8E8E5700BDCACE /* speedtest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = speedtest.h; sourceTree = ""; }; + 94936BE00A8E8E5700BDCACE /* starrider.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = starrider.cpp; sourceTree = ""; }; + 94936BE10A8E8E5700BDCACE /* starrider.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = starrider.h; sourceTree = ""; }; + 94936BE20A8E8E5700BDCACE /* superd.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = superd.cpp; sourceTree = ""; }; + 94936BE30A8E8E5700BDCACE /* superd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = superd.h; sourceTree = ""; }; + 94936BE40A8E8E5700BDCACE /* thayers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = thayers.cpp; sourceTree = ""; }; + 94936BE50A8E8E5700BDCACE /* thayers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = thayers.h; sourceTree = ""; }; + 94936BE60A8E8E5700BDCACE /* timetrav.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = timetrav.cpp; sourceTree = ""; }; + 94936BE70A8E8E5700BDCACE /* timetrav.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = timetrav.h; sourceTree = ""; }; + 94936C060A8E8E7100BDCACE /* cmdline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cmdline.cpp; sourceTree = ""; }; + 94936C070A8E8E7100BDCACE /* cmdline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cmdline.h; sourceTree = ""; }; + 94936C080A8E8E7100BDCACE /* conin.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = conin.cpp; sourceTree = ""; }; + 94936C090A8E8E7100BDCACE /* conin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = conin.h; sourceTree = ""; }; + 94936C0A0A8E8E7100BDCACE /* conout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = conout.cpp; sourceTree = ""; }; + 94936C0B0A8E8E7100BDCACE /* conout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = conout.h; sourceTree = ""; }; + 94936C0C0A8E8E7100BDCACE /* dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dll.h; sourceTree = ""; }; + 94936C0D0A8E8E7100BDCACE /* error.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = error.cpp; sourceTree = ""; }; + 94936C0E0A8E8E7100BDCACE /* error.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = ""; }; + 94936C0F0A8E8E7100BDCACE /* fileparse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = fileparse.cpp; sourceTree = ""; }; + 94936C100A8E8E7100BDCACE /* fileparse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = fileparse.h; sourceTree = ""; }; + 94936C110A8E8E7100BDCACE /* homedir.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = homedir.cpp; sourceTree = ""; }; + 94936C120A8E8E7100BDCACE /* homedir.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = homedir.h; sourceTree = ""; }; + 94936C130A8E8E7100BDCACE /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = input.cpp; sourceTree = ""; }; + 94936C140A8E8E7100BDCACE /* input.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = input.h; sourceTree = ""; }; + 94936C160A8E8E7100BDCACE /* mpo_fileio.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mpo_fileio.cpp; sourceTree = ""; }; + 94936C170A8E8E7100BDCACE /* mpo_fileio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpo_fileio.h; sourceTree = ""; }; + 94936C180A8E8E7100BDCACE /* mpo_mem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpo_mem.h; sourceTree = ""; }; + 94936C190A8E8E7100BDCACE /* my_stdio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = my_stdio.h; sourceTree = ""; }; + 94936C1A0A8E8E7100BDCACE /* network.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = network.cpp; sourceTree = ""; }; + 94936C1B0A8E8E7100BDCACE /* network.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = network.h; sourceTree = ""; }; + 94936C1C0A8E8E7100BDCACE /* numstr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = numstr.cpp; sourceTree = ""; }; + 94936C1D0A8E8E7100BDCACE /* numstr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = numstr.h; sourceTree = ""; }; + 94936C200A8E8E7100BDCACE /* parallel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = parallel.cpp; sourceTree = ""; }; + 94936C210A8E8E7100BDCACE /* parallel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = parallel.h; sourceTree = ""; }; + 94936C220A8E8E7100BDCACE /* serial.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = serial.cpp; sourceTree = ""; }; + 94936C230A8E8E7100BDCACE /* serial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = serial.h; sourceTree = ""; }; + 94936C240A8E8E7100BDCACE /* sram.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sram.cpp; sourceTree = ""; }; + 94936C250A8E8E7100BDCACE /* sram.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sram.h; sourceTree = ""; }; + 94936C260A8E8E7100BDCACE /* unzip.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = unzip.cpp; sourceTree = ""; }; + 94936C270A8E8E7100BDCACE /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = ""; }; + 94936C390A8E8E9C00BDCACE /* ldp1000.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ldp1000.cpp; sourceTree = ""; }; + 94936C3A0A8E8E9C00BDCACE /* ldp1000.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ldp1000.h; sourceTree = ""; }; + 94936C3B0A8E8E9C00BDCACE /* ldv1000.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ldv1000.cpp; sourceTree = ""; }; + 94936C3C0A8E8E9C00BDCACE /* ldv1000.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ldv1000.h; sourceTree = ""; }; + 94936C3E0A8E8E9C00BDCACE /* pr7820.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = pr7820.cpp; sourceTree = ""; }; + 94936C3F0A8E8E9C00BDCACE /* pr7820.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pr7820.h; sourceTree = ""; }; + 94936C400A8E8E9C00BDCACE /* pr8210.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = pr8210.cpp; sourceTree = ""; }; + 94936C410A8E8E9C00BDCACE /* pr8210.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pr8210.h; sourceTree = ""; }; + 94936C420A8E8E9C00BDCACE /* vip9500sg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vip9500sg.cpp; sourceTree = ""; }; + 94936C430A8E8E9C00BDCACE /* vip9500sg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vip9500sg.h; sourceTree = ""; }; + 94936C440A8E8E9C00BDCACE /* vp380.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vp380.cpp; sourceTree = ""; }; + 94936C450A8E8E9C00BDCACE /* vp380.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vp380.h; sourceTree = ""; }; + 94936C460A8E8E9C00BDCACE /* vp931.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vp931.cpp; sourceTree = ""; }; + 94936C470A8E8E9C00BDCACE /* vp931.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vp931.h; sourceTree = ""; }; + 94936C480A8E8E9C00BDCACE /* vp932.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vp932.cpp; sourceTree = ""; }; + 94936C490A8E8E9C00BDCACE /* vp932.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vp932.h; sourceTree = ""; }; + 94936C540A8E8EAB00BDCACE /* framemod.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = framemod.cpp; sourceTree = ""; }; + 94936C550A8E8EAB00BDCACE /* framemod.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = framemod.h; sourceTree = ""; }; + 94936C560A8E8EAB00BDCACE /* hitachi.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = hitachi.cpp; sourceTree = ""; }; + 94936C570A8E8EAB00BDCACE /* hitachi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = hitachi.h; sourceTree = ""; }; + 94936C580A8E8EAB00BDCACE /* ld-v6000.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "ld-v6000.cpp"; sourceTree = ""; }; + 94936C590A8E8EAB00BDCACE /* ld-v6000.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "ld-v6000.h"; sourceTree = ""; }; + 94936C5A0A8E8EAB00BDCACE /* ldp-combo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "ldp-combo.cpp"; sourceTree = ""; }; + 94936C5B0A8E8EAB00BDCACE /* ldp-combo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "ldp-combo.h"; sourceTree = ""; }; + 94936C5D0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "ldp-vldp-gl.cpp"; sourceTree = ""; }; + 94936C5E0A8E8EAB00BDCACE /* ldp-vldp-gl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "ldp-vldp-gl.h"; sourceTree = ""; }; + 94936C5F0A8E8EAB00BDCACE /* ldp-vldp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "ldp-vldp.cpp"; sourceTree = ""; }; + 94936C600A8E8EAB00BDCACE /* ldp-vldp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "ldp-vldp.h"; sourceTree = ""; }; + 94936C610A8E8EAB00BDCACE /* ldp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ldp.cpp; sourceTree = ""; }; + 94936C620A8E8EAB00BDCACE /* ldp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ldp.h; sourceTree = ""; }; + 94936C640A8E8EAB00BDCACE /* philips.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = philips.cpp; sourceTree = ""; }; + 94936C650A8E8EAB00BDCACE /* philips.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = philips.h; sourceTree = ""; }; + 94936C660A8E8EAB00BDCACE /* pioneer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = pioneer.cpp; sourceTree = ""; }; + 94936C670A8E8EAB00BDCACE /* pioneer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pioneer.h; sourceTree = ""; }; + 94936C680A8E8EAB00BDCACE /* sony.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sony.cpp; sourceTree = ""; }; + 94936C690A8E8EAB00BDCACE /* sony.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sony.h; sourceTree = ""; }; + 94936C770A8E8EBF00BDCACE /* dac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dac.cpp; sourceTree = ""; }; + 94936C780A8E8EBF00BDCACE /* dac.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dac.h; sourceTree = ""; }; + 94936C790A8E8EBF00BDCACE /* gisound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = gisound.cpp; sourceTree = ""; }; + 94936C7A0A8E8EBF00BDCACE /* gisound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gisound.h; sourceTree = ""; }; + 94936C7C0A8E8EBF00BDCACE /* pc_beeper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = pc_beeper.cpp; sourceTree = ""; }; + 94936C7D0A8E8EBF00BDCACE /* pc_beeper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pc_beeper.h; sourceTree = ""; }; + 94936C7E0A8E8EBF00BDCACE /* sn_intf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sn_intf.cpp; sourceTree = ""; }; + 94936C7F0A8E8EBF00BDCACE /* sn_intf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sn_intf.h; sourceTree = ""; }; + 94936C800A8E8EBF00BDCACE /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = ""; }; + 94936C810A8E8EBF00BDCACE /* sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = ""; }; + 94936C820A8E8EBF00BDCACE /* ssi263.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ssi263.cpp; sourceTree = ""; }; + 94936C830A8E8EBF00BDCACE /* ssi263.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ssi263.h; sourceTree = ""; }; + 94936C840A8E8EBF00BDCACE /* tms9919-sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "tms9919-sdl.cpp"; sourceTree = ""; }; + 94936C850A8E8EBF00BDCACE /* tms9919-sdl.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = "tms9919-sdl.hpp"; sourceTree = ""; }; + 94936C860A8E8EBF00BDCACE /* tms9919.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tms9919.cpp; sourceTree = ""; }; + 94936C870A8E8EBF00BDCACE /* tms9919.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = tms9919.hpp; sourceTree = ""; }; + 94936C880A8E8EBF00BDCACE /* tonegen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tonegen.cpp; sourceTree = ""; }; + 94936C890A8E8EBF00BDCACE /* tonegen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tonegen.h; sourceTree = ""; }; + 94936C8A0A8E8EBF00BDCACE /* tqsynth.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tqsynth.cpp; sourceTree = ""; }; + 94936C8B0A8E8EBF00BDCACE /* tqsynth.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tqsynth.h; sourceTree = ""; }; + 94936C990A8E8EE200BDCACE /* timer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = timer.cpp; sourceTree = ""; }; + 94936C9A0A8E8EE200BDCACE /* timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = ""; }; + 94936C9C0A8E8EE200BDCACE /* blend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = blend.cpp; sourceTree = ""; }; + 94936C9D0A8E8EE200BDCACE /* blend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = blend.h; sourceTree = ""; }; + 94936CA00A8E8EE200BDCACE /* led.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = led.cpp; sourceTree = ""; }; + 94936CA10A8E8EE200BDCACE /* led.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = led.h; sourceTree = ""; }; + 94936CA40A8E8EE200BDCACE /* palette.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = palette.cpp; sourceTree = ""; }; + 94936CA50A8E8EE200BDCACE /* palette.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = palette.h; sourceTree = ""; }; + 94936CA80A8E8EE200BDCACE /* rgb2yuv.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = rgb2yuv.cpp; sourceTree = ""; }; + 94936CA90A8E8EE200BDCACE /* rgb2yuv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = rgb2yuv.h; sourceTree = ""; }; + 94936CAC0A8E8EE200BDCACE /* SDL_Console.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SDL_Console.cpp; sourceTree = ""; }; + 94936CAD0A8E8EE200BDCACE /* SDL_Console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDL_Console.h; sourceTree = ""; }; + 94936CAE0A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SDL_ConsoleCommands.cpp; sourceTree = ""; }; + 94936CAF0A8E8EE200BDCACE /* SDL_ConsoleCommands.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDL_ConsoleCommands.h; sourceTree = ""; }; + 94936CB00A8E8EE200BDCACE /* SDL_DrawText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SDL_DrawText.cpp; sourceTree = ""; }; + 94936CB10A8E8EE200BDCACE /* SDL_DrawText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDL_DrawText.h; sourceTree = ""; }; + 94936CB30A8E8EE200BDCACE /* tms9128nl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tms9128nl.cpp; sourceTree = ""; }; + 94936CB40A8E8EE200BDCACE /* tms9128nl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tms9128nl.h; sourceTree = ""; }; + 94936CB50A8E8EE200BDCACE /* video.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = video.cpp; sourceTree = ""; }; + 94936CB60A8E8EE200BDCACE /* video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = video.h; sourceTree = ""; }; + 94936CB70A8E8EE200BDCACE /* yuv2rgb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = yuv2rgb.c; sourceTree = ""; }; + 94936CB80A8E8EE200BDCACE /* yuv2rgb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = yuv2rgb.h; sourceTree = ""; }; + 94936CB90A8E8EE200BDCACE /* yuv2rgb_lookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = yuv2rgb_lookup.h; sourceTree = ""; }; + 94936DE40A8E99C300BDCACE /* i86.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = i86.cpp; sourceTree = ""; }; + 94936DE50A8E99C300BDCACE /* i86.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = i86.h; sourceTree = ""; }; + 94936DE60A8E99C300BDCACE /* i86dasm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = i86dasm.cpp; sourceTree = ""; }; + 949B7BD60AA60481004CA4C8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 94A366050CADA86700667ABE /* hw_scoreboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = hw_scoreboard.cpp; path = ../scoreboard/hw_scoreboard.cpp; sourceTree = SOURCE_ROOT; }; + 94A366060CADA86700667ABE /* hw_scoreboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_scoreboard.h; path = ../scoreboard/hw_scoreboard.h; sourceTree = SOURCE_ROOT; }; + 94A366070CADA86700667ABE /* img_scoreboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = img_scoreboard.cpp; path = ../scoreboard/img_scoreboard.cpp; sourceTree = SOURCE_ROOT; }; + 94A366080CADA86700667ABE /* img_scoreboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = img_scoreboard.h; path = ../scoreboard/img_scoreboard.h; sourceTree = SOURCE_ROOT; }; + 94A366090CADA86700667ABE /* null_scoreboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = null_scoreboard.cpp; path = ../scoreboard/null_scoreboard.cpp; sourceTree = SOURCE_ROOT; }; + 94A3660A0CADA86700667ABE /* null_scoreboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = null_scoreboard.h; path = ../scoreboard/null_scoreboard.h; sourceTree = SOURCE_ROOT; }; + 94A3660B0CADA86700667ABE /* overlay_scoreboard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = overlay_scoreboard.cpp; path = ../scoreboard/overlay_scoreboard.cpp; sourceTree = SOURCE_ROOT; }; + 94A3660C0CADA86700667ABE /* overlay_scoreboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = overlay_scoreboard.h; path = ../scoreboard/overlay_scoreboard.h; sourceTree = SOURCE_ROOT; }; + 94A3660D0CADA86700667ABE /* scoreboard_collection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = scoreboard_collection.cpp; path = ../scoreboard/scoreboard_collection.cpp; sourceTree = SOURCE_ROOT; }; + 94A3660E0CADA86700667ABE /* scoreboard_collection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = scoreboard_collection.h; path = ../scoreboard/scoreboard_collection.h; sourceTree = SOURCE_ROOT; }; + 94A3660F0CADA86700667ABE /* scoreboard_factory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = scoreboard_factory.cpp; path = ../scoreboard/scoreboard_factory.cpp; sourceTree = SOURCE_ROOT; }; + 94A366100CADA86700667ABE /* scoreboard_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = scoreboard_factory.h; path = ../scoreboard/scoreboard_factory.h; sourceTree = SOURCE_ROOT; }; + 94A366110CADA86700667ABE /* scoreboard_howto.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = scoreboard_howto.txt; path = ../scoreboard/scoreboard_howto.txt; sourceTree = SOURCE_ROOT; }; + 94A366120CADA86700667ABE /* scoreboard_interface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = scoreboard_interface.cpp; path = ../scoreboard/scoreboard_interface.cpp; sourceTree = SOURCE_ROOT; }; + 94A366130CADA86700667ABE /* scoreboard_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = scoreboard_interface.h; path = ../scoreboard/scoreboard_interface.h; sourceTree = SOURCE_ROOT; }; + 94A3664E0CADAB1900667ABE /* logger_console.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = logger_console.cpp; sourceTree = ""; }; + 94A3664F0CADAB1900667ABE /* logger_console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = logger_console.h; sourceTree = ""; }; + 94A366500CADAB1900667ABE /* logger_factory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = logger_factory.cpp; sourceTree = ""; }; + 94A366510CADAB1900667ABE /* logger_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = logger_factory.h; sourceTree = ""; }; + 94A366520CADAB1900667ABE /* logger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = logger.cpp; sourceTree = ""; }; + 94A366530CADAB1900667ABE /* logger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = logger.h; sourceTree = ""; }; + 94A3668E0CADAC7000667ABE /* test_sb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = test_sb.cpp; sourceTree = ""; }; + 94A3668F0CADAC7000667ABE /* test_sb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = test_sb.h; sourceTree = ""; }; + 94A98EDC0C16FB8E0072471F /* singe.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = singe.cpp; path = ../game/singe.cpp; sourceTree = SOURCE_ROOT; }; + 94A98EDD0C16FB8E0072471F /* singe.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = singe.h; path = ../game/singe.h; sourceTree = SOURCE_ROOT; }; + 94A98EE00C16FBA40072471F /* lapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lapi.c; path = ../game/singe/lapi.c; sourceTree = SOURCE_ROOT; }; + 94A98EE10C16FBA40072471F /* lapi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lapi.h; path = ../game/singe/lapi.h; sourceTree = SOURCE_ROOT; }; + 94A98EE20C16FBA40072471F /* lauxlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lauxlib.c; path = ../game/singe/lauxlib.c; sourceTree = SOURCE_ROOT; }; + 94A98EE30C16FBA40072471F /* lauxlib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lauxlib.h; path = ../game/singe/lauxlib.h; sourceTree = SOURCE_ROOT; }; + 94A98EE40C16FBA40072471F /* lbaselib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lbaselib.c; path = ../game/singe/lbaselib.c; sourceTree = SOURCE_ROOT; }; + 94A98EE50C16FBA40072471F /* lcode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lcode.c; path = ../game/singe/lcode.c; sourceTree = SOURCE_ROOT; }; + 94A98EE60C16FBA40072471F /* lcode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lcode.h; path = ../game/singe/lcode.h; sourceTree = SOURCE_ROOT; }; + 94A98EE70C16FBA40072471F /* ldblib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ldblib.c; path = ../game/singe/ldblib.c; sourceTree = SOURCE_ROOT; }; + 94A98EE80C16FBA40072471F /* ldebug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ldebug.c; path = ../game/singe/ldebug.c; sourceTree = SOURCE_ROOT; }; + 94A98EE90C16FBA40072471F /* ldebug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ldebug.h; path = ../game/singe/ldebug.h; sourceTree = SOURCE_ROOT; }; + 94A98EEA0C16FBA40072471F /* ldo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ldo.c; path = ../game/singe/ldo.c; sourceTree = SOURCE_ROOT; }; + 94A98EEB0C16FBA40072471F /* ldo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ldo.h; path = ../game/singe/ldo.h; sourceTree = SOURCE_ROOT; }; + 94A98EEC0C16FBA40072471F /* ldump.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ldump.c; path = ../game/singe/ldump.c; sourceTree = SOURCE_ROOT; }; + 94A98EED0C16FBA40072471F /* lfunc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lfunc.c; path = ../game/singe/lfunc.c; sourceTree = SOURCE_ROOT; }; + 94A98EEE0C16FBA40072471F /* lfunc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lfunc.h; path = ../game/singe/lfunc.h; sourceTree = SOURCE_ROOT; }; + 94A98EEF0C16FBA40072471F /* lgc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lgc.c; path = ../game/singe/lgc.c; sourceTree = SOURCE_ROOT; }; + 94A98EF00C16FBA40072471F /* lgc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lgc.h; path = ../game/singe/lgc.h; sourceTree = SOURCE_ROOT; }; + 94A98EF10C16FBA40072471F /* linit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = linit.c; path = ../game/singe/linit.c; sourceTree = SOURCE_ROOT; }; + 94A98EF20C16FBA40072471F /* liolib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = liolib.c; path = ../game/singe/liolib.c; sourceTree = SOURCE_ROOT; }; + 94A98EF30C16FBA40072471F /* llex.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = llex.c; path = ../game/singe/llex.c; sourceTree = SOURCE_ROOT; }; + 94A98EF40C16FBA40072471F /* llex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = llex.h; path = ../game/singe/llex.h; sourceTree = SOURCE_ROOT; }; + 94A98EF50C16FBA40072471F /* llimits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = llimits.h; path = ../game/singe/llimits.h; sourceTree = SOURCE_ROOT; }; + 94A98EF60C16FBA40072471F /* lmathlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lmathlib.c; path = ../game/singe/lmathlib.c; sourceTree = SOURCE_ROOT; }; + 94A98EF70C16FBA40072471F /* lmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lmem.c; path = ../game/singe/lmem.c; sourceTree = SOURCE_ROOT; }; + 94A98EF80C16FBA40072471F /* lmem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lmem.h; path = ../game/singe/lmem.h; sourceTree = SOURCE_ROOT; }; + 94A98EF90C16FBA40072471F /* loadlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = loadlib.c; path = ../game/singe/loadlib.c; sourceTree = SOURCE_ROOT; }; + 94A98EFA0C16FBA40072471F /* lobject.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lobject.c; path = ../game/singe/lobject.c; sourceTree = SOURCE_ROOT; }; + 94A98EFB0C16FBA40072471F /* lobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lobject.h; path = ../game/singe/lobject.h; sourceTree = SOURCE_ROOT; }; + 94A98EFC0C16FBA40072471F /* lopcodes.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lopcodes.c; path = ../game/singe/lopcodes.c; sourceTree = SOURCE_ROOT; }; + 94A98EFD0C16FBA40072471F /* lopcodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lopcodes.h; path = ../game/singe/lopcodes.h; sourceTree = SOURCE_ROOT; }; + 94A98EFE0C16FBA40072471F /* loslib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = loslib.c; path = ../game/singe/loslib.c; sourceTree = SOURCE_ROOT; }; + 94A98EFF0C16FBA40072471F /* lparser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lparser.c; path = ../game/singe/lparser.c; sourceTree = SOURCE_ROOT; }; + 94A98F000C16FBA40072471F /* lparser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lparser.h; path = ../game/singe/lparser.h; sourceTree = SOURCE_ROOT; }; + 94A98F010C16FBA40072471F /* lstate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lstate.c; path = ../game/singe/lstate.c; sourceTree = SOURCE_ROOT; }; + 94A98F020C16FBA40072471F /* lstate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lstate.h; path = ../game/singe/lstate.h; sourceTree = SOURCE_ROOT; }; + 94A98F030C16FBA40072471F /* lstring.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lstring.c; path = ../game/singe/lstring.c; sourceTree = SOURCE_ROOT; }; + 94A98F040C16FBA40072471F /* lstring.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lstring.h; path = ../game/singe/lstring.h; sourceTree = SOURCE_ROOT; }; + 94A98F050C16FBA40072471F /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lstrlib.c; path = ../game/singe/lstrlib.c; sourceTree = SOURCE_ROOT; }; + 94A98F060C16FBA40072471F /* ltable.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ltable.c; path = ../game/singe/ltable.c; sourceTree = SOURCE_ROOT; }; + 94A98F070C16FBA40072471F /* ltable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ltable.h; path = ../game/singe/ltable.h; sourceTree = SOURCE_ROOT; }; + 94A98F080C16FBA40072471F /* ltablib.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ltablib.c; path = ../game/singe/ltablib.c; sourceTree = SOURCE_ROOT; }; + 94A98F090C16FBA40072471F /* ltm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ltm.c; path = ../game/singe/ltm.c; sourceTree = SOURCE_ROOT; }; + 94A98F0A0C16FBA40072471F /* ltm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ltm.h; path = ../game/singe/ltm.h; sourceTree = SOURCE_ROOT; }; + 94A98F0B0C16FBA40072471F /* lua.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lua.h; path = ../game/singe/lua.h; sourceTree = SOURCE_ROOT; }; + 94A98F0C0C16FBA40072471F /* luaconf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = luaconf.h; path = ../game/singe/luaconf.h; sourceTree = SOURCE_ROOT; }; + 94A98F0D0C16FBA40072471F /* lualib.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lualib.h; path = ../game/singe/lualib.h; sourceTree = SOURCE_ROOT; }; + 94A98F0E0C16FBA40072471F /* lundump.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lundump.c; path = ../game/singe/lundump.c; sourceTree = SOURCE_ROOT; }; + 94A98F0F0C16FBA40072471F /* lundump.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lundump.h; path = ../game/singe/lundump.h; sourceTree = SOURCE_ROOT; }; + 94A98F100C16FBA40072471F /* lvm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lvm.c; path = ../game/singe/lvm.c; sourceTree = SOURCE_ROOT; }; + 94A98F110C16FBA40072471F /* lvm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lvm.h; path = ../game/singe/lvm.h; sourceTree = SOURCE_ROOT; }; + 94A98F120C16FBA40072471F /* lzio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lzio.c; path = ../game/singe/lzio.c; sourceTree = SOURCE_ROOT; }; + 94A98F130C16FBA40072471F /* lzio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lzio.h; path = ../game/singe/lzio.h; sourceTree = SOURCE_ROOT; }; + 94A98F140C16FBA40072471F /* print.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = print.c; path = ../game/singe/print.c; sourceTree = SOURCE_ROOT; }; + 94A98F150C16FBA40072471F /* singe_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = singe_interface.h; path = ../game/singe/singe_interface.h; sourceTree = SOURCE_ROOT; }; + 94A98F160C16FBA40072471F /* singeproxy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = singeproxy.cpp; path = ../game/singe/singeproxy.cpp; sourceTree = SOURCE_ROOT; }; + 94A98F170C16FBA40072471F /* singeproxy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = singeproxy.h; path = ../game/singe/singeproxy.h; sourceTree = SOURCE_ROOT; }; + 94A9905F0C16FC780072471F /* Daphne.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Daphne.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 94A990F00C16FF870072471F /* SDL_image.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_image.framework; path = /Library/Frameworks/SDL_image.framework; sourceTree = ""; }; + 94A990F10C16FF870072471F /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = ""; }; + 94AD92670AA00B7000C9CDC4 /* Daphne Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "Daphne Icon.icns"; sourceTree = ""; }; + 94B1CF770CB56E5B00A2DB19 /* daphne-changelog.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "daphne-changelog.txt"; path = "../../daphne-changelog.txt"; sourceTree = SOURCE_ROOT; }; + 94E91AED0B23463200B51FA6 /* samples.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = samples.cpp; sourceTree = ""; }; + 94E91AEE0B23463200B51FA6 /* samples.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = samples.h; sourceTree = ""; }; + 94F97A390B39B16300F29536 /* DaphneManifest.xml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = DaphneManifest.xml; path = ../DaphneManifest.xml; sourceTree = SOURCE_ROOT; }; + 94FD7FFA0CBA97FC0023EF96 /* mmxdefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mmxdefs.h; sourceTree = ""; }; + 94FD80680CBA9ACF0023EF96 /* mix_mmx-gas.s */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; name = "mix_mmx-gas.s"; path = "../sound/mix_mmx-gas.s"; sourceTree = SOURCE_ROOT; }; + 94FD806B0CBA9AE00023EF96 /* rgb2yuv-gas.s */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; name = "rgb2yuv-gas.s"; path = "../video/rgb2yuv-gas.s"; sourceTree = SOURCE_ROOT; }; + 94FD80F40CBA9DDA0023EF96 /* blend_mmx-gas.s */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; name = "blend_mmx-gas.s"; path = "../video/blend_mmx-gas.s"; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 94465BBB0A90072F006FD484 /* Ogg.framework in Frameworks */, + 94465BBD0A90072F006FD484 /* SDL.framework in Frameworks */, + 94465BBE0A90072F006FD484 /* Vorbis.framework in Frameworks */, + 943DBCFE0CBB47CA00525DD9 /* GLExtensionWrangler.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 94A98FDF0C16FC780072471F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 94A991070C16FFFD0072471F /* SDL_ttf.framework in Frameworks */, + 94A98FE00C16FC780072471F /* Ogg.framework in Frameworks */, + 94A98FE10C16FC780072471F /* SDL.framework in Frameworks */, + 94A98FE20C16FC780072471F /* Vorbis.framework in Frameworks */, + 94A990FA0C16FF870072471F /* SDL_image.framework in Frameworks */, + 943DBCFF0CBB47CA00525DD9 /* GLExtensionWrangler.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Daphne */ = { + isa = PBXGroup; + children = ( + 949B7BD60AA60481004CA4C8 /* Info.plist */, + 94936ADF0A8E88F400BDCACE /* SDLMain.h */, + 94936AE00A8E88F400BDCACE /* SDLMain.m */, + 94936AE10A8E88F400BDCACE /* SDLMain.nib */, + 94FD80670CBA9AAB0023EF96 /* x86 Assembly */, + 94936C050A8E8E7100BDCACE /* io */, + 94936BA00A8E8E0600BDCACE /* cpu */, + 94936C970A8E8EE200BDCACE /* timer */, + 94A366040CADA83800667ABE /* scoreboard */, + 94936C9B0A8E8EE200BDCACE /* video */, + 94936C760A8E8EBF00BDCACE /* sound */, + 94936C530A8E8EAB00BDCACE /* ldp-out */, + 94936C380A8E8E9C00BDCACE /* ldp-in */, + 94936BAE0A8E8E5700BDCACE /* game */, + 94936B4C0A8E8D4600BDCACE /* daphne.cpp */, + 94936B4D0A8E8D4600BDCACE /* daphne.h */, + 94936B5E0A8E8DC700BDCACE /* globals.h */, + 94FD7FFA0CBA97FC0023EF96 /* mmxdefs.h */, + ); + name = Daphne; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* Daphne.app */, + 94A9905F0C16FC780072471F /* Daphne.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Daphne */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Daphne */, + 94A98ED60C16FB360072471F /* Singe */, + 29B97315FDCFA39411CA2CEA /* vldp2 */, + 948856240A8FDDDD000B5138 /* Image and Sound Files */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Daphne; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* vldp2 */ = { + isa = PBXGroup; + children = ( + 948859040A8FE5D5000B5138 /* libmpeg2 */, + 948858BC0A8FE345000B5138 /* vldp */, + 9488584F0A8FE316000B5138 /* include */, + 9488581D0A8FE2FB000B5138 /* libvo */, + ); + name = vldp2; + sourceTree = ""; + }; + 94465B7D0A900715006FD484 /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 943DBCF80CBB47CA00525DD9 /* GLExtensionWrangler.framework */, + 94465B7E0A90072F006FD484 /* Ogg.framework */, + 94465B800A90072F006FD484 /* SDL.framework */, + 94465B810A90072F006FD484 /* Vorbis.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 948856240A8FDDDD000B5138 /* Image and Sound Files */ = { + isa = PBXGroup; + children = ( + 94B1CF770CB56E5B00A2DB19 /* daphne-changelog.txt */, + 94F97A390B39B16300F29536 /* DaphneManifest.xml */, + 94AD92670AA00B7000C9CDC4 /* Daphne Icon.icns */, + 94465B7D0A900715006FD484 /* Linked Frameworks */, + 948856430A8FDE2D000B5138 /* sound */, + 948856250A8FDE14000B5138 /* pics */, + ); + name = "Image and Sound Files"; + sourceTree = ""; + }; + 948856250A8FDE14000B5138 /* pics */ = { + isa = PBXGroup; + children = ( + 948856260A8FDE14000B5138 /* ConsoleFont.bmp */, + 948856270A8FDE14000B5138 /* credits.bmp */, + 948856280A8FDE14000B5138 /* gamenowook.bmp */, + 948856290A8FDE14000B5138 /* ldp1450font.bmp */, + 9488562A0A8FDE14000B5138 /* led0.bmp */, + 9488562B0A8FDE14000B5138 /* led1.bmp */, + 9488562C0A8FDE14000B5138 /* led10.bmp */, + 9488562D0A8FDE14000B5138 /* led11.bmp */, + 9488562E0A8FDE14000B5138 /* led12.bmp */, + 9488562F0A8FDE14000B5138 /* led13.bmp */, + 948856300A8FDE14000B5138 /* led14.bmp */, + 948856310A8FDE14000B5138 /* led15.bmp */, + 948856320A8FDE14000B5138 /* led16.bmp */, + 948856330A8FDE14000B5138 /* led2.bmp */, + 948856340A8FDE14000B5138 /* led3.bmp */, + 948856350A8FDE14000B5138 /* led4.bmp */, + 948856360A8FDE14000B5138 /* led5.bmp */, + 948856370A8FDE14000B5138 /* led6.bmp */, + 948856380A8FDE14000B5138 /* led7.bmp */, + 948856390A8FDE14000B5138 /* led8.bmp */, + 9488563A0A8FDE14000B5138 /* led9.bmp */, + 9488563B0A8FDE14000B5138 /* lives.bmp */, + 9488563E0A8FDE14000B5138 /* overlayleds1.bmp */, + 9488563F0A8FDE14000B5138 /* overlayleds2.bmp */, + 948856400A8FDE14000B5138 /* player1.bmp */, + 948856410A8FDE14000B5138 /* player2.bmp */, + 948856420A8FDE14000B5138 /* saveme.bmp */, + ); + name = pics; + path = ../../pics; + sourceTree = ""; + }; + 948856430A8FDE2D000B5138 /* sound */ = { + isa = PBXGroup; + children = ( + 948856440A8FDE2D000B5138 /* ab_alarm1.wav */, + 948856450A8FDE2D000B5138 /* ab_alarm2.wav */, + 948856460A8FDE2D000B5138 /* ab_alarm3.wav */, + 948856470A8FDE2D000B5138 /* ab_alarm4.wav */, + 948856480A8FDE2D000B5138 /* ab_enemy.wav */, + 948856490A8FDE2D000B5138 /* ab_fire.wav */, + 9488564A0A8FDE2D000B5138 /* ab_ship.wav */, + 9488564B0A8FDE2D000B5138 /* bl_shot.wav */, + 9488564C0A8FDE2D000B5138 /* cliff_correct.wav */, + 9488564D0A8FDE2D000B5138 /* cliff_startup.wav */, + 9488564E0A8FDE2D000B5138 /* cliff_wrong.wav */, + 9488564F0A8FDE2D000B5138 /* dl2_bad.wav */, + 948856500A8FDE2D000B5138 /* dl2_coin1.wav */, + 948856510A8FDE2D000B5138 /* dl2_coin2.wav */, + 948856520A8FDE2D000B5138 /* dl2_coin3.wav */, + 948856530A8FDE2D000B5138 /* dl2_coin4.wav */, + 948856540A8FDE2D000B5138 /* dl2_error.wav */, + 948856550A8FDE2D000B5138 /* dl2_good.wav */, + 948856560A8FDE2D000B5138 /* dl2_tic.wav */, + 948856570A8FDE2D000B5138 /* dl2_toc.wav */, + 948856580A8FDE2D000B5138 /* dl2_warble.wav */, + 948856590A8FDE2D000B5138 /* dl2_warn.wav */, + 9488565A0A8FDE2D000B5138 /* dl_accept.wav */, + 9488565B0A8FDE2D000B5138 /* dl_buzz.wav */, + 9488565C0A8FDE2D000B5138 /* dl_credit.wav */, + 9488565D0A8FDE2D000B5138 /* esh_beep.wav */, + 9488565E0A8FDE2D000B5138 /* gr_alarm1.wav */, + 9488565F0A8FDE2D000B5138 /* gr_alarm2.wav */, + 948856600A8FDE2D000B5138 /* gr_alarm3.wav */, + 948856610A8FDE2D000B5138 /* gr_alarm4.wav */, + 948856620A8FDE2D000B5138 /* gr_attack.wav */, + 948856630A8FDE2D000B5138 /* gr_cannon.wav */, + 948856640A8FDE2D000B5138 /* gr_fire.wav */, + 948856650A8FDE2D000B5138 /* gr_mineon.wav */, + 948856660A8FDE2D000B5138 /* mach3-01.ogg */, + 948856670A8FDE2D000B5138 /* mach3-02.ogg */, + 948856680A8FDE2D000B5138 /* mach3-03.ogg */, + 948856690A8FDE2D000B5138 /* mach3-04.ogg */, + 9488566A0A8FDE2D000B5138 /* mach3-05.ogg */, + 9488566B0A8FDE2D000B5138 /* mach3-06.ogg */, + 9488566C0A8FDE2D000B5138 /* mach3-07.ogg */, + 9488566D0A8FDE2D000B5138 /* mach3-08.ogg */, + 9488566E0A8FDE2D000B5138 /* mach3-09.ogg */, + 9488566F0A8FDE2D000B5138 /* mach3-11.ogg */, + 948856700A8FDE2D000B5138 /* mach3-13.ogg */, + 948856710A8FDE2D000B5138 /* mach3-15.ogg */, + 948856720A8FDE2D000B5138 /* mach3-19.ogg */, + 948856730A8FDE2D000B5138 /* mach3-20.ogg */, + 948856740A8FDE2D000B5138 /* mach3-22.ogg */, + 948856750A8FDE2D000B5138 /* mach3-33.ogg */, + 948856760A8FDE2D000B5138 /* mach3-34.ogg */, + 948856770A8FDE2D000B5138 /* mach3-35.ogg */, + 948856780A8FDE2D000B5138 /* mach3-36.ogg */, + 948856790A8FDE2D000B5138 /* mach3-37.ogg */, + 9488567A0A8FDE2D000B5138 /* mach3-39.ogg */, + 9488567B0A8FDE2D000B5138 /* mach3-40.ogg */, + 9488567C0A8FDE2D000B5138 /* mach3-41.ogg */, + 9488567D0A8FDE2D000B5138 /* mach3-42.ogg */, + 9488567E0A8FDE2D000B5138 /* mach3-43.ogg */, + 9488567F0A8FDE2D000B5138 /* mach3-45.ogg */, + 948856800A8FDE2D000B5138 /* mach3-49.ogg */, + 948856810A8FDE2D000B5138 /* mach3-null.ogg */, + 948856820A8FDE2D000B5138 /* saveme.wav */, + 948856830A8FDE2D000B5138 /* sd_coin.wav */, + 948856840A8FDE2D000B5138 /* sd_fail.wav */, + 948856850A8FDE2D000B5138 /* sd_succeed.wav */, + 948856860A8FDE2D000B5138 /* sda_success_hi.wav */, + 948856870A8FDE2D000B5138 /* sda_success_lo.wav */, + ); + name = sound; + path = ../../sound; + sourceTree = ""; + }; + 9488581D0A8FE2FB000B5138 /* libvo */ = { + isa = PBXGroup; + children = ( + 946EB6B50CB83D8C003FE54F /* yuv2rgb_mmx.c */, + 9414C1C90A9106C900F8A711 /* video_out_dx.c */, + 9414C1CA0A9106C900F8A711 /* video_out_null.c */, + 9414C1CB0A9106C900F8A711 /* video_out_pgm.c */, + 9414C1CC0A9106C900F8A711 /* video_out_x11.c */, + 948858290A8FE2FB000B5138 /* convert_internal.h */, + 9488582A0A8FE2FB000B5138 /* hw_bes.h */, + 9488582E0A8FE2FB000B5138 /* video_out.c */, + 948858320A8FE2FB000B5138 /* video_out_sdl.c */, + 948858340A8FE2FB000B5138 /* yuv2rgb.c */, + 948858350A8FE2FB000B5138 /* yuv2rgb_mlib.c */, + ); + name = libvo; + path = ../vldp2/libvo; + sourceTree = ""; + }; + 9488584F0A8FE316000B5138 /* include */ = { + isa = PBXGroup; + children = ( + 948858500A8FE316000B5138 /* alpha_asm.h */, + 948858510A8FE316000B5138 /* attributes.h */, + 948858540A8FE316000B5138 /* convert.h */, + 948858580A8FE316000B5138 /* mmx.h */, + 948858590A8FE316000B5138 /* mpeg2.h */, + 9488585B0A8FE316000B5138 /* tendra.h */, + 9488585C0A8FE316000B5138 /* video_out.h */, + 9414C1B50A9104C800F8A711 /* config.h */, + ); + name = include; + path = ../vldp2/include; + sourceTree = ""; + }; + 948858BC0A8FE345000B5138 /* vldp */ = { + isa = PBXGroup; + children = ( + 948858BD0A8FE345000B5138 /* mpegscan.c */, + 948858BE0A8FE345000B5138 /* mpegscan.h */, + 948858BF0A8FE345000B5138 /* vldp.c */, + 948858C00A8FE345000B5138 /* vldp.h */, + 948858C10A8FE345000B5138 /* vldp_common.h */, + 948858C20A8FE345000B5138 /* vldp_internal.c */, + 948858C30A8FE345000B5138 /* vldp_internal.h */, + ); + name = vldp; + path = ../vldp2/vldp; + sourceTree = ""; + }; + 948859040A8FE5D5000B5138 /* libmpeg2 */ = { + isa = PBXGroup; + children = ( + 948859160A8FE5D5000B5138 /* alloc.c */, + 948859180A8FE5D5000B5138 /* cpu_accel.c */, + 948859190A8FE5D5000B5138 /* cpu_state.c */, + 9488591A0A8FE5D5000B5138 /* decode.c */, + 9488591B0A8FE5D5000B5138 /* header.c */, + 9488591C0A8FE5D5000B5138 /* idct.c */, + 9488591D0A8FE5D5000B5138 /* idct_alpha.c */, + 9488591E0A8FE5D5000B5138 /* idct_altivec.c */, + 9488591F0A8FE5D5000B5138 /* idct_mlib.c */, + 948859200A8FE5D5000B5138 /* idct_mmx.c */, + 948859260A8FE5D5000B5138 /* motion_comp.c */, + 948859270A8FE5D5000B5138 /* motion_comp_alpha.c */, + 948859280A8FE5D5000B5138 /* motion_comp_altivec.c */, + 948859290A8FE5D5000B5138 /* motion_comp_mlib.c */, + 9488592A0A8FE5D5000B5138 /* motion_comp_mmx.c */, + 9488592B0A8FE5D5000B5138 /* mpeg2_internal.h */, + 9488592C0A8FE5D5000B5138 /* slice.c */, + 9488592D0A8FE5D5000B5138 /* vlc.h */, + ); + name = libmpeg2; + path = ../vldp2/libmpeg2; + sourceTree = ""; + }; + 94936BA00A8E8E0600BDCACE /* cpu */ = { + isa = PBXGroup; + children = ( + 94936DE10A8E99C300BDCACE /* x86 */, + 94936B670A8E8DF900BDCACE /* cpu.cpp */, + 94936B680A8E8DF900BDCACE /* cpu.h */, + 94936B780A8E8DF900BDCACE /* nes_6502.h */, + 94936B790A8E8DF900BDCACE /* nes6502.cpp */, + 94936B7A0A8E8DF900BDCACE /* nes6502.h */, + 94936B7B0A8E8DF900BDCACE /* ppc_intrinsics.h */, + 94936B7C0A8E8DF900BDCACE /* types.h */, + 94936B8B0A8E8DF900BDCACE /* z80_obsolete.h */, + 94936B8D0A8E8DF900BDCACE /* z80daa.h */, + 94936B8E0A8E8DF900BDCACE /* z80dasm.cpp */, + 94936B8F0A8E8DF900BDCACE /* z80dasm.h */, + 94936B6E0A8E8DF900BDCACE /* m80.h */, + 94936B6F0A8E8DF900BDCACE /* m80daa.h */, + 94936B710A8E8DF900BDCACE /* m80tables.h */, + 94936B730A8E8DF900BDCACE /* mamewrap.cpp */, + 94936B740A8E8DF900BDCACE /* mamewrap.h */, + 94936B750A8E8DF900BDCACE /* mc6809.cpp */, + 94936B760A8E8DF900BDCACE /* mc6809.h */, + 94936B770A8E8DF900BDCACE /* nes_6502.cpp */, + 94936B600A8E8DF900BDCACE /* 6809infc.h */, + 94936B610A8E8DF900BDCACE /* cop.cpp */, + 94936B620A8E8DF900BDCACE /* cop.h */, + 94936B630A8E8DF900BDCACE /* copintf.cpp */, + 94936B640A8E8DF900BDCACE /* copintf.h */, + 94936B650A8E8DF900BDCACE /* cpu-debug.cpp */, + 94936B660A8E8DF900BDCACE /* cpu-debug.h */, + 94936B690A8E8DF900BDCACE /* generic_z80.h */, + 94936B6B0A8E8DF900BDCACE /* m80_internal_inline.h */, + 94936B6C0A8E8DF900BDCACE /* m80_internal.h */, + 94936B6D0A8E8DF900BDCACE /* m80.cpp */, + 94936B5F0A8E8DF900BDCACE /* 6809infc.cpp */, + ); + name = cpu; + sourceTree = ""; + }; + 94936BAE0A8E8E5700BDCACE /* game */ = { + isa = PBXGroup; + children = ( + 94A3668E0CADAC7000667ABE /* test_sb.cpp */, + 94A3668F0CADAC7000667ABE /* test_sb.h */, + 94936BAF0A8E8E5700BDCACE /* astron.cpp */, + 94936BB00A8E8E5700BDCACE /* astron.h */, + 94936BB10A8E8E5700BDCACE /* badlands.cpp */, + 94936BB20A8E8E5700BDCACE /* badlands.h */, + 94936BB30A8E8E5700BDCACE /* bega.cpp */, + 94936BB40A8E8E5700BDCACE /* bega.h */, + 94936BB50A8E8E5700BDCACE /* benchmark.cpp */, + 94936BB60A8E8E5700BDCACE /* benchmark.h */, + 94936BB70A8E8E5700BDCACE /* boardinfo.cpp */, + 94936BB80A8E8E5700BDCACE /* boardinfo.h */, + 94936BB90A8E8E5700BDCACE /* cliff.cpp */, + 94936BBA0A8E8E5700BDCACE /* cliff.h */, + 94936BBB0A8E8E5700BDCACE /* cobraconv.cpp */, + 94936BBC0A8E8E5700BDCACE /* cobraconv.h */, + 94936BBD0A8E8E5700BDCACE /* cputest.cpp */, + 94936BBE0A8E8E5700BDCACE /* cputest.h */, + 94936BC10A8E8E5700BDCACE /* esh.cpp */, + 94936BC20A8E8E5700BDCACE /* esh.h */, + 94936BC30A8E8E5700BDCACE /* ffr.cpp */, + 94936BC40A8E8E5700BDCACE /* ffr.h */, + 94936BC50A8E8E5700BDCACE /* firefox.cpp */, + 94936BC60A8E8E5700BDCACE /* firefox.h */, + 94936BC70A8E8E5700BDCACE /* game.cpp */, + 94936BC80A8E8E5700BDCACE /* game.h */, + 94936BC90A8E8E5700BDCACE /* gpworld.cpp */, + 94936BCA0A8E8E5700BDCACE /* gpworld.h */, + 94936BCB0A8E8E5700BDCACE /* interstellar.cpp */, + 94936BCC0A8E8E5700BDCACE /* interstellar.h */, + 94936BCD0A8E8E5700BDCACE /* lair.cpp */, + 94936BCE0A8E8E5700BDCACE /* lair.h */, + 94936BCF0A8E8E5700BDCACE /* lair2.cpp */, + 94936BD00A8E8E5700BDCACE /* lair2.h */, + 94936BD10A8E8E5700BDCACE /* laireuro.cpp */, + 94936BD20A8E8E5700BDCACE /* laireuro.h */, + 94936BD30A8E8E5700BDCACE /* lgp.cpp */, + 94936BD40A8E8E5700BDCACE /* lgp.h */, + 94936BD50A8E8E5700BDCACE /* mach3.cpp */, + 94936BD60A8E8E5700BDCACE /* mach3.h */, + 94936BD80A8E8E5700BDCACE /* multicputest.cpp */, + 94936BD90A8E8E5700BDCACE /* multicputest.h */, + 94936BDA0A8E8E5700BDCACE /* releasetest.cpp */, + 94936BDB0A8E8E5700BDCACE /* releasetest.h */, + 94936BDC0A8E8E5700BDCACE /* seektest.cpp */, + 94936BDD0A8E8E5700BDCACE /* seektest.h */, + 94936BDE0A8E8E5700BDCACE /* speedtest.cpp */, + 94936BDF0A8E8E5700BDCACE /* speedtest.h */, + 94936BE00A8E8E5700BDCACE /* starrider.cpp */, + 94936BE10A8E8E5700BDCACE /* starrider.h */, + 94936BE20A8E8E5700BDCACE /* superd.cpp */, + 94936BE30A8E8E5700BDCACE /* superd.h */, + 94936BE40A8E8E5700BDCACE /* thayers.cpp */, + 94936BE50A8E8E5700BDCACE /* thayers.h */, + 94936BE60A8E8E5700BDCACE /* timetrav.cpp */, + 94936BE70A8E8E5700BDCACE /* timetrav.h */, + ); + name = game; + path = ../game; + sourceTree = ""; + }; + 94936C050A8E8E7100BDCACE /* io */ = { + isa = PBXGroup; + children = ( + 94A3664E0CADAB1900667ABE /* logger_console.cpp */, + 94A3664F0CADAB1900667ABE /* logger_console.h */, + 94A366500CADAB1900667ABE /* logger_factory.cpp */, + 94A366510CADAB1900667ABE /* logger_factory.h */, + 94A366520CADAB1900667ABE /* logger.cpp */, + 94A366530CADAB1900667ABE /* logger.h */, + 94936C060A8E8E7100BDCACE /* cmdline.cpp */, + 94936C070A8E8E7100BDCACE /* cmdline.h */, + 94936C080A8E8E7100BDCACE /* conin.cpp */, + 94936C090A8E8E7100BDCACE /* conin.h */, + 94936C0A0A8E8E7100BDCACE /* conout.cpp */, + 94936C0B0A8E8E7100BDCACE /* conout.h */, + 94936C0C0A8E8E7100BDCACE /* dll.h */, + 94936C0D0A8E8E7100BDCACE /* error.cpp */, + 94936C0E0A8E8E7100BDCACE /* error.h */, + 94936C0F0A8E8E7100BDCACE /* fileparse.cpp */, + 94936C100A8E8E7100BDCACE /* fileparse.h */, + 94936C110A8E8E7100BDCACE /* homedir.cpp */, + 94936C120A8E8E7100BDCACE /* homedir.h */, + 94936C130A8E8E7100BDCACE /* input.cpp */, + 94936C140A8E8E7100BDCACE /* input.h */, + 94936C160A8E8E7100BDCACE /* mpo_fileio.cpp */, + 94936C170A8E8E7100BDCACE /* mpo_fileio.h */, + 94936C180A8E8E7100BDCACE /* mpo_mem.h */, + 94936C190A8E8E7100BDCACE /* my_stdio.h */, + 94936C1A0A8E8E7100BDCACE /* network.cpp */, + 94936C1B0A8E8E7100BDCACE /* network.h */, + 94936C1C0A8E8E7100BDCACE /* numstr.cpp */, + 94936C1D0A8E8E7100BDCACE /* numstr.h */, + 94936C200A8E8E7100BDCACE /* parallel.cpp */, + 94936C210A8E8E7100BDCACE /* parallel.h */, + 94936C220A8E8E7100BDCACE /* serial.cpp */, + 94936C230A8E8E7100BDCACE /* serial.h */, + 94936C240A8E8E7100BDCACE /* sram.cpp */, + 94936C250A8E8E7100BDCACE /* sram.h */, + 94936C260A8E8E7100BDCACE /* unzip.cpp */, + 94936C270A8E8E7100BDCACE /* unzip.h */, + ); + name = io; + path = ../io; + sourceTree = ""; + }; + 94936C380A8E8E9C00BDCACE /* ldp-in */ = { + isa = PBXGroup; + children = ( + 94936C390A8E8E9C00BDCACE /* ldp1000.cpp */, + 94936C3A0A8E8E9C00BDCACE /* ldp1000.h */, + 94936C3B0A8E8E9C00BDCACE /* ldv1000.cpp */, + 94936C3C0A8E8E9C00BDCACE /* ldv1000.h */, + 94936C3E0A8E8E9C00BDCACE /* pr7820.cpp */, + 94936C3F0A8E8E9C00BDCACE /* pr7820.h */, + 94936C400A8E8E9C00BDCACE /* pr8210.cpp */, + 94936C410A8E8E9C00BDCACE /* pr8210.h */, + 94936C420A8E8E9C00BDCACE /* vip9500sg.cpp */, + 94936C430A8E8E9C00BDCACE /* vip9500sg.h */, + 94936C440A8E8E9C00BDCACE /* vp380.cpp */, + 94936C450A8E8E9C00BDCACE /* vp380.h */, + 94936C460A8E8E9C00BDCACE /* vp931.cpp */, + 94936C470A8E8E9C00BDCACE /* vp931.h */, + 94936C480A8E8E9C00BDCACE /* vp932.cpp */, + 94936C490A8E8E9C00BDCACE /* vp932.h */, + ); + name = "ldp-in"; + path = "../ldp-in"; + sourceTree = ""; + }; + 94936C530A8E8EAB00BDCACE /* ldp-out */ = { + isa = PBXGroup; + children = ( + 94885A650A8FF28A000B5138 /* ldp-vldp-audio.cpp */, + 94936C600A8E8EAB00BDCACE /* ldp-vldp.h */, + 94936C540A8E8EAB00BDCACE /* framemod.cpp */, + 94936C550A8E8EAB00BDCACE /* framemod.h */, + 94936C560A8E8EAB00BDCACE /* hitachi.cpp */, + 94936C570A8E8EAB00BDCACE /* hitachi.h */, + 94936C580A8E8EAB00BDCACE /* ld-v6000.cpp */, + 94936C590A8E8EAB00BDCACE /* ld-v6000.h */, + 94936C5A0A8E8EAB00BDCACE /* ldp-combo.cpp */, + 94936C5B0A8E8EAB00BDCACE /* ldp-combo.h */, + 94936C5D0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp */, + 94936C5E0A8E8EAB00BDCACE /* ldp-vldp-gl.h */, + 94936C5F0A8E8EAB00BDCACE /* ldp-vldp.cpp */, + 94936C610A8E8EAB00BDCACE /* ldp.cpp */, + 94936C620A8E8EAB00BDCACE /* ldp.h */, + 94936C640A8E8EAB00BDCACE /* philips.cpp */, + 94936C650A8E8EAB00BDCACE /* philips.h */, + 94936C660A8E8EAB00BDCACE /* pioneer.cpp */, + 94936C670A8E8EAB00BDCACE /* pioneer.h */, + 94936C680A8E8EAB00BDCACE /* sony.cpp */, + 94936C690A8E8EAB00BDCACE /* sony.h */, + ); + name = "ldp-out"; + path = "../ldp-out"; + sourceTree = ""; + }; + 94936C760A8E8EBF00BDCACE /* sound */ = { + isa = PBXGroup; + children = ( + 9453E3350C10C64E000EFDC2 /* mix.cpp */, + 9453E3360C10C64E000EFDC2 /* mix.h */, + 94E91AED0B23463200B51FA6 /* samples.cpp */, + 94E91AEE0B23463200B51FA6 /* samples.h */, + 94936C770A8E8EBF00BDCACE /* dac.cpp */, + 94936C780A8E8EBF00BDCACE /* dac.h */, + 94936C790A8E8EBF00BDCACE /* gisound.cpp */, + 94936C7A0A8E8EBF00BDCACE /* gisound.h */, + 94936C7C0A8E8EBF00BDCACE /* pc_beeper.cpp */, + 94936C7D0A8E8EBF00BDCACE /* pc_beeper.h */, + 94936C7E0A8E8EBF00BDCACE /* sn_intf.cpp */, + 94936C7F0A8E8EBF00BDCACE /* sn_intf.h */, + 94936C800A8E8EBF00BDCACE /* sound.cpp */, + 94936C810A8E8EBF00BDCACE /* sound.h */, + 94936C820A8E8EBF00BDCACE /* ssi263.cpp */, + 94936C830A8E8EBF00BDCACE /* ssi263.h */, + 94936C840A8E8EBF00BDCACE /* tms9919-sdl.cpp */, + 94936C850A8E8EBF00BDCACE /* tms9919-sdl.hpp */, + 94936C860A8E8EBF00BDCACE /* tms9919.cpp */, + 94936C870A8E8EBF00BDCACE /* tms9919.hpp */, + 94936C880A8E8EBF00BDCACE /* tonegen.cpp */, + 94936C890A8E8EBF00BDCACE /* tonegen.h */, + 94936C8A0A8E8EBF00BDCACE /* tqsynth.cpp */, + 94936C8B0A8E8EBF00BDCACE /* tqsynth.h */, + ); + name = sound; + path = ../sound; + sourceTree = ""; + }; + 94936C970A8E8EE200BDCACE /* timer */ = { + isa = PBXGroup; + children = ( + 94936C990A8E8EE200BDCACE /* timer.cpp */, + 94936C9A0A8E8EE200BDCACE /* timer.h */, + ); + name = timer; + path = ../timer; + sourceTree = ""; + }; + 94936C9B0A8E8EE200BDCACE /* video */ = { + isa = PBXGroup; + children = ( + 94936C9C0A8E8EE200BDCACE /* blend.cpp */, + 94936C9D0A8E8EE200BDCACE /* blend.h */, + 94936CA00A8E8EE200BDCACE /* led.cpp */, + 94936CA10A8E8EE200BDCACE /* led.h */, + 94936CA40A8E8EE200BDCACE /* palette.cpp */, + 94936CA50A8E8EE200BDCACE /* palette.h */, + 94936CA80A8E8EE200BDCACE /* rgb2yuv.cpp */, + 94936CA90A8E8EE200BDCACE /* rgb2yuv.h */, + 94936CAC0A8E8EE200BDCACE /* SDL_Console.cpp */, + 94936CAD0A8E8EE200BDCACE /* SDL_Console.h */, + 94936CAE0A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp */, + 94936CAF0A8E8EE200BDCACE /* SDL_ConsoleCommands.h */, + 94936CB00A8E8EE200BDCACE /* SDL_DrawText.cpp */, + 94936CB10A8E8EE200BDCACE /* SDL_DrawText.h */, + 94936CB30A8E8EE200BDCACE /* tms9128nl.cpp */, + 94936CB40A8E8EE200BDCACE /* tms9128nl.h */, + 94936CB50A8E8EE200BDCACE /* video.cpp */, + 94936CB60A8E8EE200BDCACE /* video.h */, + 94936CB70A8E8EE200BDCACE /* yuv2rgb.c */, + 94936CB80A8E8EE200BDCACE /* yuv2rgb.h */, + 94936CB90A8E8EE200BDCACE /* yuv2rgb_lookup.h */, + ); + name = video; + path = ../video; + sourceTree = ""; + }; + 94936DE10A8E99C300BDCACE /* x86 */ = { + isa = PBXGroup; + children = ( + 94936DE40A8E99C300BDCACE /* i86.cpp */, + 94936DE50A8E99C300BDCACE /* i86.h */, + 94936DE60A8E99C300BDCACE /* i86dasm.cpp */, + ); + name = x86; + path = ../cpu/x86; + sourceTree = ""; + }; + 94A366040CADA83800667ABE /* scoreboard */ = { + isa = PBXGroup; + children = ( + 94A366050CADA86700667ABE /* hw_scoreboard.cpp */, + 94A366060CADA86700667ABE /* hw_scoreboard.h */, + 94A366070CADA86700667ABE /* img_scoreboard.cpp */, + 94A366080CADA86700667ABE /* img_scoreboard.h */, + 94A366090CADA86700667ABE /* null_scoreboard.cpp */, + 94A3660A0CADA86700667ABE /* null_scoreboard.h */, + 94A3660B0CADA86700667ABE /* overlay_scoreboard.cpp */, + 94A3660C0CADA86700667ABE /* overlay_scoreboard.h */, + 94A3660D0CADA86700667ABE /* scoreboard_collection.cpp */, + 94A3660E0CADA86700667ABE /* scoreboard_collection.h */, + 94A3660F0CADA86700667ABE /* scoreboard_factory.cpp */, + 94A366100CADA86700667ABE /* scoreboard_factory.h */, + 94A366110CADA86700667ABE /* scoreboard_howto.txt */, + 94A366120CADA86700667ABE /* scoreboard_interface.cpp */, + 94A366130CADA86700667ABE /* scoreboard_interface.h */, + ); + name = scoreboard; + sourceTree = ""; + }; + 94A98ED60C16FB360072471F /* Singe */ = { + isa = PBXGroup; + children = ( + 94A990F00C16FF870072471F /* SDL_image.framework */, + 94A990F10C16FF870072471F /* SDL_ttf.framework */, + 94A98EE00C16FBA40072471F /* lapi.c */, + 94A98EE10C16FBA40072471F /* lapi.h */, + 94A98EE20C16FBA40072471F /* lauxlib.c */, + 94A98EE30C16FBA40072471F /* lauxlib.h */, + 94A98EE40C16FBA40072471F /* lbaselib.c */, + 94A98EE50C16FBA40072471F /* lcode.c */, + 94A98EE60C16FBA40072471F /* lcode.h */, + 94A98EE70C16FBA40072471F /* ldblib.c */, + 94A98EE80C16FBA40072471F /* ldebug.c */, + 94A98EE90C16FBA40072471F /* ldebug.h */, + 94A98EEA0C16FBA40072471F /* ldo.c */, + 94A98EEB0C16FBA40072471F /* ldo.h */, + 94A98EEC0C16FBA40072471F /* ldump.c */, + 94A98EED0C16FBA40072471F /* lfunc.c */, + 94A98EEE0C16FBA40072471F /* lfunc.h */, + 94A98EEF0C16FBA40072471F /* lgc.c */, + 94A98EF00C16FBA40072471F /* lgc.h */, + 94A98EF10C16FBA40072471F /* linit.c */, + 94A98EF20C16FBA40072471F /* liolib.c */, + 94A98EF30C16FBA40072471F /* llex.c */, + 94A98EF40C16FBA40072471F /* llex.h */, + 94A98EF50C16FBA40072471F /* llimits.h */, + 94A98EF60C16FBA40072471F /* lmathlib.c */, + 94A98EF70C16FBA40072471F /* lmem.c */, + 94A98EF80C16FBA40072471F /* lmem.h */, + 94A98EF90C16FBA40072471F /* loadlib.c */, + 94A98EFA0C16FBA40072471F /* lobject.c */, + 94A98EFB0C16FBA40072471F /* lobject.h */, + 94A98EFC0C16FBA40072471F /* lopcodes.c */, + 94A98EFD0C16FBA40072471F /* lopcodes.h */, + 94A98EFE0C16FBA40072471F /* loslib.c */, + 94A98EFF0C16FBA40072471F /* lparser.c */, + 94A98F000C16FBA40072471F /* lparser.h */, + 94A98F010C16FBA40072471F /* lstate.c */, + 94A98F020C16FBA40072471F /* lstate.h */, + 94A98F030C16FBA40072471F /* lstring.c */, + 94A98F040C16FBA40072471F /* lstring.h */, + 94A98F050C16FBA40072471F /* lstrlib.c */, + 94A98F060C16FBA40072471F /* ltable.c */, + 94A98F070C16FBA40072471F /* ltable.h */, + 94A98F080C16FBA40072471F /* ltablib.c */, + 94A98F090C16FBA40072471F /* ltm.c */, + 94A98F0A0C16FBA40072471F /* ltm.h */, + 94A98F0B0C16FBA40072471F /* lua.h */, + 94A98F0C0C16FBA40072471F /* luaconf.h */, + 94A98F0D0C16FBA40072471F /* lualib.h */, + 94A98F0E0C16FBA40072471F /* lundump.c */, + 94A98F0F0C16FBA40072471F /* lundump.h */, + 94A98F100C16FBA40072471F /* lvm.c */, + 94A98F110C16FBA40072471F /* lvm.h */, + 94A98F120C16FBA40072471F /* lzio.c */, + 94A98F130C16FBA40072471F /* lzio.h */, + 94A98F140C16FBA40072471F /* print.c */, + 94A98F150C16FBA40072471F /* singe_interface.h */, + 94A98F160C16FBA40072471F /* singeproxy.cpp */, + 94A98F170C16FBA40072471F /* singeproxy.h */, + 94A98EDC0C16FB8E0072471F /* singe.cpp */, + 94A98EDD0C16FB8E0072471F /* singe.h */, + ); + name = Singe; + sourceTree = ""; + }; + 94FD80670CBA9AAB0023EF96 /* x86 Assembly */ = { + isa = PBXGroup; + children = ( + 94FD80F40CBA9DDA0023EF96 /* blend_mmx-gas.s */, + 94FD806B0CBA9AE00023EF96 /* rgb2yuv-gas.s */, + 94FD80680CBA9ACF0023EF96 /* mix_mmx-gas.s */, + ); + name = "x86 Assembly"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* Daphne */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Daphne" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + 94862D5E0A8EB56000AA9A46 /* Copy Bitmaps */, + 94862DCD0A8EB78300AA9A46 /* Copy Sounds */, + 94465B7B0A900708006FD484 /* Copy Frameworks */, + 94F97A580B39B2A000F29536 /* Copy Manifest */, + ); + buildRules = ( + 94E82BC70CBAAFB000B799C1 /* PBXBuildRule */, + 94FD81FD0CBAA7860023EF96 /* PBXBuildRule */, + ); + dependencies = ( + ); + name = Daphne; + productInstallPath = "$(HOME)/Applications"; + productName = Daphne; + productReference = 8D1107320486CEB800E47090 /* Daphne.app */; + productType = "com.apple.product-type.application"; + }; + 94A98F5A0C16FC770072471F /* Daphne+SINGE */ = { + isa = PBXNativeTarget; + buildConfigurationList = 94A9905C0C16FC780072471F /* Build configuration list for PBXNativeTarget "Daphne+SINGE" */; + buildPhases = ( + 94A98F5B0C16FC770072471F /* Resources */, + 94A98F5F0C16FC770072471F /* Sources */, + 94A98FDF0C16FC780072471F /* Frameworks */, + 94A98FE30C16FC780072471F /* Copy Bitmaps */, + 94A990110C16FC780072471F /* Copy Sounds */, + 94A990560C16FC780072471F /* Copy Frameworks */, + 94A9905A0C16FC780072471F /* Copy Manifest */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Daphne+SINGE"; + productInstallPath = "$(HOME)/Applications"; + productName = Daphne; + productReference = 94A9905F0C16FC780072471F /* Daphne.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Daphne" */; + compatibilityVersion = "Xcode 3.0"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* Daphne */; + projectDirPath = ""; + projectRoot = ..; + targets = ( + 8D1107260486CEB800E47090 /* Daphne */, + 94A98F5A0C16FC770072471F /* Daphne+SINGE */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 94936AE30A8E88F400BDCACE /* SDLMain.nib in Resources */, + 94AD92680AA00B7000C9CDC4 /* Daphne Icon.icns in Resources */, + 94F97A3A0B39B16300F29536 /* DaphneManifest.xml in Resources */, + 94A3662F0CADA86700667ABE /* scoreboard_howto.txt in Resources */, + 94B1CF790CB56E5B00A2DB19 /* daphne-changelog.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 94A98F5B0C16FC770072471F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 94A98F5C0C16FC770072471F /* SDLMain.nib in Resources */, + 94A98F5D0C16FC770072471F /* Daphne Icon.icns in Resources */, + 94A98F5E0C16FC770072471F /* DaphneManifest.xml in Resources */, + 94A366200CADA86700667ABE /* scoreboard_howto.txt in Resources */, + 94B1CF780CB56E5B00A2DB19 /* daphne-changelog.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 94FD81240CBAA10A0023EF96 /* blend_mmx-gas.s in Sources */, + 94FD81250CBAA10A0023EF96 /* rgb2yuv-gas.s in Sources */, + 94FD81260CBAA10A0023EF96 /* mix_mmx-gas.s in Sources */, + 94936AE20A8E88F400BDCACE /* SDLMain.m in Sources */, + 94936B4E0A8E8D4600BDCACE /* daphne.cpp in Sources */, + 94936B900A8E8DF900BDCACE /* 6809infc.cpp in Sources */, + 94936B910A8E8DF900BDCACE /* cop.cpp in Sources */, + 94936B920A8E8DF900BDCACE /* copintf.cpp in Sources */, + 94936B930A8E8DF900BDCACE /* cpu-debug.cpp in Sources */, + 94936B940A8E8DF900BDCACE /* cpu.cpp in Sources */, + 94936B960A8E8DF900BDCACE /* m80.cpp in Sources */, + 94936B990A8E8DF900BDCACE /* mamewrap.cpp in Sources */, + 94936B9A0A8E8DF900BDCACE /* mc6809.cpp in Sources */, + 94936B9B0A8E8DF900BDCACE /* nes_6502.cpp in Sources */, + 94936B9C0A8E8DF900BDCACE /* nes6502.cpp in Sources */, + 94936B9F0A8E8DF900BDCACE /* z80dasm.cpp in Sources */, + 94936BE80A8E8E5700BDCACE /* astron.cpp in Sources */, + 94936BE90A8E8E5700BDCACE /* badlands.cpp in Sources */, + 94936BEA0A8E8E5700BDCACE /* bega.cpp in Sources */, + 94936BEB0A8E8E5700BDCACE /* benchmark.cpp in Sources */, + 94936BEC0A8E8E5700BDCACE /* boardinfo.cpp in Sources */, + 94936BED0A8E8E5700BDCACE /* cliff.cpp in Sources */, + 94936BEE0A8E8E5700BDCACE /* cobraconv.cpp in Sources */, + 94936BEF0A8E8E5700BDCACE /* cputest.cpp in Sources */, + 94936BF10A8E8E5700BDCACE /* esh.cpp in Sources */, + 94936BF20A8E8E5700BDCACE /* ffr.cpp in Sources */, + 94936BF30A8E8E5700BDCACE /* firefox.cpp in Sources */, + 94936BF40A8E8E5700BDCACE /* game.cpp in Sources */, + 94936BF50A8E8E5700BDCACE /* gpworld.cpp in Sources */, + 94936BF60A8E8E5700BDCACE /* interstellar.cpp in Sources */, + 94936BF70A8E8E5700BDCACE /* lair.cpp in Sources */, + 94936BF80A8E8E5700BDCACE /* lair2.cpp in Sources */, + 94936BF90A8E8E5700BDCACE /* laireuro.cpp in Sources */, + 94936BFA0A8E8E5700BDCACE /* lgp.cpp in Sources */, + 94936BFB0A8E8E5700BDCACE /* mach3.cpp in Sources */, + 94936BFD0A8E8E5700BDCACE /* multicputest.cpp in Sources */, + 94936BFE0A8E8E5700BDCACE /* releasetest.cpp in Sources */, + 94936BFF0A8E8E5700BDCACE /* seektest.cpp in Sources */, + 94936C000A8E8E5700BDCACE /* speedtest.cpp in Sources */, + 94936C010A8E8E5700BDCACE /* starrider.cpp in Sources */, + 94936C020A8E8E5700BDCACE /* superd.cpp in Sources */, + 94936C030A8E8E5700BDCACE /* thayers.cpp in Sources */, + 94936C040A8E8E5700BDCACE /* timetrav.cpp in Sources */, + 94936C280A8E8E7100BDCACE /* cmdline.cpp in Sources */, + 94936C290A8E8E7100BDCACE /* conin.cpp in Sources */, + 94936C2A0A8E8E7100BDCACE /* conout.cpp in Sources */, + 94936C2B0A8E8E7100BDCACE /* error.cpp in Sources */, + 94936C2C0A8E8E7100BDCACE /* fileparse.cpp in Sources */, + 94936C2D0A8E8E7100BDCACE /* homedir.cpp in Sources */, + 94936C2E0A8E8E7100BDCACE /* input.cpp in Sources */, + 94936C300A8E8E7100BDCACE /* mpo_fileio.cpp in Sources */, + 94936C310A8E8E7100BDCACE /* network.cpp in Sources */, + 94936C320A8E8E7100BDCACE /* numstr.cpp in Sources */, + 94936C340A8E8E7100BDCACE /* parallel.cpp in Sources */, + 94936C350A8E8E7100BDCACE /* serial.cpp in Sources */, + 94936C360A8E8E7100BDCACE /* sram.cpp in Sources */, + 94936C370A8E8E7100BDCACE /* unzip.cpp in Sources */, + 94936C4A0A8E8E9C00BDCACE /* ldp1000.cpp in Sources */, + 94936C4B0A8E8E9C00BDCACE /* ldv1000.cpp in Sources */, + 94936C4D0A8E8E9C00BDCACE /* pr7820.cpp in Sources */, + 94936C4E0A8E8E9C00BDCACE /* pr8210.cpp in Sources */, + 94936C4F0A8E8E9C00BDCACE /* vip9500sg.cpp in Sources */, + 94936C500A8E8E9C00BDCACE /* vp380.cpp in Sources */, + 94936C510A8E8E9C00BDCACE /* vp931.cpp in Sources */, + 94936C520A8E8E9C00BDCACE /* vp932.cpp in Sources */, + 94936C6A0A8E8EAB00BDCACE /* framemod.cpp in Sources */, + 94936C6B0A8E8EAB00BDCACE /* hitachi.cpp in Sources */, + 94936C6C0A8E8EAB00BDCACE /* ld-v6000.cpp in Sources */, + 94936C6D0A8E8EAB00BDCACE /* ldp-combo.cpp in Sources */, + 94936C6F0A8E8EAB00BDCACE /* ldp-vldp-gl.cpp in Sources */, + 94936C700A8E8EAB00BDCACE /* ldp-vldp.cpp in Sources */, + 94936C710A8E8EAB00BDCACE /* ldp.cpp in Sources */, + 94936C730A8E8EAB00BDCACE /* philips.cpp in Sources */, + 94936C740A8E8EAB00BDCACE /* pioneer.cpp in Sources */, + 94936C750A8E8EAB00BDCACE /* sony.cpp in Sources */, + 94936C8C0A8E8EBF00BDCACE /* dac.cpp in Sources */, + 94936C8D0A8E8EBF00BDCACE /* gisound.cpp in Sources */, + 94936C8F0A8E8EBF00BDCACE /* pc_beeper.cpp in Sources */, + 94936C900A8E8EBF00BDCACE /* sn_intf.cpp in Sources */, + 94936C910A8E8EBF00BDCACE /* sound.cpp in Sources */, + 94936C920A8E8EBF00BDCACE /* ssi263.cpp in Sources */, + 94936C930A8E8EBF00BDCACE /* tms9919-sdl.cpp in Sources */, + 94936C940A8E8EBF00BDCACE /* tms9919.cpp in Sources */, + 94936C950A8E8EBF00BDCACE /* tonegen.cpp in Sources */, + 94936C960A8E8EBF00BDCACE /* tqsynth.cpp in Sources */, + 94936CBC0A8E8EE200BDCACE /* timer.cpp in Sources */, + 94936CBD0A8E8EE200BDCACE /* blend.cpp in Sources */, + 94936CC00A8E8EE200BDCACE /* led.cpp in Sources */, + 94936CC30A8E8EE200BDCACE /* palette.cpp in Sources */, + 94936CC60A8E8EE200BDCACE /* rgb2yuv.cpp in Sources */, + 94936CC80A8E8EE200BDCACE /* SDL_Console.cpp in Sources */, + 94936CC90A8E8EE200BDCACE /* SDL_ConsoleCommands.cpp in Sources */, + 94936CCA0A8E8EE200BDCACE /* SDL_DrawText.cpp in Sources */, + 94936CCC0A8E8EE200BDCACE /* tms9128nl.cpp in Sources */, + 94936CCD0A8E8EE200BDCACE /* video.cpp in Sources */, + 94936CCE0A8E8EE200BDCACE /* yuv2rgb.c in Sources */, + 94936DEE0A8E99C300BDCACE /* i86.cpp in Sources */, + 94936DEF0A8E99C300BDCACE /* i86dasm.cpp in Sources */, + 948858460A8FE2FC000B5138 /* video_out.c in Sources */, + 9488584A0A8FE2FC000B5138 /* video_out_sdl.c in Sources */, + 9488584C0A8FE2FC000B5138 /* yuv2rgb.c in Sources */, + 9488584D0A8FE2FC000B5138 /* yuv2rgb_mlib.c in Sources */, + 948858C40A8FE345000B5138 /* mpegscan.c in Sources */, + 948858C60A8FE345000B5138 /* vldp.c in Sources */, + 948858C90A8FE345000B5138 /* vldp_internal.c in Sources */, + 9488593E0A8FE5D5000B5138 /* alloc.c in Sources */, + 948859400A8FE5D5000B5138 /* cpu_accel.c in Sources */, + 948859410A8FE5D5000B5138 /* cpu_state.c in Sources */, + 948859420A8FE5D5000B5138 /* decode.c in Sources */, + 948859430A8FE5D5000B5138 /* header.c in Sources */, + 948859440A8FE5D5000B5138 /* idct.c in Sources */, + 948859450A8FE5D5000B5138 /* idct_alpha.c in Sources */, + 948859460A8FE5D5000B5138 /* idct_altivec.c in Sources */, + 948859470A8FE5D5000B5138 /* idct_mlib.c in Sources */, + 948859480A8FE5D5000B5138 /* idct_mmx.c in Sources */, + 9488594E0A8FE5D5000B5138 /* motion_comp.c in Sources */, + 9488594F0A8FE5D5000B5138 /* motion_comp_alpha.c in Sources */, + 948859500A8FE5D5000B5138 /* motion_comp_altivec.c in Sources */, + 948859510A8FE5D5000B5138 /* motion_comp_mlib.c in Sources */, + 948859520A8FE5D5000B5138 /* motion_comp_mmx.c in Sources */, + 948859540A8FE5D5000B5138 /* slice.c in Sources */, + 94885A660A8FF28A000B5138 /* ldp-vldp-audio.cpp in Sources */, + 9414C1CD0A9106C900F8A711 /* video_out_dx.c in Sources */, + 9414C1CE0A9106C900F8A711 /* video_out_null.c in Sources */, + 9414C1CF0A9106C900F8A711 /* video_out_pgm.c in Sources */, + 9414C1D00A9106C900F8A711 /* video_out_x11.c in Sources */, + 94E91AEF0B23463200B51FA6 /* samples.cpp in Sources */, + 9453E3370C10C64E000EFDC2 /* mix.cpp in Sources */, + 94A366230CADA86700667ABE /* hw_scoreboard.cpp in Sources */, + 94A366250CADA86700667ABE /* img_scoreboard.cpp in Sources */, + 94A366270CADA86700667ABE /* null_scoreboard.cpp in Sources */, + 94A366290CADA86700667ABE /* overlay_scoreboard.cpp in Sources */, + 94A3662B0CADA86700667ABE /* scoreboard_collection.cpp in Sources */, + 94A3662D0CADA86700667ABE /* scoreboard_factory.cpp in Sources */, + 94A366300CADA86700667ABE /* scoreboard_interface.cpp in Sources */, + 94A3665A0CADAB1900667ABE /* logger_console.cpp in Sources */, + 94A3665C0CADAB1900667ABE /* logger_factory.cpp in Sources */, + 94A3665E0CADAB1900667ABE /* logger.cpp in Sources */, + 94A366920CADAC7000667ABE /* test_sb.cpp in Sources */, + 946EB6B60CB83D8C003FE54F /* yuv2rgb_mmx.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 94A98F5F0C16FC770072471F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 94A98F600C16FC770072471F /* SDLMain.m in Sources */, + 94A98F610C16FC770072471F /* daphne.cpp in Sources */, + 94A98F620C16FC770072471F /* 6809infc.cpp in Sources */, + 94A98F630C16FC770072471F /* cop.cpp in Sources */, + 94A98F640C16FC770072471F /* copintf.cpp in Sources */, + 94A98F650C16FC770072471F /* cpu-debug.cpp in Sources */, + 94A98F660C16FC770072471F /* cpu.cpp in Sources */, + 94A98F670C16FC770072471F /* m80.cpp in Sources */, + 94A98F680C16FC770072471F /* mamewrap.cpp in Sources */, + 94A98F690C16FC770072471F /* mc6809.cpp in Sources */, + 94A98F6A0C16FC770072471F /* nes_6502.cpp in Sources */, + 94A98F6B0C16FC770072471F /* nes6502.cpp in Sources */, + 94A98F6C0C16FC770072471F /* z80dasm.cpp in Sources */, + 94A98F6D0C16FC770072471F /* astron.cpp in Sources */, + 94A98F6E0C16FC770072471F /* badlands.cpp in Sources */, + 94A98F6F0C16FC770072471F /* bega.cpp in Sources */, + 94A98F700C16FC770072471F /* benchmark.cpp in Sources */, + 94A98F710C16FC770072471F /* boardinfo.cpp in Sources */, + 94A98F720C16FC770072471F /* cliff.cpp in Sources */, + 94A98F730C16FC770072471F /* cobraconv.cpp in Sources */, + 94A98F740C16FC770072471F /* cputest.cpp in Sources */, + 94A98F750C16FC770072471F /* esh.cpp in Sources */, + 94A98F760C16FC770072471F /* ffr.cpp in Sources */, + 94A98F770C16FC770072471F /* firefox.cpp in Sources */, + 94A98F780C16FC770072471F /* game.cpp in Sources */, + 94A98F790C16FC770072471F /* gpworld.cpp in Sources */, + 94A98F7A0C16FC770072471F /* interstellar.cpp in Sources */, + 94A98F7B0C16FC770072471F /* lair.cpp in Sources */, + 94A98F7C0C16FC770072471F /* lair2.cpp in Sources */, + 94A98F7D0C16FC770072471F /* laireuro.cpp in Sources */, + 94A98F7E0C16FC770072471F /* lgp.cpp in Sources */, + 94A98F7F0C16FC770072471F /* mach3.cpp in Sources */, + 94A98F800C16FC770072471F /* multicputest.cpp in Sources */, + 94A98F810C16FC770072471F /* releasetest.cpp in Sources */, + 94A98F820C16FC770072471F /* seektest.cpp in Sources */, + 94A98F830C16FC770072471F /* speedtest.cpp in Sources */, + 94A98F840C16FC770072471F /* starrider.cpp in Sources */, + 94A98F850C16FC770072471F /* superd.cpp in Sources */, + 94A98F860C16FC770072471F /* thayers.cpp in Sources */, + 94A98F870C16FC780072471F /* timetrav.cpp in Sources */, + 94A98F880C16FC780072471F /* cmdline.cpp in Sources */, + 94A98F890C16FC780072471F /* conin.cpp in Sources */, + 94A98F8A0C16FC780072471F /* conout.cpp in Sources */, + 94A98F8B0C16FC780072471F /* error.cpp in Sources */, + 94A98F8C0C16FC780072471F /* fileparse.cpp in Sources */, + 94A98F8D0C16FC780072471F /* homedir.cpp in Sources */, + 94A98F8E0C16FC780072471F /* input.cpp in Sources */, + 94A98F8F0C16FC780072471F /* mpo_fileio.cpp in Sources */, + 94A98F900C16FC780072471F /* network.cpp in Sources */, + 94A98F910C16FC780072471F /* numstr.cpp in Sources */, + 94A98F920C16FC780072471F /* parallel.cpp in Sources */, + 94A98F930C16FC780072471F /* serial.cpp in Sources */, + 94A98F940C16FC780072471F /* sram.cpp in Sources */, + 94A98F950C16FC780072471F /* unzip.cpp in Sources */, + 94A98F960C16FC780072471F /* ldp1000.cpp in Sources */, + 94A98F970C16FC780072471F /* ldv1000.cpp in Sources */, + 94A98F980C16FC780072471F /* pr7820.cpp in Sources */, + 94A98F990C16FC780072471F /* pr8210.cpp in Sources */, + 94A98F9A0C16FC780072471F /* vip9500sg.cpp in Sources */, + 94A98F9B0C16FC780072471F /* vp380.cpp in Sources */, + 94A98F9C0C16FC780072471F /* vp931.cpp in Sources */, + 94A98F9D0C16FC780072471F /* vp932.cpp in Sources */, + 94A98F9E0C16FC780072471F /* framemod.cpp in Sources */, + 94A98F9F0C16FC780072471F /* hitachi.cpp in Sources */, + 94A98FA00C16FC780072471F /* ld-v6000.cpp in Sources */, + 94A98FA10C16FC780072471F /* ldp-combo.cpp in Sources */, + 94A98FA20C16FC780072471F /* ldp-vldp-gl.cpp in Sources */, + 94A98FA30C16FC780072471F /* ldp-vldp.cpp in Sources */, + 94A98FA40C16FC780072471F /* ldp.cpp in Sources */, + 94A98FA50C16FC780072471F /* philips.cpp in Sources */, + 94A98FA60C16FC780072471F /* pioneer.cpp in Sources */, + 94A98FA70C16FC780072471F /* sony.cpp in Sources */, + 94A98FA80C16FC780072471F /* dac.cpp in Sources */, + 94A98FA90C16FC780072471F /* gisound.cpp in Sources */, + 94A98FAA0C16FC780072471F /* pc_beeper.cpp in Sources */, + 94A98FAB0C16FC780072471F /* sn_intf.cpp in Sources */, + 94A98FAC0C16FC780072471F /* sound.cpp in Sources */, + 94A98FAD0C16FC780072471F /* ssi263.cpp in Sources */, + 94A98FAE0C16FC780072471F /* tms9919-sdl.cpp in Sources */, + 94A98FAF0C16FC780072471F /* tms9919.cpp in Sources */, + 94A98FB00C16FC780072471F /* tonegen.cpp in Sources */, + 94A98FB10C16FC780072471F /* tqsynth.cpp in Sources */, + 94A98FB20C16FC780072471F /* timer.cpp in Sources */, + 94A98FB30C16FC780072471F /* blend.cpp in Sources */, + 94A98FB40C16FC780072471F /* led.cpp in Sources */, + 94A98FB50C16FC780072471F /* palette.cpp in Sources */, + 94A98FB60C16FC780072471F /* rgb2yuv.cpp in Sources */, + 94A98FB80C16FC780072471F /* SDL_Console.cpp in Sources */, + 94A98FB90C16FC780072471F /* SDL_ConsoleCommands.cpp in Sources */, + 94A98FBA0C16FC780072471F /* SDL_DrawText.cpp in Sources */, + 94A98FBB0C16FC780072471F /* tms9128nl.cpp in Sources */, + 94A98FBC0C16FC780072471F /* video.cpp in Sources */, + 94A98FBD0C16FC780072471F /* yuv2rgb.c in Sources */, + 94A98FBE0C16FC780072471F /* i86.cpp in Sources */, + 94A98FBF0C16FC780072471F /* i86dasm.cpp in Sources */, + 94A98FC00C16FC780072471F /* video_out.c in Sources */, + 94A98FC10C16FC780072471F /* video_out_sdl.c in Sources */, + 94A98FC20C16FC780072471F /* yuv2rgb.c in Sources */, + 94A98FC30C16FC780072471F /* yuv2rgb_mlib.c in Sources */, + 94A98FC50C16FC780072471F /* mpegscan.c in Sources */, + 94A98FC60C16FC780072471F /* vldp.c in Sources */, + 94A98FC70C16FC780072471F /* vldp_internal.c in Sources */, + 94A98FC80C16FC780072471F /* alloc.c in Sources */, + 94A98FC90C16FC780072471F /* cpu_accel.c in Sources */, + 94A98FCA0C16FC780072471F /* cpu_state.c in Sources */, + 94A98FCB0C16FC780072471F /* decode.c in Sources */, + 94A98FCC0C16FC780072471F /* header.c in Sources */, + 94A98FCD0C16FC780072471F /* idct.c in Sources */, + 94A98FCE0C16FC780072471F /* idct_alpha.c in Sources */, + 94A98FCF0C16FC780072471F /* idct_altivec.c in Sources */, + 94A98FD00C16FC780072471F /* idct_mlib.c in Sources */, + 94A98FD10C16FC780072471F /* idct_mmx.c in Sources */, + 94A98FD20C16FC780072471F /* motion_comp.c in Sources */, + 94A98FD30C16FC780072471F /* motion_comp_alpha.c in Sources */, + 94A98FD40C16FC780072471F /* motion_comp_altivec.c in Sources */, + 94A98FD50C16FC780072471F /* motion_comp_mlib.c in Sources */, + 94A98FD60C16FC780072471F /* motion_comp_mmx.c in Sources */, + 94A98FD70C16FC780072471F /* slice.c in Sources */, + 94A98FD80C16FC780072471F /* ldp-vldp-audio.cpp in Sources */, + 94A98FD90C16FC780072471F /* video_out_dx.c in Sources */, + 94A98FDA0C16FC780072471F /* video_out_null.c in Sources */, + 94A98FDB0C16FC780072471F /* video_out_pgm.c in Sources */, + 94A98FDC0C16FC780072471F /* video_out_x11.c in Sources */, + 94A98FDD0C16FC780072471F /* samples.cpp in Sources */, + 94A98FDE0C16FC780072471F /* mix.cpp in Sources */, + 94A990620C16FC8D0072471F /* lapi.c in Sources */, + 94A990640C16FC8D0072471F /* lauxlib.c in Sources */, + 94A990660C16FC8D0072471F /* lbaselib.c in Sources */, + 94A990670C16FC8D0072471F /* lcode.c in Sources */, + 94A990690C16FC8D0072471F /* ldblib.c in Sources */, + 94A9906A0C16FC8D0072471F /* ldebug.c in Sources */, + 94A9906C0C16FC8D0072471F /* ldo.c in Sources */, + 94A9906E0C16FC8D0072471F /* ldump.c in Sources */, + 94A9906F0C16FC8D0072471F /* lfunc.c in Sources */, + 94A990710C16FC8D0072471F /* lgc.c in Sources */, + 94A990730C16FC8D0072471F /* linit.c in Sources */, + 94A990740C16FC8D0072471F /* liolib.c in Sources */, + 94A990750C16FC8D0072471F /* llex.c in Sources */, + 94A990780C16FC8D0072471F /* lmathlib.c in Sources */, + 94A990790C16FC8D0072471F /* lmem.c in Sources */, + 94A9907B0C16FC8D0072471F /* loadlib.c in Sources */, + 94A9907C0C16FC8D0072471F /* lobject.c in Sources */, + 94A9907E0C16FC8D0072471F /* lopcodes.c in Sources */, + 94A990800C16FC8D0072471F /* loslib.c in Sources */, + 94A990810C16FC8D0072471F /* lparser.c in Sources */, + 94A990830C16FC8D0072471F /* lstate.c in Sources */, + 94A990850C16FC8D0072471F /* lstring.c in Sources */, + 94A990870C16FC8D0072471F /* lstrlib.c in Sources */, + 94A990880C16FC8D0072471F /* ltable.c in Sources */, + 94A9908A0C16FC8D0072471F /* ltablib.c in Sources */, + 94A9908B0C16FC8D0072471F /* ltm.c in Sources */, + 94A990900C16FC8D0072471F /* lundump.c in Sources */, + 94A990920C16FC8D0072471F /* lvm.c in Sources */, + 94A990940C16FC8D0072471F /* lzio.c in Sources */, + 94A990960C16FC8D0072471F /* print.c in Sources */, + 94A990980C16FC8D0072471F /* singeproxy.cpp in Sources */, + 94A9909A0C16FC8D0072471F /* singe.cpp in Sources */, + 94A366140CADA86700667ABE /* hw_scoreboard.cpp in Sources */, + 94A366160CADA86700667ABE /* img_scoreboard.cpp in Sources */, + 94A366180CADA86700667ABE /* null_scoreboard.cpp in Sources */, + 94A3661A0CADA86700667ABE /* overlay_scoreboard.cpp in Sources */, + 94A3661C0CADA86700667ABE /* scoreboard_collection.cpp in Sources */, + 94A3661E0CADA86700667ABE /* scoreboard_factory.cpp in Sources */, + 94A366210CADA86700667ABE /* scoreboard_interface.cpp in Sources */, + 94A366540CADAB1900667ABE /* logger_console.cpp in Sources */, + 94A366560CADAB1900667ABE /* logger_factory.cpp in Sources */, + 94A366580CADAB1900667ABE /* logger.cpp in Sources */, + 94A366900CADAC7000667ABE /* test_sb.cpp in Sources */, + 946EB6B70CB83D8C003FE54F /* yuv2rgb_mmx.c in Sources */, + 94FD806A0CBA9ACF0023EF96 /* mix_mmx-gas.s in Sources */, + 94FD806D0CBA9AE00023EF96 /* rgb2yuv-gas.s in Sources */, + 94FD80F60CBA9DDA0023EF96 /* blend_mmx-gas.s in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 94A9905D0C16FC780072471F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + UNIX, + MAC_OSX, + STATIC_VLDP, + STATIC_SINGE, + BUILD_SINGE, + ); + HEADER_SEARCH_PATHS = ( + /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL_ttf.framework/Headers, + /Library/Frameworks/SDL_image.framework/Headers, + ); + INFOPLIST_FILE = "/Users/derekstutsman/Documents/Development/daphne/src/macosx/Info copy.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Daphne; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Debug; + }; + 94A9905E0C16FC780072471F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = ( + UNIX, + MAC_OSX, + STATIC_VLDP, + STATIC_SINGE, + BUILD_SINGE, + ); + HEADER_SEARCH_PATHS = ( + /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL_ttf.framework/Headers, + /Library/Frameworks/SDL_image.framework/Headers, + ); + INFOPLIST_FILE = "/Users/derekstutsman/Documents/Development/daphne/src/macosx/Info copy.plist"; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Daphne; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../../../GLEW/build/Release\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Daphne; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../../../GLEW/build/Release\""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = Daphne; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; + GCC_ALTIVEC_EXTENSIONS = YES; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; + GCC_ENABLE_SSE3_EXTENSIONS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + UNIX, + MAC_OSX, + STATIC_VLDP, + USE_OPENGL, + ); + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 3.3; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/GLExtensionWrangler.framework/Headers, + ); + MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; + OTHER_CPLUSPLUSFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + SDL, + "-framework", + Ogg, + "-framework", + Vorbis, + "-framework", + Foundation, + "-framework", + AppKit, + "-framework", + GLExtensionWrangler, + "-framework", + OpenGL, + "-lz", + ); + PER_ARCH_CFLAGS_i386 = "-mmmx"; + PER_ARCH_CFLAGS_ppc = "-faltivec"; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; + GCC_ALTIVEC_EXTENSIONS = YES; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; + GCC_ENABLE_SSE3_EXTENSIONS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + UNIX, + MAC_OSX, + STATIC_VLDP, + USE_OPENGL, + ); + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 3.3; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/GLExtensionWrangler.framework/Headers, + ); + MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; + OTHER_CPLUSPLUSFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + SDL, + "-framework", + Ogg, + "-framework", + Vorbis, + "-framework", + Foundation, + "-framework", + AppKit, + "-framework", + GLExtensionWrangler, + "-framework", + OpenGL, + "-lz", + ); + PER_ARCH_CFLAGS_i386 = "-mmmx"; + PER_ARCH_CFLAGS_ppc = "-faltivec"; + PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 94A9905C0C16FC780072471F /* Build configuration list for PBXNativeTarget "Daphne+SINGE" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 94A9905D0C16FC780072471F /* Debug */, + 94A9905E0C16FC780072471F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Daphne" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Daphne" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/macosx/HOWTO_Build_Daphne_on_MacOSX.txt b/macosx/HOWTO_Build_Daphne_on_MacOSX.txt new file mode 100644 index 000000000..fc2fae760 --- /dev/null +++ b/macosx/HOWTO_Build_Daphne_on_MacOSX.txt @@ -0,0 +1,98 @@ + + + + +========================================= +HOWTO: Build Daphne as a Universal Binary on OSX +========================================= + +Building Daphne is a simple process of: + + 1. Ensuring your build machine has the right tools (XCode 2.4, and MacOS SDKs) + 2. Collecting and building the required frameworks + 3. Opening and building the XCode project (in src/macosx) + +NOTE: At this time, the Daphne frontend is not being built. To run daphne you will have to manually CD into the Daphne.app bundle to the exe and launch it from the command-line. + +========================================= +STEP 1: Prepare Build Environment +========================================= + + 1. Download and install XCode 2.4 from Apple - it's free. If you have alredy installed XCode, check to see if you have the folder /Developer/SDKs/MacOSX10.2.8.sdk. If not, reinstall. (You need to use the “Customize†button for this and select everything under "Cross Development.) + 2. Download and install Daphne source: + ⃠Open Terminal. + ⃠Type export CVSROOT=:pserver:cvs@cvs.daphne-emu.com:/cvs/daphnecvs + ⃠Type cvs login + ⃠When it asks for a password, type in cvs as the password + ⃠Type cvs -z3 co daphne + +========================================= +STEP 2a: Build SDL Framework +========================================= + + 1. Make a folder in your home dir called "lib" + 2. Download SDL 1.2.11 from: http://www.libsdl.org/release/SDL-1.2.11.tar.gz + 3. Copy the SDL-1.2.11 dir to the lib folder you created. + 4. Unpack the SDL XCode project: + ⃠Open Terminal + ⃠cd ~/lib/SDL-1.2.11/ + ⃠tar -zxf Xcode.tar.gz + 5. Build SDL: + ⃠Open the XCode project (~/lib/SDL-1.2.11/Xcode/SDL/SDL.xcodeproj) in Finder. + ⃠Change the target (Project->Set active target) to “Framework without X11 Stuff.†+ ⃠Change the build configuration (Project->Set active build configuration) to “Deployment†+ ⃠Build :) I got 79 warnings and assume that’s normal. + 6. Deploy SDL Framework: + ⃠In Finder, locate ~/lib/SDL-1.2.11/Xcode/SDL/build/Deployment. Move the “SDL.framework†folder to /Library/Frameworks. + +========================================= +STEP 2b: Build SDL Mixer Framework +========================================= + + 1. Copy SDL_mixer-1.2.7 to the lib folder you created. + 2. Unpack the SDL mixer XCode project: + ⃠Open Terminal + ⃠CD ~/lib/SDL_mixer_1.2.7 + ⃠tar -zxf Xcode.tar.gz + 3. Build SDL Mixer: + ⃠Open the XCode project in Finder + ⃠Change the target to “Framework with static smpeg†+ ⃠Change the build configuration to “Deployment†+ ⃠Build. I got 63 warnings. + 4. In Finder, locate ~/Lib/SDL_mixer-1.2.7/XCode/SDL_mixer-1.2.7/Xcode/build.Deployment. Move “SDL_mixer.framework†to /Library/Frameworks. + +========================================= +STEP 2c: Build Ogg Framework +========================================= + + 1. Download LibOgg from: http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz + 2. Move libogg-1.1.3 to the lib folder you created. + 3. Build Ogg: + ⃠Open the XCode project in Finder (~/lib/liboggg-1.1.3/macosx/Ogg.xcodeproj) + ⃠Click Project, Edit Project Settings, choose the Build tab, and set the Architectures to "i386 ppc" This is important, or you won't get a universal binary framework! + ⃠Change the build configuration to “Deployment†+ 4. Build. I got 1 warning. + 5. In Finder, locate ~/lib/libogg-1.1.3/macosx/build/Deployment. Move Ogg.framework to /Library/Frameworks. + +========================================= +STEP 2d: Build Vorbis Framework +========================================= + + 1. Download VOrbis from http://downloads.xiph.org/releases/vorbis/libvorbis-1.1.2.tar.gz + 2. Move libvorbis-1.1.2 to the lib folder you created. + 3. Build Vorbis: + ⃠Open the Xcode project in Finder (~/lib/libvorbis-1.1.2/macosx/Vorbis.xcodeproj) + ⃠Click Project, Project Settings and set the Architectures to "i386 ppc" This is important, or you won't get a universal binary framework! + ⃠Change the build configuration to 'Deployment' + 4. Build. I got 32 warnings. + 5. In Finder, locate ~/lib/libvorbis-1.1.2/macosx/build/Deployment and move Vorbis.framework to /Library/Frameworks. + +========================================= +STEP 3: Build Daphne +========================================= + +Simply open Daphne.xcodeproj and build. Enjoy! + + + + diff --git a/macosx/Info.plist b/macosx/Info.plist new file mode 100644 index 000000000..96bcbd2e8 --- /dev/null +++ b/macosx/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Daphne Icon + CFBundleIdentifier + www.daphne-emu.com + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macosx/SDLMain.h b/macosx/SDLMain.h new file mode 100644 index 000000000..4683df57a --- /dev/null +++ b/macosx/SDLMain.h @@ -0,0 +1,11 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import + +@interface SDLMain : NSObject +@end diff --git a/macosx/SDLMain.m b/macosx/SDLMain.m new file mode 100644 index 000000000..bbc35f342 --- /dev/null +++ b/macosx/SDLMain.m @@ -0,0 +1,384 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import "SDL.h" +#import "SDLMain.h" +#import /* for MAXPATHLEN */ +#import + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface SDLApplication : NSApplication +@end + +@implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { + assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } + +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [SDLApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [SDLApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + /* Copy the arguments into a global variable */ + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } + +#if SDL_USE_NIB_FILE + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} + diff --git a/macosx/SDLMain.nib/classes.nib b/macosx/SDLMain.nib/classes.nib new file mode 100644 index 000000000..f8f4e9a4b --- /dev/null +++ b/macosx/SDLMain.nib/classes.nib @@ -0,0 +1,12 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {makeFullscreen = id; quit = id; }; + CLASS = SDLMain; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + } + ); + IBVersion = 1; +} diff --git a/macosx/SDLMain.nib/info.nib b/macosx/SDLMain.nib/info.nib new file mode 100644 index 000000000..2211cf9d7 --- /dev/null +++ b/macosx/SDLMain.nib/info.nib @@ -0,0 +1,12 @@ + + + + + IBDocumentLocation + 49 97 356 240 0 0 987 746 + IBMainMenuLocation + 20 515 195 44 0 46 800 532 + IBUserGuides + + + diff --git a/macosx/SDLMain.nib/objects.nib b/macosx/SDLMain.nib/objects.nib new file mode 100644 index 000000000..9f697b0ee Binary files /dev/null and b/macosx/SDLMain.nib/objects.nib differ diff --git a/macosx/config.h b/macosx/config.h new file mode 100644 index 000000000..674765f32 --- /dev/null +++ b/macosx/config.h @@ -0,0 +1,169 @@ +/* include/config.h. Generated by configure. */ +/* include/config.h.in. Generated from configure.in by autoheader. */ + +/* autodetect accelerations */ +#define ACCEL_DETECT + +/* alpha architecture */ +/* #undef ARCH_ALPHA */ + +/* ppc architecture */ +/* #undef ARCH_PPC */ + +/* x86 architecture */ +#define ARCH_X86 + +/* MacOSX Defines for both sides of the Universal Binary */ + +#ifdef MAC_OSX +/* MacIntel */ +#ifdef __i386__ +#define NATIVE_CPU_X86 +#define MMX_RGB2YUV +#define PIC +#endif + +/* PPC */ +#ifdef __ppc__ +#define NATIVE_CPU_PPC +#undef ACCEL_DETECT +#undef ARCH_X86 +#endif + +#endif +/* End of MacOSX Defines */ + +/* maximum supported data alignment */ +#define ATTRIBUTE_ALIGNED_MAX 64 + +/* debug mode configuration */ +/* #undef DEBUG */ + +/* Define if you have the `__builtin_expect' function. */ +#define HAVE_BUILTIN_EXPECT + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DDRAW_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `ftime' function. */ +#define HAVE_FTIME 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define to 1 if you have the `memalign' function. */ +/* #undef HAVE_MEMALIGN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMEB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* libmpeg2 mediaLib support */ +/* #undef LIBMPEG2_MLIB */ + +/* libvo DirectX support */ +/* #undef LIBVO_DX */ + +/* libvo mediaLib support */ +/* #undef LIBVO_MLIB */ + +/* libvo SDL support */ +/* #undef LIBVO_SDL */ + +/* libvo X11 support */ +/* #undef LIBVO_X11 */ + +/* libvo Xv support */ +/* #undef LIBVO_XV */ + +/* Name of package */ +#define PACKAGE "mpeg2dec" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* The size of a `char', as computed by sizeof. */ +/* #undef SIZEOF_CHAR */ + +/* The size of a `int', as computed by sizeof. */ +/* #undef SIZEOF_INT */ + +/* The size of a `short', as computed by sizeof. */ +/* #undef SIZEOF_SHORT */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.3.1" + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to 1 if the X Window System is missing or not being used. */ +#define X_DISPLAY_MISSING 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define as `__inline' if that's what the C compiler calls it, or to nothing + if it is not supported. */ +#define inline __attribute__ ((__always_inline__)) + +/* Define as `__restrict' if that's what the C compiler calls it, or to + nothing if it is not supported. */ +#define restrict __restrict__ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ diff --git a/macosx/mmxdefs.h b/macosx/mmxdefs.h new file mode 100644 index 000000000..0f71aa390 --- /dev/null +++ b/macosx/mmxdefs.h @@ -0,0 +1,19 @@ +/* + * mmxdefs.h + * Daphne + * + * Created by Derek S on 10/8/07. + * Copyright 2007 . All rights reserved. + * + */ + + // Ensure all the x86 defines and optimizations exist on OSX + #ifdef MAC_OSX + #ifdef __i386__ + #define USE_MMX + #define ARCH_X86 + #define NATIVE_CPU_X86 + #include + #endif //i386 + #endif //MAC_OSX + diff --git a/manymouse/LICENSE.txt b/manymouse/LICENSE.txt new file mode 100644 index 000000000..7cd592087 --- /dev/null +++ b/manymouse/LICENSE.txt @@ -0,0 +1,23 @@ + + Copyright (c) 2005-2008 Ryan C. Gordon and others. + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from + the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + Ryan C. Gordon + diff --git a/manymouse/Makefile b/manymouse/Makefile new file mode 100644 index 000000000..426f922fb --- /dev/null +++ b/manymouse/Makefile @@ -0,0 +1,120 @@ +# Set this variable if you need to. +WINDOWS_JDK_PATH := C:\\Program\ Files\\Java\\jdk1.6.0_02\\ +LINUX_JDK_PATH := /usr/lib/j2se/1.4/ + +linux := false +macosx := false +cygwin := false + +uname_s := $(shell uname -s) +ifeq ($(strip $(uname_s)),Darwin) + macosx := true +else + uname_o := $(shell uname -o) +endif +ifeq ($(strip $(uname_s)),Linux) + linux := true +endif +ifeq ($(strip $(uname_o)),Cygwin) + cygwin := true +endif + +CFLAGS += -O0 -Wall -g -c +CFLAGS += -I. + +#CFLAGS += -ISDL-1.2.8/include +#LDFLAGS += -LSDL-1.2.8/lib -lSDL -lSDLmain + +CC := gcc +LD := gcc + +ifeq ($(strip $(macosx)),true) + LDFLAGS += -framework Carbon -framework IOKit + JAVAC := javac + MANYMOUSEJNILIB := libManyMouse.jnilib + JNICFLAGS += -I/System/Library/Frameworks/JavaVM.framework/Headers + JNILDFLAGS += -bundle -framework JavaVM +endif + +ifeq ($(strip $(linux)),true) + CFLAGS += -fPIC -I/usr/src/linux/include + LDFLAGS += -ldl + JDKPATH := $(LINUX_JDK_PATH) + JAVAC := $(JDKPATH)bin/javac + MANYMOUSEJNILIB := libManyMouse.so + JNICFLAGS += -I$(JDKPATH)include -I$(JDKPATH)include/linux + JNILDFLAGS += -shared -Wl,-soname,$(MANYMOUSEJNILIB) +endif + +ifeq ($(strip $(cygwin)),true) + CFLAGS += -mno-cygwin + LDFLAGS += -mno-cygwin + JDKPATH := $(WINDOWS_JDK_PATH) + JAVAC := $(JDKPATH)bin\\javac + MANYMOUSEJNILIB := ManyMouse.dll + JNICFLAGS += -I$(JDKPATH)include -I$(JDKPATH)include\\win32 + JNILDFLAGS += -Wl,--add-stdcall-alias -shared +endif + + + +BASEOBJS := linux_evdev.o macosx_hidutilities.o macosx_hidmanager.o windows_wminput.o x11_xinput2.o manymouse.o + +.PHONY: clean all + +all: detect_mice test_manymouse_stdio test_manymouse_sdl mmpong manymousepong + +clean: + rm -rf *.o *.obj *.exe *.class $(MANYMOUSEJNILIB) example/*.o example/*.obj test_manymouse_stdio test_manymouse_sdl detect_mice mmpong manymousepong + +%.o : %c + $(CC) $(CFLAGS) -o $@ $< + +example/test_manymouse_sdl.o : example/test_manymouse_sdl.c + $(CC) $(CFLAGS) -o $@ $< `sdl-config --cflags` + +example/mmpong.o : example/mmpong.c + $(CC) $(CFLAGS) -o $@ $< `sdl-config --cflags` + +example/manymousepong.o : example/manymousepong.c + $(CC) $(CFLAGS) -o $@ $< `sdl-config --cflags` + +detect_mice: $(BASEOBJS) example/detect_mice.o + $(LD) $(LDFLAGS) -o $@ $+ + +test_manymouse_stdio: $(BASEOBJS) example/test_manymouse_stdio.o + $(LD) $(LDFLAGS) -o $@ $+ + +test_manymouse_sdl: $(BASEOBJS) example/test_manymouse_sdl.o + $(LD) $(LDFLAGS) -o $@ $+ `sdl-config --libs` + +mmpong: $(BASEOBJS) example/mmpong.o + $(LD) $(LDFLAGS) -o $@ $+ `sdl-config --libs` + +manymousepong: $(BASEOBJS) example/manymousepong.o + $(LD) $(LDFLAGS) -o $@ $+ `sdl-config --libs` + + +# Java support ... + +.PHONY: java +java: $(MANYMOUSEJNILIB) ManyMouse.class ManyMouseEvent.class TestManyMouse.class + +ManyMouse.class: contrib/java/ManyMouse.java $(MANYMOUSEJNILIB) + $(JAVAC) -d . -classpath contrib/java $< + +ManyMouseEvent.class: contrib/java/ManyMouseEvent.java ManyMouse.class + $(JAVAC) -d . -classpath contrib/java $< + +TestManyMouse.class: contrib/java/TestManyMouse.java ManyMouse.class ManyMouseEvent.class + $(JAVAC) -d . $< + +ManyMouseJava.o: contrib/java/ManyMouseJava.c + $(CC) $(CFLAGS) -o $@ $< $(JNICFLAGS) + +$(MANYMOUSEJNILIB): $(BASEOBJS) ManyMouseJava.o + @mkdir -p $(dir $@) + $(LD) $(LDFLAGS) -o $@ $^ $(JNILDFLAGS) + +# end of Makefile ... + diff --git a/manymouse/README.txt b/manymouse/README.txt new file mode 100644 index 000000000..3771dead2 --- /dev/null +++ b/manymouse/README.txt @@ -0,0 +1,203 @@ + +ManyMouse's website is http://icculus.org/manymouse/ + +This is a simple library to abstract away the reading of multiple input + devices. It is designed to work cross-platform. + +Just copy all of the C files and headers in this directory into your + project, and build the C files. Unless explicitly noted, you shouldn't have + to #define anything, and each file is wrapped in #ifdefs to avoid compiling + on the wrong platforms, so it is safe to build everything without close + examination. + +You don't have to build this as a shared library; we encourage you to just + compile the source and statically link them into your application...this + makes integrating ManyMouse much less complex. + +The "example" directory contains complete programs to demostrate the use of + the ManyMouse API in action. These files don't need to be copied into your + project, but you can cut-and-paste their contents as needed. + +Basic usage: + - Copy *.c and *.h from the base of the manymouse folder to your project. + - Add the new files to your project's build system. + - #include "manymouse.h" in your source code + - Call ManyMouse_Init() once before using anything else in the library, + usually at program startup time. If it returns > 0, that's the number of + mice it found. If it returns zero, it means the system works, but there + aren't any mice to be found, and calling ManyMouse_Init() may report mice + in the future if one is plugged in. If it returns < 0, it means the system + will never report mice; this can happen, for example, on Windows 95, which + lacks functionality we need that was introduced with Windows XP. + - Call ManyMouse_DriverName() if you want to know the human-readable + name of the driver that handles devices behind the scenes. Some platforms + have different drivers depending on the system being used. This is for + debugging purposes only: it is not localized and we don't promise they + won't change. The string is in UTF-8 format. Don't free this string. + This will return NULL if ManyMouse_Init() failed. + - Call ManyMouse_DeviceName() if you want to know the human-readable + name of each device ("Logitech USB mouse", etc). This is for debugging + purposes only: it is not localized and we don't promise they won't change. + As these strings are created by the device and the OS, we can't even + promise they'll even actually help you identify the mouse in your hand; + sometimes, they are quite lousy descriptions. The string is in UTF-8 + format. Don't free this string. + - Read input from the mice with ManyMouse_PollEvent() in a loop until the + function returns 0. Each time through the loop, examine the event that + was returned and react appropriately. Do this with regular frequency: + generally, a good rule is to poll for ManyMouse events at the same time + you poll for other system GUI events...once per iteration of your + program's main loop. + - When you are done processing mice, call ManyMouse_Quit() once, usually at + program termination. + +There are examples of complete usage in the "example" directory. The simplest + is test_manymouse_stdio.c ... + + +Thread safety note: +Pick a thread to call into ManyMouse from, and don't call into it from any + other. We make no promises on any platform of thread safety. For safety's + sake, you might want to use the same thread that talks to the system's + GUI interfaces and/or the main thread, if you have one. + + +Building the code: +The test apps on Linux and Mac OS X can be built by running "make" from a + terminal. The SDL test app will fail if Simple Directmedia Layer + (http://libsdl.org/) isn't installed. The stdio apps will still work. + +Windows isn't integrated into the Makefile, since most people will want to + put it in a VS.NET project anyhow, but here's the command line used to + build some of the standalone test apps: + +cl /I. *.c example\test_manymouse_stdio.c /Fetest_manymouse_stdio.exe +cl /I. *.c example\detect_mice.c /Fedetect_mice.exe + +(yes, that's simple, that's the point)...getting the SDL test app to work + on Windows can be done, but takes too much effort unrelated to ManyMouse + itself for this document to explain. + + +Java bindings: + There are now Java bindings available in the contrib/java directory. + They should work on any platform that ManyMouse supports that has a Java + virtual machine. If you're using the makefile, you can run "make java" and + it will produce the native code glue library and class files that you can + include in your application. Please see contrib/java/TestManyMouse.java + for an example of how to use ManyMouse from your Java application. Most + of this documentation talks about the C interface to ManyMouse, but with + minor modifications also applies to the Java bindings. We welcome patches + and bug reports on the Java bindings, but don't officially support them. + + Mac OS X, Linux and Cygwin can run "make java" to build the bindings and run + "java TestManyMouse" to make sure they worked. Cygwin users may need to + adjust the WINDOWS_JDK_PATH line at the top of the Makefile to match their + JDK installation. Linux users should do the same with LINUX_JDK_PATH and + make sure that the resulting libManyMouse.so file is in their dynamic loader + path (LD_LIBRARY_PATH or whatnot) so that the Java VM can find it. + + Thanks to Brian Ballsun-Stanton for kicking this into gear. Jeremy Brown + gave me the rundown on getting this to work with Cygwin. + + +Some general ManyMouse usage notes: + - If a mouse is disconnected, it will not return future events, even if you + plug it right back in. You will be alerted of disconnects programmatically + through the MANYMOUSE_EVENT_DISCONNECT event, which will be the last + event sent for the disconnected device. You can safely redetect all mice by + calling ManyMouse_Quit() followed by ManyMouse_Init(), but be warned that + this may cause mice (even ones that weren't unplugged) to suddenly have a + different device index, since on most systems, the replug will cause the + mouse to show up elsewhere in the system's USB device tree. It is + recommended that you make redetection an explicit user-requested function + for this reason. + + - In most systems, all mice will control the same system cursor. It's + recommended that you ask your window system to grab the mouse input to your + application and hide the system cursor, and then do all mouse input + processing through ManyMouse. Most GUI systems will continue to deliver + mouse events through the system cursor even when ManyMouse is working; in + these cases, you should continue to read the usual GUI system event queue, + for the usual reasons, and just throw away the mouse events, which you + instead grab via ManyMouse_PollEvent(). Hiding the system cursor will mean + that you may need to draw your own cursor in an app-specific way, but + chances are you need to do that anyhow if you plan to support multiple + mice. Grabbing the input means preventing other apps from getting mouse + events, too, so you'll probably need to build in a means to ungrab the + mouse if the user wants to, say, respond to an instant message window or + email...again, you will probably need to do this anyhow. + + - On Windows, ManyMouse requires Windows XP or later to function, since it + relies on APIs that are new to XP...it uses LoadLibrary() on User32.dll and + GetProcAddress() to get all the Windows entry points it uses, so on pre-XP + systems, it will run, but fail to find any mice in ManyMouse_Init(). + ManyMouse does not require a window to run, and can even be used by console + (stdio) applications. Please note that using DirectInput at the same time + as ManyMouse can cause problems; ManyMouse does not use DirectInput, due + to DI8's limitations, but its parallel use seems to prevent ManyMouse from + getting mouse input anyhow. This is mostly not an issue, but users of + Simple Directmedia Layer (SDL, http://libsdl.org/) may find that it uses + DirectInput behind the scenes. We are still researching the issue, but we + recommend using SDL's "windib" target in the meantime to avoid this + problem. + + - On Unix systems, we try to use the XInput2 extension if possible. + ManyMouse will try to fallback to other approaches if there is no X server + available or the X server doesn't support XInput2. If you want to use the + XInput2 target, make sure you link with "-ldl", since we use dlopen() to + find the X11/XInput2 libraries. You do not have to link against Xlib + directly, and ManyMouse will fail gracefully (reporting no mice in the + ManyMouse XInput2 driver) if the libraries don't exist on the end user's + system. Naturally, you'll need the X11 headers on your system (on Ubuntu, + you would want to apt-get install libxi-dev). You can build with + SUPPORT_XINPUT2 defined to zero to disable XInput2 support completely. + Please note that the XInput2 target does not need your app to supply an X11 + window. The test_manymouse_stdio app works with this target, so long as the + X server is running. Please note that the X11 DGA extension conflicts with + XInput2 (specifically: SDL might use it). This is a good way to deal with + this in SDL 1.2: + + char namebuf[16]; + const char *driver; + + SDL_Init(SDL_INIT_VIDEO); + driver = SDL_VideoDriverName(namebuf, sizeof (namebuf)); + if (driver && (strcmp(driver, "x11") == 0)) + { + if (strcmp(ManyMouse_DriverName(), "X11 XInput2 extension") == 0) + setenv("SDL_MOUSE_RELATIVE", "0", 1); + } + + // now you may call SDL_SetVideoMode() or SDL_WM_GrabInput() safely. + + - On Linux, we can try to use the /dev/input/event* devices; this means + that ManyMouse can function with or without an X server. Please note that + modern Linux systems only allow root access to these devices. Most users + will want XInput2, but this can be used if the device permissions allow. + + - There (currently) exists a class of users that have Linux systems with + evdev device nodes forbidden to all but the root user, and no XInput2 + support. These users are out of luck; they should either force the + permissions on /dev/input/event*, or upgrade their X server. This is a + problem that will solve itself with time. + + - On Mac OS X, we use IOKit's HID Manager API, which means you can use this + C-callable library from Cocoa, Carbon, and generic Unix applications, with + or without a GUI. There are Java bindings available, too, letting you use + ManyMouse from any of the official Mac application layers. This code may or + may not work on Darwin (we're not sure if IOKit is available to that + platform); reports of success are welcome. If you aren't already, you will + need to make sure you link against the "Carbon" and "IOKit" frameworks once + you add ManyMouse to your project. + + - Support for other platforms than Mac OS X, Linux, and Windows is not + planned, but contributions of implementations for other platforms are + welcome. + +Please see the file LICENSE in the source's root directory. + +This library was written by Ryan C. Gordon . + +--ryan. + diff --git a/manymouse/linux_evdev.c b/manymouse/linux_evdev.c new file mode 100644 index 000000000..0db138c7d --- /dev/null +++ b/manymouse/linux_evdev.c @@ -0,0 +1,339 @@ +/* + * Support for Linux evdevs...the /dev/input/event* devices. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include "manymouse.h" + +#ifdef __linux__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* evdev interface... */ + +#define test_bit(array, bit) (array[bit/8] & (1<<(bit%8))) + +/* linux allows 32 evdev nodes currently. */ +#define MAX_MICE 32 +typedef struct +{ + int fd; + int min_x; + int min_y; + int max_x; + int max_y; + char name[64]; +} MouseStruct; + +static MouseStruct mice[MAX_MICE]; +static unsigned int available_mice = 0; + + +static int poll_mouse(MouseStruct *mouse, ManyMouseEvent *outevent) +{ + int unhandled = 1; + while (unhandled) /* read until failure or valid event. */ + { + struct input_event event; + int br = read(mouse->fd, &event, sizeof (event)); + if (br == -1) + { + if (errno == EAGAIN) + return 0; /* just no new data at the moment. */ + + /* mouse was unplugged? */ + close(mouse->fd); /* stop reading from this mouse. */ + mouse->fd = -1; + outevent->type = MANYMOUSE_EVENT_DISCONNECT; + return 1; + } /* if */ + + if (br != sizeof (event)) + return 0; /* oh well. */ + + unhandled = 0; /* will reset if necessary. */ + outevent->value = event.value; + if (event.type == EV_REL) + { + outevent->type = MANYMOUSE_EVENT_RELMOTION; + if ((event.code == REL_X) || (event.code == REL_DIAL)) + outevent->item = 0; + else if (event.code == REL_Y) + outevent->item = 1; + + else if (event.code == REL_WHEEL) + { + outevent->type = MANYMOUSE_EVENT_SCROLL; + outevent->item = 0; + } /* else if */ + + else if (event.code == REL_HWHEEL) + { + outevent->type = MANYMOUSE_EVENT_SCROLL; + outevent->item = 1; + } /* else if */ + + else + { + unhandled = 1; + } /* else */ + } /* if */ + + else if (event.type == EV_ABS) + { + outevent->type = MANYMOUSE_EVENT_ABSMOTION; + if (event.code == ABS_X) + { + outevent->item = 0; + outevent->minval = mouse->min_x; + outevent->maxval = mouse->max_x; + } /* if */ + else if (event.code == ABS_Y) + { + outevent->item = 1; + outevent->minval = mouse->min_y; + outevent->maxval = mouse->max_y; + } /* if */ + else + { + unhandled = 1; + } /* else */ + } /* else if */ + + else if (event.type == EV_KEY) + { + outevent->type = MANYMOUSE_EVENT_BUTTON; + if ((event.code >= BTN_LEFT) && (event.code <= BTN_BACK)) + outevent->item = event.code - BTN_MOUSE; + + /* just in case some device uses this block of events instead... */ + else if ((event.code >= BTN_MISC) && (event.code <= BTN_LEFT)) + outevent->item = (event.code - BTN_MISC); + + else if (event.code == BTN_TOUCH) /* tablet... */ + outevent->item = 0; + else if (event.code == BTN_STYLUS) /* tablet... */ + outevent->item = 1; + else if (event.code == BTN_STYLUS2) /* tablet... */ + outevent->item = 2; + + else + { + /*printf("unhandled mouse button: 0x%X\n", event.code);*/ + unhandled = 1; + } /* else */ + } /* else if */ + else + { + unhandled = 1; + } /* else */ + } /* while */ + + return 1; /* got a valid event */ +} /* poll_mouse */ + + +static int init_mouse(const char *fname, int fd) +{ + MouseStruct *mouse = &mice[available_mice]; + int has_absolutes = 0; + int is_mouse = 0; + unsigned char relcaps[(REL_MAX / 8) + 1]; + unsigned char abscaps[(ABS_MAX / 8) + 1]; + unsigned char keycaps[(KEY_MAX / 8) + 1]; + + memset(relcaps, '\0', sizeof (relcaps)); + memset(abscaps, '\0', sizeof (abscaps)); + memset(keycaps, '\0', sizeof (keycaps)); + + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof (keycaps)), keycaps) == -1) + return 0; /* gotta have some buttons! :) */ + + if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof (relcaps)), relcaps) != -1) + { + if ( (test_bit(relcaps, REL_X)) && (test_bit(relcaps, REL_Y)) ) + { + if (test_bit(keycaps, BTN_MOUSE)) + is_mouse = 1; + } /* if */ + + #if ALLOW_DIALS_TO_BE_MICE + if (test_bit(relcaps, REL_DIAL)) + is_mouse = 1; // griffin powermate? + #endif + } /* if */ + + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof (abscaps)), abscaps) != -1) + { + if ( (test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y)) ) + { + /* might be a touchpad... */ + if (test_bit(keycaps, BTN_TOUCH)) + { + is_mouse = 1; /* touchpad, touchscreen, or tablet. */ + has_absolutes = 1; + } /* if */ + } /* if */ + } /* if */ + + if (!is_mouse) + return 0; + + mouse->min_x = mouse->min_y = mouse->max_x = mouse->max_y = 0; + if (has_absolutes) + { + struct input_absinfo absinfo; + if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) == -1) + return 0; + mouse->min_x = absinfo.minimum; + mouse->max_x = absinfo.maximum; + + if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) == -1) + return 0; + mouse->min_y = absinfo.minimum; + mouse->max_y = absinfo.maximum; + } /* if */ + + if (ioctl(fd, EVIOCGNAME(sizeof (mouse->name)), mouse->name) == -1) + snprintf(mouse->name, sizeof (mouse->name), "Unknown device"); + + mouse->fd = fd; + + return 1; /* we're golden. */ +} /* init_mouse */ + + +/* Return a file descriptor if this is really a mouse, -1 otherwise. */ +static int open_if_mouse(const char *fname) +{ + struct stat statbuf; + int fd; + int devmajor, devminor; + + if (stat(fname, &statbuf) == -1) + return 0; + + if (S_ISCHR(statbuf.st_mode) == 0) + return 0; /* not a character device... */ + + /* evdev node ids are major 13, minor 64-96. Is this safe to check? */ + devmajor = (statbuf.st_rdev & 0xFF00) >> 8; + devminor = (statbuf.st_rdev & 0x00FF); + if ( (devmajor != 13) || (devminor < 64) || (devminor > 96) ) + return 0; /* not an evdev. */ + + if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) == -1) + return 0; + + if (init_mouse(fname, fd)) + return 1; + + close(fd); + return 0; +} /* open_if_mouse */ + + +static int linux_evdev_init(void) +{ + DIR *dirp; + struct dirent *dent; + int i; + + for (i = 0; i < MAX_MICE; i++) + mice[i].fd = -1; + + dirp = opendir("/dev/input"); + if (!dirp) + return -1; + + while ((dent = readdir(dirp)) != NULL) + { + char fname[128]; + snprintf(fname, sizeof (fname), "/dev/input/%s", dent->d_name); + if (open_if_mouse(fname)) + available_mice++; + } /* while */ + + closedir(dirp); + + return available_mice; +} /* linux_evdev_init */ + + +static void linux_evdev_quit(void) +{ + while (available_mice) + { + int fd = mice[available_mice--].fd; + if (fd != -1) + close(fd); + } /* while */ +} /* linux_evdev_quit */ + + +static const char *linux_evdev_name(unsigned int index) +{ + return (index < available_mice) ? mice[index].name : NULL; +} /* linux_evdev_name */ + + +static int linux_evdev_poll(ManyMouseEvent *event) +{ + /* + * (i) is static so we iterate through all mice round-robin. This + * prevents a chatty mouse from dominating the queue. + */ + static unsigned int i = 0; + + if (i >= available_mice) + i = 0; /* handle reset condition. */ + + if (event != NULL) + { + while (i < available_mice) + { + MouseStruct *mouse = &mice[i]; + if (mouse->fd != -1) + { + if (poll_mouse(mouse, event)) + { + event->device = i; + return 1; + } /* if */ + } /* if */ + i++; + } /* while */ + } /* if */ + + return 0; /* no new events */ +} /* linux_evdev_poll */ + +static const ManyMouseDriver ManyMouseDriver_interface = +{ + "Linux /dev/input/event* interface", + linux_evdev_init, + linux_evdev_quit, + linux_evdev_name, + linux_evdev_poll +}; + +const ManyMouseDriver *ManyMouseDriver_evdev = &ManyMouseDriver_interface; + +#else +const ManyMouseDriver *ManyMouseDriver_evdev = 0; +#endif /* ifdef Linux blocker */ + +/* end of linux_evdev.c ... */ + diff --git a/manymouse/macosx_hidmanager.c b/manymouse/macosx_hidmanager.c new file mode 100644 index 000000000..c4d79343f --- /dev/null +++ b/manymouse/macosx_hidmanager.c @@ -0,0 +1,427 @@ +/* + * Support for Mac OS X via the HID Manager APIs that are new to OS X 10.5 + * ("Leopard"). The technotes suggest that after 10.5, the code in + * macosx_hidutilities.c may stop working. We dynamically look up the 10.5 + * symbols, and if they are there, we use them. If they aren't, we fail so + * the legacy code can do its magic. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include "manymouse.h" + +#if ( (defined(__MACH__)) && (defined(__APPLE__)) ) +# include // we need the 10.5 SDK headers here... +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +# define MANYMOUSE_DO_MAC_10_POINT_5_API 1 +# endif +#endif + +#if MANYMOUSE_DO_MAC_10_POINT_5_API + +#include + +#define ALLOCATOR kCFAllocatorDefault +#define RUNLOOPMODE (CFSTR("ManyMouse")) +#define HIDOPS kIOHIDOptionsTypeNone + +typedef struct +{ + IOHIDDeviceRef device; + char *name; + int logical; /* maps to what ManyMouse reports for an index. */ +} MouseStruct; + +static unsigned int logical_mice = 0; +static unsigned int physical_mice = 0; +static IOHIDManagerRef hidman = NULL; +static MouseStruct *mice = NULL; + +static char *get_device_name(IOHIDDeviceRef device) +{ + char *buf = NULL; + void *ptr = NULL; + CFIndex len = 0; + CFStringRef cfstr = (CFStringRef) IOHIDDeviceGetProperty(device, + CFSTR(kIOHIDProductKey)); + if (!cfstr) + return NULL; + + CFRetain(cfstr); + len = (CFStringGetLength(cfstr)+1) * 12; /* 12 is overkill, but oh well. */ + + buf = (char *) malloc(len); + if (!buf) + { + CFRelease(cfstr); + return NULL; + } /* if */ + + if (!CFStringGetCString(cfstr, buf, len, kCFStringEncodingUTF8)) + { + free(buf); + CFRelease(cfstr); + return NULL; + } /* if */ + + ptr = realloc(buf, strlen(buf) + 1); /* shrink down our allocation. */ + if (ptr != NULL) + buf = (char *) ptr; + return buf; +} /* get_device_name */ + + +static inline int is_trackpad(const MouseStruct *mouse) +{ + /* + * This stupid thing shows up as two logical devices. One does + * most of the mouse events, the other does the mouse wheel. + */ + return (strcmp(mouse->name, "Apple Internal Keyboard / Trackpad") == 0); +} /* is_trackpad */ + + +/* + * Just trying to avoid malloc() here...we statically allocate a buffer + * for events and treat it as a ring buffer. + */ +/* !!! FIXME: tweak this? */ +#define MAX_EVENTS 1024 +static ManyMouseEvent input_events[MAX_EVENTS]; +static volatile int input_events_read = 0; +static volatile int input_events_write = 0; + +static void queue_event(const ManyMouseEvent *event) +{ + /* copy the event info. We'll process it in ManyMouse_PollEvent(). */ + memcpy(&input_events[input_events_write], event, sizeof (ManyMouseEvent)); + + input_events_write = ((input_events_write + 1) % MAX_EVENTS); + + /* Ring buffer full? Lose oldest event. */ + if (input_events_write == input_events_read) + { + /* !!! FIXME: we need to not lose mouse buttons here. */ + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + } /* if */ +} /* queue_event */ + + +static int dequeue_event(ManyMouseEvent *event) +{ + if (input_events_read != input_events_write) /* no events if equal. */ + { + memcpy(event, &input_events[input_events_read], sizeof (*event)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + return 1; + } /* if */ + return 0; /* no event. */ +} /* dequeue_event */ + + +/* returns non-zero if (a <= b). */ +typedef unsigned long long ui64; +static inline int oldEvent(const AbsoluteTime *a, const AbsoluteTime *b) +{ +#if 0 // !!! FIXME: doesn't work, timestamps aren't reliable. + const ui64 a64 = (((unsigned long long) a->hi) << 32) | a->lo; + const ui64 b64 = (((unsigned long long) b->hi) << 32) | b->lo; +#endif + return 0; +} /* oldEvent */ + + +/* Callback fires whenever a device is unplugged/lost/whatever. */ +static void unplugged_callback(void *ctx, IOReturn res, void *sender) +{ + const unsigned int idx = (unsigned int) ((size_t) ctx); + if ((idx < physical_mice) && (mice[idx].device) && (mice[idx].logical >= 0)) + { + unsigned int i; + const int logical = mice[idx].logical; + ManyMouseEvent ev; + memset(&ev, '\0', sizeof (ev)); + ev.type = MANYMOUSE_EVENT_DISCONNECT; + ev.device = logical; + queue_event(&ev); + + /* disable any physical devices that back the same logical mouse. */ + for (i = 0; i < physical_mice; i++) + { + if (mice[i].logical == logical) + { + mice[i].device = NULL; + mice[i].logical = -1; + } /* if */ + } /* for */ + } /* if */ +} /* unplugged_callback */ + + +/* Callback fires for new mouse input events. */ +static void input_callback(void *ctx, IOReturn res, + void *sender, IOHIDValueRef val) +{ + const unsigned int idx = (unsigned int) ((size_t) ctx); + const MouseStruct *mouse = NULL; + if ((res == kIOReturnSuccess) && (idx < physical_mice)) + mouse = &mice[idx]; + + if ((mouse != NULL) && (mouse->device != NULL) && (mouse->logical >= 0)) + { + ManyMouseEvent ev; + IOHIDElementRef elem = IOHIDValueGetElement(val); + const CFIndex value = IOHIDValueGetIntegerValue(val); + const uint32_t page = IOHIDElementGetUsagePage(elem); + const uint32_t usage = IOHIDElementGetUsage(elem); + + memset(&ev, '\0', sizeof (ev)); + ev.value = (int) value; + ev.device = mouse->logical; + + if (page == kHIDPage_GenericDesktop) + { + /* + * some devices (two-finger-scroll trackpads?) seem to give + * a flood of events with values of zero for every legitimate + * event. Throw these zero events out. + */ + if (value != 0) + { + switch (usage) + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + /*if (!oldEvent(&event.timestamp, &mouse->lastScrollTime))*/ + { + ev.type = MANYMOUSE_EVENT_RELMOTION; + ev.item = (usage == kHIDUsage_GD_X) ? 0 : 1; + queue_event(&ev); + } /* if */ + break; + + case kHIDUsage_GD_Wheel: + /*memcpy(&mouse->lastScrollTime, &event.timestamp, sizeof (AbsoluteTime)); */ + ev.type = MANYMOUSE_EVENT_SCROLL; + ev.item = 0; /* !!! FIXME: horiz scroll? */ + queue_event(&ev); + break; + + /*default: !!! FIXME: absolute motion? */ + } /* switch */ + } /* if */ + } /* if */ + + else if (page == kHIDPage_Button) + { + ev.type = MANYMOUSE_EVENT_BUTTON; + ev.item = ((int) usage) - 1; + queue_event(&ev); + } /* else if */ + } /* if */ +} /* input_callback */ + + +/* We ignore hotplugs...this callback is only for initial device discovery. */ +static void enum_callback(void *ctx, IOReturn res, + void *sender, IOHIDDeviceRef device) +{ + if (res == kIOReturnSuccess) + { + const size_t len = sizeof (MouseStruct) * (physical_mice + 1); + void *ptr = realloc(mice, len); + if (ptr != NULL) /* if realloc fails, we just drop the device. */ + { + mice = (MouseStruct *) ptr; + mice[physical_mice].device = device; + mice[physical_mice].logical = -1; /* filled in later. */ + mice[physical_mice].name = get_device_name(device); + if (mice[physical_mice].name == NULL) + return; /* This is bad! Don't add this mouse, I guess. */ + + physical_mice++; + } /* if */ + } /* if */ +} /* enum_callback */ + + +static int config_hidmanager(CFMutableDictionaryRef dict) +{ + CFRunLoopRef runloop = CFRunLoopGetCurrent(); + int trackpad = -1; + unsigned int i; + + IOHIDManagerRegisterDeviceMatchingCallback(hidman, enum_callback, NULL); + IOHIDManagerScheduleWithRunLoop(hidman,CFRunLoopGetCurrent(),RUNLOOPMODE); + IOHIDManagerSetDeviceMatching(hidman, dict); + IOHIDManagerOpen(hidman, HIDOPS); + + while (CFRunLoopRunInMode(RUNLOOPMODE,0,TRUE)==kCFRunLoopRunHandledSource) + /* no-op. Callback fires once per existing device. */ ; + + /* globals (physical_mice) and (mice) are now configured. */ + /* don't care about any hotplugged devices after the initial list. */ + IOHIDManagerRegisterDeviceMatchingCallback(hidman, NULL, NULL); + IOHIDManagerUnscheduleFromRunLoop(hidman, runloop, RUNLOOPMODE); + + /* now put all those discovered devices into the runloop instead... */ + for (i = 0; i < physical_mice; i++) + { + MouseStruct *mouse = &mice[i]; + IOHIDDeviceRef dev = mouse->device; + if (IOHIDDeviceOpen(dev, HIDOPS) != kIOReturnSuccess) + { + mouse->device = NULL; /* oh well. */ + mouse->logical = -1; + } /* if */ + else + { + void *ctx = (void *) ((size_t) i); + + if (!is_trackpad(mouse)) + mouse->logical = logical_mice++; + else + { + if (trackpad < 0) + trackpad = logical_mice++; + mouse->logical = trackpad; + } /* else */ + + IOHIDDeviceRegisterRemovalCallback(dev, unplugged_callback, ctx); + IOHIDDeviceRegisterInputValueCallback(dev, input_callback, ctx); + IOHIDDeviceScheduleWithRunLoop(dev, runloop, RUNLOOPMODE); + } /* else */ + } /* for */ + + return 1; /* good to go. */ +} /* config_hidmanager */ + + +static int create_hidmanager(const UInt32 page, const UInt32 usage) +{ + int retval = -1; + CFNumberRef num = NULL; + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(ALLOCATOR, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (dict != NULL) + { + num = CFNumberCreate(ALLOCATOR, kCFNumberIntType, &page); + if (num != NULL) + { + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), num); + CFRelease(num); + num = CFNumberCreate(ALLOCATOR, kCFNumberIntType, &usage); + if (num != NULL) + { + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), num); + CFRelease(num); + hidman = IOHIDManagerCreate(ALLOCATOR, HIDOPS); + if (hidman != NULL) + retval = config_hidmanager(dict); + } /* if */ + } /* if */ + CFRelease(dict); + } /* if */ + + return retval; +} /* create_hidmanager */ + + +/* ManyMouseDriver interface... */ + +static void macosx_hidmanager_quit(void) +{ + unsigned int i; + for (i = 0; i < physical_mice; i++) + free(mice[i].name); + + if (hidman != NULL) + { + /* closing (hidman) should close all open devices, too. */ + IOHIDManagerClose(hidman, HIDOPS); + CFRelease(hidman); + hidman = NULL; + } /* if */ + + logical_mice = 0; + physical_mice = 0; + free(mice); + mice = NULL; + + memset(input_events, '\0', sizeof (input_events)); + input_events_read = input_events_write = 0; +} /* macosx_hidmanager_quit */ + + +static int macosx_hidmanager_init(void) +{ + if (IOHIDManagerCreate == NULL) + return -1; /* weak symbol is NULL...we don't have OS X >= 10.5.0 */ + + macosx_hidmanager_quit(); /* just in case... */ + + /* Prepare global (hidman), (mice), (physical_mice), etc. */ + if (!create_hidmanager(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) + return -1; + + return (int) logical_mice; +} /* macosx_hidmanager_init */ + + +/* returns the first physical device that backs a logical device. */ +static MouseStruct *map_logical_device(const unsigned int index) +{ + if (index < logical_mice) + { + unsigned int i; + for (i = 0; i < physical_mice; i++) + { + if (mice[i].logical == ((int) index)) + return &mice[i]; + } /* for */ + } /* if */ + + return NULL; /* not found (maybe unplugged?) */ +} /* map_logical_device */ + +static const char *macosx_hidmanager_name(unsigned int index) +{ + const MouseStruct *mouse = map_logical_device(index); + return mouse ? mouse->name : NULL; +} /* macosx_hidmanager_name */ + + +static int macosx_hidmanager_poll(ManyMouseEvent *event) +{ + /* ...favor existing events in the queue... */ + if (dequeue_event(event)) + return 1; + + /* pump runloop for new hardware events... */ + while (CFRunLoopRunInMode(RUNLOOPMODE,0,TRUE)==kCFRunLoopRunHandledSource) + /* no-op. We're filling our queue... !!! FIXME: stop if queue fills. */ ; + + return dequeue_event(event); /* see if anything had shown up... */ +} /* macosx_hidmanager_poll */ + + +static const ManyMouseDriver ManyMouseDriver_interface = +{ + "Mac OS X 10.5+ HID Manager", + macosx_hidmanager_init, + macosx_hidmanager_quit, + macosx_hidmanager_name, + macosx_hidmanager_poll +}; + +const ManyMouseDriver *ManyMouseDriver_hidmanager = &ManyMouseDriver_interface; + +#else +const ManyMouseDriver *ManyMouseDriver_hidmanager = 0; +#endif /* ifdef Mac OS X blocker */ + +/* end of macosx_hidmanager.c ... */ + diff --git a/manymouse/macosx_hidutilities.c b/manymouse/macosx_hidutilities.c new file mode 100644 index 000000000..bc0bfe496 --- /dev/null +++ b/manymouse/macosx_hidutilities.c @@ -0,0 +1,1728 @@ +/* + * Support for Mac OS X via the HID Utilities example code. HID Utilities + * talks to very low-level parts of the HID Manager API, which are deprecated + * in OS X 10.5. Please see macosx_hidmanager.c for the 10.5 implementation. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include "manymouse.h" + +/* + * These APIs exist on x86_64 in 10.6, but don't actually work (they'll work + * for 32-bit x86 binaries in 10.6, though!). HID Utilities is for legacy + * Macs, going forward you want macosx_hidmanager.c instead. + */ +#if ( (defined(__APPLE__)) && (defined(i386) || defined(__POWERPC__)) ) + +/* + * This source is almost entirely lifted from Apple's HID Utilities + * example source code, written by George Warner: + * + * http://developer.apple.com/samplecode/HID_Utilities_Source/HID_Utilities_Source.html + * + * The source license to HID Utilities allows this sort of blatant stealing. + * + * Patches to HID Utilities have comments like "ryan added this", otherwise, + * I just tried to cut down that package to the smallest set of functions + * I needed. + * + * Scroll down for "-- END HID UTILITIES --" to see the ManyMouse glue code. + */ + +#include + +#include +// 10.0.x +//#include +// 10.1.x +#include +#include +#include +#include +#include + +#define USE_NOTIFICATIONS 1 + +#define HIDREPORTERRORNUM(s,n) do {} while (false) +#define HIDREPORTERROR(s) do {} while (false) + +typedef enum HIDElementTypeMask +{ + kHIDElementTypeInput = 1 << 1, + kHIDElementTypeOutput = 1 << 2, + kHIDElementTypeFeature = 1 << 3, + kHIDElementTypeCollection = 1 << 4, + kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, + kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection +}HIDElementTypeMask; + +enum +{ + kDefaultUserMin = 0, // default user min and max used for scaling + kDefaultUserMax = 255 +}; + +enum +{ + kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible + // but should account for the maximum possible events in the queue + // USB updates will likely occur at 100 Hz so one must account for this rate of + // if states change quickly (updates are only posted on state changes) +}; + +struct recElement +{ + unsigned long type; // the type defined by IOHIDElementType in IOHIDKeys.h + long usagePage; // usage page from IOUSBHIDParser.h which defines general usage + long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage + void * cookie; // unique value (within device of specific vendorID and productID) which identifies element, will NOT change + long min; // reported min value possible + long max; // reported max value possible + long scaledMin; // reported scaled min value possible + long scaledMax; // reported scaled max value possible + long size; // size in bits of data return from element + unsigned char relative; // are reports relative to last report (deltas) + unsigned char wrapping; // does element wrap around (one value higher than max is min) + unsigned char nonLinear; // are the values reported non-linear relative to element movement + unsigned char preferredState; // does element have a preferred state (such as a button) + unsigned char nullState; // does element have null state + long units; // units value is reported in (not used very often) + long unitExp; // exponent for units (also not used very often) + char name[256]; // name of element (c string) + +// runtime variables + long calMin; // min returned value + long calMax; // max returned value (calibrate call) + long userMin; // user set value to scale to (scale call) + long userMax; + + struct recElement * pPrevious; // previous element (NULL at list head) + struct recElement * pChild; // next child (only of collections) + struct recElement * pSibling; // next sibling (for elements and collections) + + long depth; +}; +typedef struct recElement recElement; +typedef recElement* pRecElement; + +// ryan added this. +typedef enum +{ + DISCONNECT_CONNECTED, + DISCONNECT_TELLUSER, + DISCONNECT_COMPLETE +} DisconnectState; + +struct recDevice +{ + void * interface; // interface to device, NULL = no interface + void * queue; // device queue, NULL = no queue + void * queueRunLoopSource; // device queue run loop source, NULL == no source + void * transaction; // output transaction interface, NULL == no interface + void * notification; // notifications + char transport[256]; // device transport (c string) + long vendorID; // id for device vendor, unique across all devices + long productID; // id for particular product, unique across all of a vendors devices + long version; // version of product + char manufacturer[256]; // name of manufacturer + char product[256]; // name of product + char serial[256]; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often) + long locID; // long representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine + long usage; // usage page from IOUSBHID Parser.h which defines general usage + long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage + long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device) + long features; // number of elements of type kIOHIDElementTypeFeature + long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes + long outputs; // number of elements of type kIOHIDElementTypeOutput + long collections; // number of elements of type kIOHIDElementTypeCollection + long axis; // number of axis (calculated, not reported by device) + long buttons; // number of buttons (calculated, not reported by device) + long hats; // number of hat switches (calculated, not reported by device) + long sliders; // number of sliders (calculated, not reported by device) + long dials; // number of dials (calculated, not reported by device) + long wheels; // number of wheels (calculated, not reported by device) + recElement* pListElements; // head of linked list of elements + DisconnectState disconnect; // (ryan added this.) + AbsoluteTime lastScrollTime; // (ryan added this.) + int logical; // (ryan added this.) + struct recDevice* pNext; // next device +}; +typedef struct recDevice recDevice; +typedef recDevice* pRecDevice; + + +#if USE_NOTIFICATIONS +static IONotificationPortRef gNotifyPort; +static io_iterator_t gAddedIter; +static CFRunLoopRef gRunLoop; +#endif USE_NOTIFICATIONS + +// for element retrieval +static pRecDevice gCurrentGetDevice = NULL; +static Boolean gAddAsChild = false; +static int gDepth = false; + +static pRecDevice gpDeviceList = NULL; +static UInt32 gNumDevices = 0; + +static Boolean HIDIsValidDevice(const pRecDevice pSearchDevice); +static pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask); +static pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask); +static pRecDevice HIDGetFirstDevice (void); +static pRecDevice HIDGetNextDevice (pRecDevice pDevice); +static void HIDReleaseDeviceList (void); +static unsigned long HIDDequeueDevice (pRecDevice pDevice); +static void hid_GetElements (CFTypeRef refElementCurrent, pRecElement *ppCurrentElement); + + +static void HIDReportError(const char *err) {} +static void HIDReportErrorNum(const char *err, int num) {} + + +static void hid_GetCollectionElements (CFMutableDictionaryRef deviceProperties, pRecElement *ppCurrentCollection) +{ + CFTypeRef refElementTop = CFDictionaryGetValue (deviceProperties, CFSTR(kIOHIDElementKey)); + if (refElementTop) + hid_GetElements (refElementTop, ppCurrentCollection); + else + HIDReportError ("hid_GetCollectionElements: CFDictionaryGetValue error when creating CFTypeRef for kIOHIDElementKey."); +} + + +// extracts actual specific element information from each element CF dictionary entry +static void hid_GetElementInfo (CFTypeRef refElement, pRecElement pElement) +{ + long number; + CFTypeRef refType; + // type, usagePage, usage already stored + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementCookieKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->cookie = (IOHIDElementCookie) number; + else + pElement->cookie = (IOHIDElementCookie) 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMinKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->min = number; + else + pElement->min = 0; + + pElement->calMax = pElement->min; + pElement->userMin = kDefaultUserMin; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMaxKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->max = number; + else + pElement->max = 0; + + pElement->calMin = pElement->max; + pElement->userMax = kDefaultUserMax; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMinKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->scaledMin = number; + else + pElement->scaledMin = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMaxKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->scaledMax = number; + else + pElement->scaledMax = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementSizeKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->size = number; + else + pElement->size = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsRelativeKey)); + if (refType) + pElement->relative = CFBooleanGetValue (refType); + else + pElement->relative = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsWrappingKey)); + if (refType) + pElement->wrapping = CFBooleanGetValue (refType); + else + pElement->wrapping = false; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsNonLinearKey)); + if (refType) + pElement->nonLinear = CFBooleanGetValue (refType); + else + pElement->wrapping = false; + +#ifdef kIOHIDElementHasPreferredStateKey + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasPreferredStateKey)); +#else // Mac OS X 10.0 has spelling error + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasPreferedStateKey)); +#endif + if (refType) + pElement->preferredState = CFBooleanGetValue (refType); + else + pElement->preferredState = false; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasNullStateKey)); + if (refType) + pElement->nullState = CFBooleanGetValue (refType); + else + pElement->nullState = false; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUnitKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->units = number; + else + pElement->units = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUnitExponentKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->unitExp = number; + else + pElement->unitExp = 0; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementNameKey)); + if (refType) + if (!CFStringGetCString (refType, pElement->name, 256, CFStringGetSystemEncoding ())) + HIDReportError ("CFStringGetCString error retrieving pElement->name."); + + #if 0 + if (!*pElement->name) + { + // set name from vendor id, product id & usage info look up + if (!HIDGetElementNameFromVendorProductUsage (gCurrentGetDevice->vendorID, gCurrentGetDevice->productID, pElement->usagePage, pElement->usage, pElement->name)) + { + // set name from vendor id/product id look up + HIDGetElementNameFromVendorProductCookie (gCurrentGetDevice->vendorID, gCurrentGetDevice->productID, (long) pElement->cookie, pElement->name); + if (!*pElement->name) { // if no name + HIDGetUsageName (pElement->usagePage, pElement->usage, pElement->name); + if (!*pElement->name) // if not usage + sprintf (pElement->name, "Element"); + } + } + } + #endif +} + + +static void hid_AddElement (CFTypeRef refElement, pRecElement * ppElementCurrent) +{ + pRecDevice pDevice = gCurrentGetDevice; + pRecElement pElement = NULL; + long elementType, usagePage, usage; + CFTypeRef refElementType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementTypeKey)); + CFTypeRef refUsagePage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsagePageKey)); + CFTypeRef refUsage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsageKey)); + + if (refElementType) + CFNumberGetValue (refElementType, kCFNumberLongType, &elementType); + if (refUsagePage) + CFNumberGetValue (refUsagePage, kCFNumberLongType, &usagePage); + if (refUsage) + CFNumberGetValue (refUsage, kCFNumberLongType, &usage); + + if (NULL == pDevice) + return; + + if (elementType) + { + // look at types of interest + if (elementType != kIOHIDElementTypeCollection) + { + if (usagePage && usage) // if valid usage and page + { + switch (usagePage) // only interested in kHIDPage_GenericDesktop and kHIDPage_Button + { + case kHIDPage_GenericDesktop: + { + switch (usage) // look at usage to determine function + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->axis++; + break; + case kHIDUsage_GD_Slider: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->sliders++; + break; + case kHIDUsage_GD_Dial: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->dials++; + break; + case kHIDUsage_GD_Wheel: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->wheels++; + break; + case kHIDUsage_GD_Hatswitch: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->hats++; + break; + default: + pElement = (pRecElement) malloc (sizeof (recElement)); + break; + } + } + break; + case kHIDPage_Button: + pElement = (pRecElement) malloc (sizeof (recElement)); + if (pElement) pDevice->buttons++; + break; + default: + // just add a generic element + pElement = (pRecElement) malloc (sizeof (recElement)); + break; + } + } +#if 0 + else + HIDReportError ("CFNumberGetValue error when getting value for refUsage or refUsagePage."); +#endif 0 + } + else // collection + pElement = (pRecElement) malloc (sizeof (recElement)); + } + else + HIDReportError ("CFNumberGetValue error when getting value for refElementType."); + + if (pElement) // add to list + { + // this code builds a binary tree based on the collection hierarchy of inherent in the device element layout + // it preserves the structure of the lements as collections have children and elements are siblings to each other + + // clear record + bzero(pElement,sizeof(recElement)); + + // get element info + pElement->type = elementType; + pElement->usagePage = usagePage; + pElement->usage = usage; + pElement->depth = 0; // assume root object + hid_GetElementInfo (refElement, pElement); + + // count elements + pDevice->totalElements++; + + switch (pElement->type) + { + case kIOHIDElementTypeInput_Misc: + case kIOHIDElementTypeInput_Button: + case kIOHIDElementTypeInput_Axis: + case kIOHIDElementTypeInput_ScanCodes: + pDevice->inputs++; + break; + case kIOHIDElementTypeOutput: + pDevice->outputs++; + break; + case kIOHIDElementTypeFeature: + pDevice->features++; + break; + case kIOHIDElementTypeCollection: + pDevice->collections++; + break; + default: + HIDReportErrorNum ("Unknown element type : ", pElement->type); + } + + if (NULL == *ppElementCurrent) // if at list head + { + pDevice->pListElements = pElement; // add current element + *ppElementCurrent = pElement; // set current element to element we just added + } + else // have exsiting structure + { + if (gAddAsChild) // if the previous element was a collection, let's add this as a child of the previous + { + // this iteration should not be needed but there maybe some untested degenerate case which this code will ensure works + while ((*ppElementCurrent)->pChild) // step down tree until free child node found + *ppElementCurrent = (*ppElementCurrent)->pChild; + (*ppElementCurrent)->pChild = pElement; // insert there + pElement->depth = (*ppElementCurrent)->depth + 1; + } + else // add as sibling + { + // this iteration should not be needed but there maybe some untested degenerate case which this code will ensure works + while ((*ppElementCurrent)->pSibling) // step down tree until free sibling node found + *ppElementCurrent = (*ppElementCurrent)->pSibling; + (*ppElementCurrent)->pSibling = pElement; // insert there + pElement->depth = (*ppElementCurrent)->depth; + } + pElement->pPrevious = *ppElementCurrent; // point to previous + *ppElementCurrent = pElement; // set current to our collection + } + + if (elementType == kIOHIDElementTypeCollection) // if this element is a collection of other elements + { + gAddAsChild = true; // add next set as children to this element + gDepth++; + hid_GetCollectionElements ((CFMutableDictionaryRef) refElement, &pElement); // recursively process the collection + gDepth--; + } + gAddAsChild = false; // add next as this elements sibling (when return from a collection or with non-collections) + } +#if 0 + else + HIDReportError ("hid_AddElement - no element added."); +#endif +} + + +static void hid_GetElementsCFArrayHandler (const void * value, void * parameter) +{ + if (CFGetTypeID (value) == CFDictionaryGetTypeID ()) + hid_AddElement ((CFTypeRef) value, (pRecElement *) parameter); +} + +// --------------------------------- +// handles retrieval of element information from arrays of elements in device IO registry information + +static void hid_GetElements (CFTypeRef refElementCurrent, pRecElement *ppCurrentElement) +{ + CFTypeID type = CFGetTypeID (refElementCurrent); + if (type == CFArrayGetTypeID()) // if element is an array + { + CFRange range = {0, CFArrayGetCount (refElementCurrent)}; + // CountElementsCFArrayHandler called for each array member + CFArrayApplyFunction (refElementCurrent, range, hid_GetElementsCFArrayHandler, ppCurrentElement); + } +} + +static void hid_TopLevelElementHandler (const void * value, void * parameter) +{ + CFTypeRef refCF = 0; + if ((NULL == value) || (NULL == parameter)) + return; // (kIOReturnBadArgument) + if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) + return; // (kIOReturnBadArgument) + refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsagePageKey)); + if (!CFNumberGetValue (refCF, kCFNumberLongType, &((pRecDevice) parameter)->usagePage)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->usagePage."); + refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsageKey)); + if (!CFNumberGetValue (refCF, kCFNumberLongType, &((pRecDevice) parameter)->usage)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->usage."); +} + + +static void hid_GetDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, pRecDevice pDevice) +{ + CFMutableDictionaryRef usbProperties = 0; + io_registry_entry_t parent1, parent2; + + // Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also + // get dictionary for usb properties: step up two levels and get CF dictionary for USB properties + if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) && + (KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) && + (KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) + { + if (usbProperties) + { + CFTypeRef refCF = 0; + // get device info + // try hid dictionary first, if fail then go to usb dictionary + + // get transport + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDTransportKey)); + if (refCF) + { + if (!CFStringGetCString (refCF, pDevice->transport, 256, CFStringGetSystemEncoding ())) + HIDReportError ("CFStringGetCString error retrieving pDevice->transport."); + } + + // get vendorID + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDVendorIDKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("idVendor")); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->vendorID)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->vendorID."); + } + + // get product ID + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductIDKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("idProduct")); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->productID)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->productID."); + } + + // get product version + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDVersionNumberKey)); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->version)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->version."); + } + + // get manufacturer name + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDManufacturerKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Vendor Name")); + if (refCF) + { + if (!CFStringGetCString (refCF, pDevice->manufacturer, 256, CFStringGetSystemEncoding ())) + HIDReportError ("CFStringGetCString error retrieving pDevice->manufacturer."); + } + + // get product name + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Product Name")); + if (refCF) + { + // ryan forced this to UTF-8. + //if (!CFStringGetCString (refCF, pDevice->product, 256, CFStringGetSystemEncoding ())) + if (!CFStringGetCString (refCF, pDevice->product, 256, kCFStringEncodingUTF8)) + HIDReportError ("CFStringGetCString error retrieving pDevice->product."); + } + + // get serial + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDSerialNumberKey)); + if (refCF) + { + if (!CFStringGetCString (refCF, pDevice->serial, 256, CFStringGetSystemEncoding ())) + HIDReportError ("CFStringGetCString error retrieving pDevice->serial."); + } + + // get location ID + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDLocationIDKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("locationID")); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->locID)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->locID."); + } + + // get usage page and usage + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->usagePage."); + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); + if (refCF) + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) + HIDReportError ("CFNumberGetValue error retrieving pDevice->usage."); + } + if (NULL == refCF) // get top level element HID usage page or usage + { + // use top level element instead + CFTypeRef refCFTopElement = 0; + refCFTopElement = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); + { + // refCFTopElement points to an array of element dictionaries + CFRange range = {0, CFArrayGetCount (refCFTopElement)}; + CFArrayApplyFunction (refCFTopElement, range, hid_TopLevelElementHandler, NULL); + } + } + } + else + HIDReportError ("IORegistryEntryCreateCFProperties failed to create usbProperties."); + + CFRelease (usbProperties); + if (kIOReturnSuccess != IOObjectRelease (parent2)) + HIDReportError ("IOObjectRelease error with parent2."); + if (kIOReturnSuccess != IOObjectRelease (parent1)) + HIDReportError ("IOObjectRelease error with parent1."); + } +} + + +static Boolean hid_MatchElementTypeMask (IOHIDElementType type, HIDElementTypeMask typeMask) +{ + if (typeMask & kHIDElementTypeInput) + if ((type == kIOHIDElementTypeInput_Misc) || (type == kIOHIDElementTypeInput_Button) || (type == kIOHIDElementTypeInput_Axis) || (type == kIOHIDElementTypeInput_ScanCodes)) + return true; + if (typeMask & kHIDElementTypeOutput) + if (type == kIOHIDElementTypeOutput) + return true; + if (typeMask & kHIDElementTypeFeature) + if (type == kIOHIDElementTypeFeature) + return true; + if (typeMask & kHIDElementTypeCollection) + if (type == kIOHIDElementTypeCollection) + return true; + return false; +} + +static pRecElement hid_GetDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask) +{ + // we are asking for this element + if (NULL != pElement) + { + if (hid_MatchElementTypeMask (pElement->type, typeMask)) // if the type match what we are looking for + return pElement; // return the element + else + return HIDGetNextDeviceElement (pElement, typeMask); // else get the next one + } + return NULL; +} + +static unsigned long HIDCloseReleaseInterface (pRecDevice pDevice) +{ + IOReturn result = kIOReturnSuccess; + + if (HIDIsValidDevice(pDevice) && (NULL != pDevice->interface)) + { + // close the interface + result = (*(IOHIDDeviceInterface**) pDevice->interface)->close (pDevice->interface); + if (kIOReturnNotOpen == result) + { + // do nothing as device was not opened, thus can't be closed + } + else if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to close IOHIDDeviceInterface.", result); + //release the interface + result = (*(IOHIDDeviceInterface**) pDevice->interface)->Release (pDevice->interface); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to release interface.", result); + pDevice->interface = NULL; + } + return result; +} + + +// --------------------------------- +// count number of devices in global device list (gpDeviceList) +static UInt32 hid_CountCurrentDevices (void) +{ + pRecDevice pDevice = gpDeviceList; + UInt32 devices = 0; + while (pDevice) + { + devices++; + pDevice = pDevice->pNext; + } + return devices; +} + +static UInt32 HIDCountDevices (void) +{ + gNumDevices = hid_CountCurrentDevices (); + + return gNumDevices; +} + +static void hid_DisposeDeviceElements (pRecElement pElement) +{ + if (pElement) + { + if (pElement->pChild) + hid_DisposeDeviceElements (pElement->pChild); + if (pElement->pSibling) + hid_DisposeDeviceElements (pElement->pSibling); + free (pElement); + } +} + +static pRecDevice hid_DisposeDevice (pRecDevice pDevice) +{ + kern_return_t result = KERN_SUCCESS; + pRecDevice pDeviceNext = NULL; + + if (HIDIsValidDevice(pDevice)) + { + // save next device prior to disposing of this device + pDeviceNext = pDevice->pNext; + + result = HIDDequeueDevice (pDevice); +#if 0 + if (kIOReturnSuccess != result) + HIDReportErrorNum ("hid_DisposeDevice: HIDDequeueDevice error: 0x%8.8X.", result); +#endif 1 + + hid_DisposeDeviceElements (pDevice->pListElements); + pDevice->pListElements = NULL; + + result = HIDCloseReleaseInterface (pDevice); // function sanity checks interface value (now application does not own device) + if (kIOReturnSuccess != result) + HIDReportErrorNum ("hid_DisposeDevice: HIDCloseReleaseInterface error: 0x%8.8X.", result); + +#if USE_NOTIFICATIONS + if (pDevice->interface) + { + // replace (*pDevice->interface)->Release(pDevice->interface); + result = IODestroyPlugInInterface (pDevice->interface); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("hid_DisposeDevice: IODestroyPlugInInterface error: 0x%8.8X.", result); + } + + if (pDevice->notification) + { + result = IOObjectRelease((io_object_t) pDevice->notification); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("hid_DisposeDevice: IOObjectRelease error: 0x%8.8X.", result); + } +#endif USE_NOTIFICATIONS + + // remove this device from the device list + if (gpDeviceList == pDevice) // head of list? + gpDeviceList = pDeviceNext; + else + { + pRecDevice pDeviceTemp = pDeviceNext = gpDeviceList; // we're going to return this if we don't find ourselfs in the list + while (pDeviceTemp) + { + if (pDeviceTemp->pNext == pDevice) // found us! + { + // take us out of linked list + pDeviceTemp->pNext = pDeviceNext = pDevice->pNext; + break; + } + pDeviceTemp = pDeviceTemp->pNext; + } + } + free (pDevice); + } + + // update device count + gNumDevices = hid_CountCurrentDevices (); + + return pDeviceNext; +} + + +// --------------------------------- +// disposes and releases queue, sets queue to NULL,. +// Note: will have no effect if device or queue do not exist + +static IOReturn hid_DisposeReleaseQueue (pRecDevice pDevice) +{ + IOReturn result = kIOReturnError; // assume failure (pessimist!) + + if (HIDIsValidDevice(pDevice)) // need valid device + { + if (pDevice->queue) // and queue + { + // stop queue + result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to stop queue.", result); + // dispose of queue + result = (*(IOHIDQueueInterface**) pDevice->queue)->dispose (pDevice->queue); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to dipose queue.", result); + // release the queue + result = (*(IOHIDQueueInterface**) pDevice->queue)->Release (pDevice->queue); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to release queue.", result); + + pDevice->queue = NULL; + } + else + HIDREPORTERROR ("hid_DisposeReleaseQueue - no queue."); + } + else + HIDREPORTERROR ("hid_DisposeReleaseQueue - Invalid device."); + return result; +} + + +// --------------------------------- +// completely removes all elements from queue and releases queue and closes device interface +// does not release device interfaces, application must call HIDReleaseDeviceList on exit + +static unsigned long HIDDequeueDevice (pRecDevice pDevice) +{ + IOReturn result = kIOReturnSuccess; + + if (HIDIsValidDevice(pDevice)) + { + if ((pDevice->interface) && (pDevice->queue)) + { + // iterate through elements and if queued, remove + pRecElement pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); + while (pElement) + { + if ((*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie)) + { + result = (*(IOHIDQueueInterface**) pDevice->queue)->removeElement (pDevice->queue, pElement->cookie); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDDequeueDevice - Failed to remove element from queue.", result); + } + pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); + } + } + // ensure queue is disposed and released + // interface will be closed and released on call to HIDReleaseDeviceList + result = hid_DisposeReleaseQueue (pDevice); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("removeElement - Failed to dispose and release queue.", result); +#if USE_ASYNC_EVENTS + else if (NULL != pDevice->queueRunLoopSource) + { + if (CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode)) + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode); + CFRelease(pDevice->queueRunLoopSource); + pDevice->queueRunLoopSource = NULL; + } +#endif USE_ASYNC_EVENTS + } + else + { + HIDREPORTERROR ("HIDDequeueDevice - Invalid device."); + result = kIOReturnBadArgument; + } + return result; +} + +// --------------------------------- +// releases all device queues for quit or rebuild (must be called) +// does not release device interfaces, application must call HIDReleaseDeviceList on exit + +static unsigned long HIDReleaseAllDeviceQueues (void) +{ + IOReturn result = kIOReturnBadArgument; + pRecDevice pDevice = HIDGetFirstDevice (); + + while (pDevice) + { + result = HIDDequeueDevice (pDevice); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDReleaseAllDeviceQueues - Could not dequeue device.", result); + pDevice = HIDGetNextDevice (pDevice); + } + return result; +} + + +// --------------------------------- +// Get the next event in the queue for a device +// elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice +// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise +// Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition +// Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility) + +static unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent) +{ + IOReturn result = kIOReturnBadArgument; + AbsoluteTime zeroTime = {0,0}; + + if (HIDIsValidDevice(pDevice)) + { + if (pDevice->queue) + { + result = (*(IOHIDQueueInterface**) pDevice->queue)->getNextEvent (pDevice->queue, (IOHIDEventStruct *)pHIDEvent, zeroTime, 0); + if (kIOReturnUnderrun == result) + return false; // no events in queue not an error per say + else if (kIOReturnSuccess != result) // actual error versus just an empty queue + HIDREPORTERRORNUM ("HIDGetEvent - Could not get HID event via getNextEvent.", result); + else + return true; + } + else + HIDREPORTERROR ("HIDGetEvent - queue does not exist."); + } + else + HIDREPORTERROR ("HIDGetEvent - invalid device."); + + return false; // did not get event +} + + +static unsigned long HIDCreateOpenDeviceInterface (UInt32 hidDevice, pRecDevice pDevice) +{ + IOReturn result = kIOReturnSuccess; + HRESULT plugInResult = S_OK; + SInt32 score = 0; + IOCFPlugInInterface ** ppPlugInInterface = NULL; + + if (NULL == pDevice->interface) + { + result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); + if (kIOReturnSuccess == result) + { + // Call a method of the intermediate plug-in to create the device interface + plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, + CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface)); + if (S_OK != plugInResult) + HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult); + IODestroyPlugInInterface (ppPlugInInterface); // replace (*ppPlugInInterface)->Release (ppPlugInInterface) + } + else + HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result); + } + if (NULL != pDevice->interface) + { + result = (*(IOHIDDeviceInterface**)pDevice->interface)->open (pDevice->interface, 0); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("Failed to open pDevice->interface via open.", result); + } + return result; +} + + +// --------------------------------- +// adds device to linked list of devices passed in (handles NULL lists properly) +// (returns where you just stored it) +static pRecDevice* hid_AddDevice (pRecDevice *ppListDeviceHead, pRecDevice pNewDevice) +{ + pRecDevice* result = NULL; + + if (NULL == *ppListDeviceHead) + result = ppListDeviceHead; + else + { + pRecDevice pDevicePrevious = NULL, pDevice = *ppListDeviceHead; + while (pDevice) + { + pDevicePrevious = pDevice; + pDevice = pDevicePrevious->pNext; + } + result = &pDevicePrevious->pNext; + } + pNewDevice->pNext = NULL; + + *result = pNewDevice; + + return result; +} + +static pRecDevice hid_BuildDevice (io_object_t hidDevice) +{ + pRecDevice pDevice = (pRecDevice) malloc (sizeof (recDevice)); + + if (NULL != pDevice) + { + // get dictionary for HID properties + CFMutableDictionaryRef hidProperties = 0; + kern_return_t result = IORegistryEntryCreateCFProperties (hidDevice, &hidProperties, kCFAllocatorDefault, kNilOptions); + + // clear record + bzero(pDevice, sizeof(recDevice)); + + if ((result == KERN_SUCCESS) && (NULL != hidProperties)) + { + pRecElement pCurrentElement = NULL; + // create device interface + result = HIDCreateOpenDeviceInterface (hidDevice, pDevice); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("HIDCreateOpenDeviceInterface failed.", result); + hid_GetDeviceInfo (hidDevice, hidProperties, pDevice); // hidDevice used to find parents in registry tree + // set current device for use in getting elements + gCurrentGetDevice = pDevice; + // Add all elements + hid_GetCollectionElements (hidProperties, &pCurrentElement); + gCurrentGetDevice = NULL; + CFRelease (hidProperties); + } + else + HIDReportErrorNum ("IORegistryEntryCreateCFProperties error when creating deviceProperties.", result); + } + else + HIDReportError ("malloc error when allocating pRecDevice."); + return pDevice; +} + + + +#if USE_NOTIFICATIONS +//================================================================================================ +// +// hid_DeviceNotification +// +// This routine will get called whenever any kIOGeneralInterest notification happens. We are +// interested in the kIOMessageServiceIsTerminated message so that's what we look for. Other +// messages are defined in IOMessage.h. +// +//================================================================================================ +// +static void hid_DeviceNotification( void *refCon, + io_service_t service, + natural_t messageType, + void *messageArgument ) +{ + pRecDevice pDevice = (pRecDevice) refCon; + + if (messageType == kIOMessageServiceIsTerminated) + { + //printf("Device 0x%08x \"%s\"removed.\n", service, pDevice->product); + // ryan added this. + if (pDevice->disconnect == DISCONNECT_CONNECTED) + pDevice->disconnect = DISCONNECT_TELLUSER; + + // Free the data we're no longer using now that the device is going away + // ryan commented this out. + //hid_DisposeDevice (pDevice); + } +} +#else + +static void hid_RemovalCallbackFunction(void * target, IOReturn result, void * refcon, void * sender) +{ + // ryan commented this out. + //hid_DisposeDevice ((pRecDevice) target); + + // ryan added this. + pRecDevice = (pRecDevice) target; + if (pDevice->disconnect == DISCONNECT_CONNECTED) + pDevice->disconnect = DISCONNECT_TELLUSER; +} + +#endif USE_NOTIFICATIONS + + + +static void hid_AddDevices (void *refCon, io_iterator_t iterator) +{ + // NOTE: refcon passed in is used to point to the device list head + pRecDevice* pListDeviceHead = (pRecDevice*) refCon; + IOReturn result = kIOReturnSuccess; + io_object_t ioHIDDeviceObject = 0; + + while ((ioHIDDeviceObject = IOIteratorNext (iterator)) != 0) + { + pRecDevice* pNewDeviceAt = NULL; + pRecDevice pNewDevice = hid_BuildDevice (ioHIDDeviceObject); + if (pNewDevice) + { +#if 0 // set true for verbose output + printf("\nhid_AddDevices: pNewDevice = {t: \"%s\", v: %ld, p: %ld, v: %ld, m: \"%s\", " \ + "p: \"%s\", l: %ld, u: %4.4lX:%4.4lX, #e: %ld, #f: %ld, #i: %ld, #o: %ld, " \ + "#c: %ld, #a: %ld, #b: %ld, #h: %ld, #s: %ld, #d: %ld, #w: %ld}.", + pNewDevice->transport, + pNewDevice->vendorID, + pNewDevice->productID, + pNewDevice->version, + pNewDevice->manufacturer, + pNewDevice->product, + pNewDevice->locID, + pNewDevice->usagePage, + pNewDevice->usage, + pNewDevice->totalElements, + pNewDevice->features, + pNewDevice->inputs, + pNewDevice->outputs, + pNewDevice->collections, + pNewDevice->axis, + pNewDevice->buttons, + pNewDevice->hats, + pNewDevice->sliders, + pNewDevice->dials, + pNewDevice->wheels + ); + fflush(stdout); +#elif 0 // otherwise output brief description + printf("\nhid_AddDevices: pNewDevice = {m: \"%s\" p: \"%s\", vid: %ld, pid: %ld, loc: %8.8lX, usage: %4.4lX:%4.4lX}.", + pNewDevice->manufacturer, + pNewDevice->product, + pNewDevice->vendorID, + pNewDevice->productID, + pNewDevice->locID, + pNewDevice->usagePage, + pNewDevice->usage + ); + fflush(stdout); +#endif + pNewDeviceAt = hid_AddDevice (pListDeviceHead, pNewDevice); + } + +#if USE_NOTIFICATIONS + // Register for an interest notification of this device being removed. Use a reference to our + // private data as the refCon which will be passed to the notification callback. + result = IOServiceAddInterestNotification( gNotifyPort, // notifyPort + ioHIDDeviceObject, // service + kIOGeneralInterest, // interestType + hid_DeviceNotification, // callback + pNewDevice, // refCon + (io_object_t*) &pNewDevice->notification); // notification + if (KERN_SUCCESS != result) + HIDReportErrorNum ("hid_AddDevices: IOServiceAddInterestNotification error: x0%8.8lX.", result); +#else + result = (*(IOHIDDeviceInterface**)pNewDevice->interface)->setRemovalCallback (pNewDevice->interface, hid_RemovalCallbackFunction,pNewDeviceAt,0); +#endif USE_NOTIFICATIONS + + // release the device object, it is no longer needed + result = IOObjectRelease (ioHIDDeviceObject); + if (KERN_SUCCESS != result) + HIDReportErrorNum ("hid_AddDevices: IOObjectRelease error with ioHIDDeviceObject.", result); + } +} + + +static Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage) +{ + IOReturn result = kIOReturnSuccess; + mach_port_t masterPort = 0; + + if (NULL != gpDeviceList) + HIDReleaseDeviceList (); + + result = IOMasterPort (bootstrap_port, &masterPort); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("IOMasterPort error with bootstrap_port.", result); + else + { + CFMutableDictionaryRef hidMatchDictionary = NULL; + + // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error. + { + CFNumberRef refUsage = NULL, refUsagePage = NULL; + + // Set up a matching dictionary to search I/O Registry by class name for all HID class devices. + hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); + if (NULL != hidMatchDictionary) + { + if (usagePage) + { + // Add key for device type (joystick, in this case) to refine the matching dictionary. + refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberLongType, &usagePage); + CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); + CFRelease (refUsagePage); + if (usage) + { + refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberLongType, &usage); + CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); + CFRelease (refUsage); + } + } + CFRetain(hidMatchDictionary); + } + else + HIDReportError ("Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); + } + +#if USE_NOTIFICATIONS + // Create a notification port and add its run loop event source to our run loop + // This is how async notifications get set up. + { + CFRunLoopSourceRef runLoopSource; + + gNotifyPort = IONotificationPortCreate(masterPort); + runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); + + gRunLoop = CFRunLoopGetCurrent(); + CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode); + + // Now set up a notification to be called when a device is first matched by I/O Kit. + result = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort + kIOFirstMatchNotification, // notificationType + hidMatchDictionary, // matching + hid_AddDevices, // callback + &gpDeviceList, // refCon + &gAddedIter // notification + ); + + // call it now to add all existing devices + hid_AddDevices(&gpDeviceList,gAddedIter); + return true; + } +#else + { + io_iterator_t hidObjectIterator = NULL; + + // Now search I/O Registry for matching devices. + result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("Failed to create IO object iterator, error:", result); + else if (NULL == hidObjectIterator) // likely no HID devices which matched selection criteria are connected + HIDReportError ("Warning: Could not find any matching devices, thus iterator creation failed."); + + if (NULL != hidObjectIterator) + { + hid_AddDevices(&gpDeviceList,hidObjectIterator); + + result = IOObjectRelease (hidObjectIterator); // release the iterator + if (kIOReturnSuccess != result) + HIDReportErrorNum ("IOObjectRelease error with hidObjectIterator.", result); + + gNumDevices = hid_CountCurrentDevices (); + return true; + } + } +#endif USE_NOTIFICATIONS + // IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. + hidMatchDictionary = NULL; + } + return false; +} + +// --------------------------------- +// release list built by above function +// MUST be called prior to application exit to properly release devices +// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain + +static void HIDReleaseDeviceList (void) +{ + while (NULL != gpDeviceList) + gpDeviceList = hid_DisposeDevice (gpDeviceList); // dispose current device return next device will set gpDeviceList to NULL + gNumDevices = 0; +} + +// --------------------------------- +// get the first device in the device list +// returns NULL if no list exists + +static pRecDevice HIDGetFirstDevice (void) +{ + return gpDeviceList; +} + +// --------------------------------- +// get next device in list given current device as parameter +// returns NULL if end of list + +static pRecDevice HIDGetNextDevice (pRecDevice pDevice) +{ + if (NULL != pDevice) + return pDevice->pNext; + else + return NULL; +} + +// --------------------------------- +// get the first element of device passed in as parameter +// returns NULL if no list exists or device does not exists or is NULL +static pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask) +{ + if (HIDIsValidDevice(pDevice)) + { + if (hid_MatchElementTypeMask (pDevice->pListElements->type, typeMask)) // ensure first type matches + return pDevice->pListElements; + else + return HIDGetNextDeviceElement (pDevice->pListElements, typeMask); + } + else + return NULL; +} + +// --------------------------------- +// get next element of given device in list given current element as parameter +// will walk down each collection then to next element or collection (depthwise traverse) +// returns NULL if end of list +// uses mask of HIDElementTypeMask to restrict element found +// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality +static pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask) +{ + // should only have elements passed in (though someone could mix calls and pass us a collection) + // collection means return the next child or sibling (in that order) + // element means returnt he next sibling (as elements can't have children + if (NULL != pElement) + { + if (pElement->pChild) + { + if (pElement->type != kIOHIDElementTypeCollection) + HIDReportError ("Malformed element list: found child of element."); + else + return hid_GetDeviceElement (pElement->pChild, typeMask); // return the child of this element + } + else if (pElement->pSibling) + { + return hid_GetDeviceElement (pElement->pSibling, typeMask); //return the sibling of this element + } + else // at end back up correctly + { + pRecElement pPreviousElement = NULL; + // malformed device ending in collection + if (pElement->type == kIOHIDElementTypeCollection) + HIDReportError ("Malformed device: found collection at end of element chain."); + // walk back up tree to element prior to first collection ecountered and take next element + while (NULL != pElement->pPrevious) + { + pPreviousElement = pElement; + pElement = pElement->pPrevious; // look at previous element + // if we have a collection and the previous element is the branch element (should have both a colection and next element attached to it) + // if we found a collection, which we are not at the sibling level that actually does have siblings + if (((pElement->type == kIOHIDElementTypeCollection) && (pPreviousElement != pElement->pSibling) && pElement->pSibling) || + // or if we are at the top + (NULL == pElement->pPrevious)) // at top of tree + break; + } + if (NULL == pElement->pPrevious) + return NULL; // got to top of list with only a collection as the first element + // now we must have been down the child route so go down the sibling route + pElement = pElement->pSibling; // element of interest + return hid_GetDeviceElement (pElement, typeMask); // otherwise return this element + } + } + return NULL; +} + + +// return true if this is a valid device pointer +Boolean HIDIsValidDevice(const pRecDevice pSearchDevice) +{ + pRecDevice pDevice = gpDeviceList; + + while (pDevice) + { + if (pDevice == pSearchDevice) + return true; + pDevice = pDevice->pNext; + } + return false; +} + + +static IOReturn hid_CreateQueue (pRecDevice pDevice) +{ + IOReturn result = kIOReturnError; // assume failure (pessimist!) + + if (HIDIsValidDevice(pDevice)) + { + if (NULL == pDevice->queue) // do we already have a queue + { + if (NULL != pDevice->interface) + { + pDevice->queue = (void *) (*(IOHIDDeviceInterface**) pDevice->interface)->allocQueue (pDevice->interface); // alloc queue + if (pDevice->queue) + { + result = (*(IOHIDQueueInterface**) pDevice->queue)->create (pDevice->queue, 0, kDeviceQueueSize); // create actual queue + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("hid_CreateQueue - Failed to create queue via create", result); + } + else + { + HIDREPORTERROR ("hid_CreateQueue - Failed to alloc IOHIDQueueInterface ** via allocQueue"); + result = kIOReturnError; // synthesis error + } + } + else + HIDREPORTERRORNUM ("hid_CreateQueue - Device inteface does not exist for queue creation", result); + } + } + else + HIDREPORTERRORNUM ("hid_CreateQueue - Invalid Device", result); + return result; +} + +static unsigned long HIDQueueDevice (pRecDevice pDevice) +{ + IOReturn result = kIOReturnError; // assume failure (pessimist!) + pRecElement pElement; + + if (HIDIsValidDevice(pDevice)) + { + // error checking + if (NULL == pDevice) + { + HIDREPORTERROR ("HIDQueueDevice - Device does not exist."); + return kIOReturnBadArgument; + } + if (NULL == pDevice->interface) // must have interface + { + HIDREPORTERROR ("HIDQueueDevice - Device does not have interface."); + return kIOReturnError; + } + if (NULL == pDevice->queue) // if no queue create queue + result = hid_CreateQueue (pDevice); + if ((kIOReturnSuccess != result) || (NULL == pDevice->queue)) + { + HIDREPORTERRORNUM ("HIDQueueDevice - problem creating queue.", result); + if (kIOReturnSuccess != result) + return result; + else + return kIOReturnError; + } + + // stop queue + result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDQueueDevice - Failed to stop queue.", result); + + // queue element + //¥ pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); + pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeInput | kHIDElementTypeFeature); + + while (pElement) + { + if (!(*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie)) + { + result = (*(IOHIDQueueInterface**) pDevice->queue)->addElement (pDevice->queue, pElement->cookie, 0); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDQueueDevice - Failed to add element to queue.", result); + } + //¥ pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); + pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeInput | kHIDElementTypeFeature); + } + + // start queue + result = (*(IOHIDQueueInterface**) pDevice->queue)->start (pDevice->queue); + if (kIOReturnSuccess != result) + HIDREPORTERRORNUM ("HIDQueueDevice - Failed to start queue.", result); + + } + else + HIDREPORTERROR ("HIDQueueDevice - Invalid device."); + + return result; +} + + +/* -- END HID UTILITIES -- */ + + +static int logical_mice = 0; +static int physical_mice = 0; +static pRecDevice *devices = NULL; + +static inline int is_trackpad(const pRecDevice dev) +{ + /* + * This stupid thing shows up as two logical devices. One does + * most of the mouse events, the other does the mouse wheel. + */ + return (strcmp(dev->product, "Apple Internal Keyboard / Trackpad") == 0); +} /* is_trackpad */ + + +/* returns non-zero if (a <= b). */ +typedef unsigned long long ui64; +static inline int oldEvent(const AbsoluteTime *a, const AbsoluteTime *b) +{ +#if 0 // !!! FIXME: doesn't work, timestamps aren't reliable. + const ui64 a64 = (((unsigned long long) a->hi) << 32) | a->lo; + const ui64 b64 = (((unsigned long long) b->hi) << 32) | b->lo; +#endif + return 0; +} /* oldEvent */ + +static int poll_mouse(pRecDevice mouse, ManyMouseEvent *outevent) +{ + int unhandled = 1; + while (unhandled) /* read until failure or valid event. */ + { + pRecElement recelem; + IOHIDEventStruct event; + + if (!HIDGetEvent(mouse, &event)) + return 0; /* no new event. */ + + unhandled = 0; /* will reset if necessary. */ + recelem = HIDGetFirstDeviceElement(mouse, kHIDElementTypeInput); + while (recelem != NULL) + { + if (recelem->cookie == event.elementCookie) + break; + recelem = HIDGetNextDeviceElement(recelem, kHIDElementTypeInput); + } /* while */ + + if (recelem == NULL) + continue; /* unknown device element. Can this actually happen? */ + + outevent->value = event.value; + if (recelem->usagePage == kHIDPage_GenericDesktop) + { + /* + * some devices (two-finger-scroll trackpads?) seem to give + * a flood of events with values of zero for every legitimate + * event. Throw these zero events out. + */ + if (outevent->value == 0) + unhandled = 1; + else + { + switch (recelem->usage) + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + if (oldEvent(&event.timestamp, &mouse->lastScrollTime)) + unhandled = 1; + else + { + outevent->type = MANYMOUSE_EVENT_RELMOTION; + if (recelem->usage == kHIDUsage_GD_X) + outevent->item = 0; + else + outevent->item = 1; + } /* else */ + break; + + case kHIDUsage_GD_Wheel: + memcpy(&mouse->lastScrollTime, &event.timestamp, + sizeof (AbsoluteTime)); + outevent->type = MANYMOUSE_EVENT_SCROLL; + outevent->item = 0; /* !!! FIXME: horiz scroll? */ + break; + + default: /* !!! FIXME: absolute motion? */ + unhandled = 1; + } /* switch */ + } /* else */ + } /* if */ + + else if (recelem->usagePage == kHIDPage_Button) + { + outevent->type = MANYMOUSE_EVENT_BUTTON; + outevent->item = ((int) recelem->usage) - 1; + } /* else if */ + + else + { + unhandled = 1; + } /* else */ + } /* while */ + + return 1; /* got a valid event */ +} /* poll_mouse */ + + +static void macosx_hidutilities_quit(void) +{ + HIDReleaseAllDeviceQueues(); + HIDReleaseDeviceList(); + free(devices); + devices = NULL; + logical_mice = 0; + physical_mice = 0; +} /* macosx_hidutilities_quit */ + + +static int macosx_hidutilities_init(void) +{ + macosx_hidutilities_quit(); /* just in case... */ + + if (!HIDBuildDeviceList(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) + return -1; + + physical_mice = HIDCountDevices(); + if (physical_mice > 0) + { + pRecDevice dev = NULL; + int trackpad = -1; + int i; + + dev = HIDGetFirstDevice(); + devices = (pRecDevice *) malloc(sizeof (pRecDevice) * physical_mice); + if ((devices == NULL) || (dev == NULL)) + { + macosx_hidutilities_quit(); + return -1; + } /* if */ + + for (i = 0; i < physical_mice; i++) + { + if (dev == NULL) /* what? list ended? Truncate final list... */ + physical_mice = i; + + if (HIDQueueDevice(dev) == kIOReturnSuccess) + { + if (!is_trackpad(dev)) + dev->logical = logical_mice++; + else + { + if (trackpad < 0) + trackpad = logical_mice++; + dev->logical = trackpad; + } /* else */ + devices[i] = dev; + } /* if */ + + else /* failed? Chop this device from the list... */ + { + i--; + physical_mice--; + } /* else */ + + dev = HIDGetNextDevice(dev); + } /* for */ + } /* if */ + + return logical_mice; +} /* macosx_hidutilities_init */ + + +/* returns the first physical device that backs a logical device. */ +static pRecDevice map_logical_device(const unsigned int index) +{ + if (index < logical_mice) + { + unsigned int i; + for (i = 0; i < physical_mice; i++) + { + if (devices[i]->logical == ((int) index)) + return devices[i]; + } /* for */ + } /* if */ + + return NULL; /* not found (maybe unplugged?) */ +} /* map_logical_device */ + + +static const char *macosx_hidutilities_name(unsigned int index) +{ + pRecDevice dev = map_logical_device(index); + return (dev != NULL) ? dev->product : NULL; +} /* macosx_hidutilities_name */ + + +static int macosx_hidutilities_poll(ManyMouseEvent *event) +{ + /* + * (i) is static so we iterate through all mice round-robin. This + * prevents a chatty mouse from dominating the queue. + */ + static unsigned int i = 0; + + if (i >= physical_mice) + i = 0; /* handle reset condition. */ + + if (event != NULL) + { + while (i < physical_mice) + { + pRecDevice dev = devices[i]; + if ((dev) && (dev->disconnect != DISCONNECT_COMPLETE)) + { + const int logical = dev->logical; + event->device = logical; + + /* see if mouse was unplugged since last polling... */ + if (dev->disconnect == DISCONNECT_TELLUSER) + { + int j; + + /* disable physical devices backing this logical mouse. */ + for (j = 0; j < physical_mice; j++) + { + if (devices[j]->logical == logical) + { + devices[j]->disconnect = DISCONNECT_COMPLETE; + devices[j]->logical = -1; + } /* if */ + } /* for */ + + event->type = MANYMOUSE_EVENT_DISCONNECT; + return 1; + } /* if */ + + if (poll_mouse(dev, event)) + return 1; + } /* if */ + i++; + } /* while */ + } /* if */ + + return 0; /* no new events */ +} /* macosx_hidutilities_poll */ + +static const ManyMouseDriver ManyMouseDriver_interface = +{ + "Mac OS X Legacy HID Utilities", + macosx_hidutilities_init, + macosx_hidutilities_quit, + macosx_hidutilities_name, + macosx_hidutilities_poll +}; + +const ManyMouseDriver *ManyMouseDriver_hidutilities = &ManyMouseDriver_interface; + +#else +const ManyMouseDriver *ManyMouseDriver_hidutilities = 0; +#endif /* ifdef Mac OS X blocker */ + +/* end of macosx_hidutilities.c ... */ + diff --git a/manymouse/manymouse.c b/manymouse/manymouse.c new file mode 100644 index 000000000..ea1c988b4 --- /dev/null +++ b/manymouse/manymouse.c @@ -0,0 +1,100 @@ +/* + * ManyMouse foundation code; apps talks to this and it talks to the lowlevel + * code for various platforms. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include +#include "manymouse.h" + +static const char *manymouse_copyright = + "ManyMouse " MANYMOUSE_VERSION " copyright (c) 2005-2011 Ryan C. Gordon."; + +extern const ManyMouseDriver *ManyMouseDriver_windows; +extern const ManyMouseDriver *ManyMouseDriver_evdev; +extern const ManyMouseDriver *ManyMouseDriver_hidmanager; +extern const ManyMouseDriver *ManyMouseDriver_hidutilities; +extern const ManyMouseDriver *ManyMouseDriver_xinput2; + +/* + * These have to be in the favored order...obviously it doesn't matter if the + * Linux driver comes before or after the Windows one, since one won't + * exist on a given platform, but things like Mac OS X's hidmanager (which + * only works on OS X 10.5 and later) should come before Mac OS X's + * hidutilities (which works on older systems, but may stop working in 10.6 + * and later). In the Mac OS X case, you want to try the newer tech, and if + * it's not available (on 10.4 or earlier), fall back to trying the legacy + * code. + */ +static const ManyMouseDriver **mice_drivers[] = +{ + &ManyMouseDriver_xinput2, + &ManyMouseDriver_evdev, + &ManyMouseDriver_windows, + &ManyMouseDriver_hidmanager, + &ManyMouseDriver_hidutilities, +}; + + +static const ManyMouseDriver *driver = NULL; + +int ManyMouse_Init(void) +{ + const int upper = (sizeof (mice_drivers) / sizeof (mice_drivers[0])); + int i; + int retval = -1; + + /* impossible test to keep manymouse_copyright linked into the binary. */ + if (manymouse_copyright == NULL) + return -1; + + if (driver != NULL) + return -1; + + for (i = 0; (i < upper) && (driver == NULL); i++) + { + const ManyMouseDriver *this_driver = *(mice_drivers[i]); + if (this_driver != NULL) /* if not built for this platform, skip it. */ + { + const int mice = this_driver->init(); + if (mice > retval) + retval = mice; /* may move from "error" to "no mice found". */ + + if (mice > 0) + driver = this_driver; + } /* if */ + } /* for */ + + return retval; +} /* ManyMouse_Init */ + + +void ManyMouse_Quit(void) +{ + if (driver != NULL) + { + driver->quit(); + driver = NULL; + } /* if */ +} /* ManyMouse_Quit */ + +const char *ManyMouse_DriverName(void) +{ + return (driver) ? driver->driver_name : NULL; +} /* ManyMouse_DriverName */ + +const char *ManyMouse_DeviceName(unsigned int index) +{ + return (driver) ? driver->name(index) : NULL; +} /* ManyMouse_DeviceName */ + +int ManyMouse_PollEvent(ManyMouseEvent *event) +{ + return (driver) ? driver->poll(event) : 0; +} /* ManyMouse_PollEvent */ + +/* end of manymouse.c ... */ + diff --git a/manymouse/manymouse.h b/manymouse/manymouse.h new file mode 100644 index 000000000..870fa2155 --- /dev/null +++ b/manymouse/manymouse.h @@ -0,0 +1,63 @@ +/* + * ManyMouse main header. Include this from your app. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#ifndef _INCLUDE_MANYMOUSE_H_ +#define _INCLUDE_MANYMOUSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MANYMOUSE_VERSION "0.0.3" + +typedef enum +{ + MANYMOUSE_EVENT_ABSMOTION = 0, + MANYMOUSE_EVENT_RELMOTION, + MANYMOUSE_EVENT_BUTTON, + MANYMOUSE_EVENT_SCROLL, + MANYMOUSE_EVENT_DISCONNECT, + MANYMOUSE_EVENT_MAX +} ManyMouseEventType; + +typedef struct +{ + ManyMouseEventType type; + unsigned int device; + unsigned int item; + int value; + int minval; + int maxval; +} ManyMouseEvent; + + +/* internal use only. */ +typedef struct +{ + const char *driver_name; + int (*init)(void); + void (*quit)(void); + const char *(*name)(unsigned int index); + int (*poll)(ManyMouseEvent *event); +} ManyMouseDriver; + + +int ManyMouse_Init(void); +const char *ManyMouse_DriverName(void); +void ManyMouse_Quit(void); +const char *ManyMouse_DeviceName(unsigned int index); +int ManyMouse_PollEvent(ManyMouseEvent *event); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined _INCLUDE_MANYMOUSE_H_ */ + +/* end of manymouse.h ... */ + diff --git a/manymouse/windows_wminput.c b/manymouse/windows_wminput.c new file mode 100644 index 000000000..7d1f9142e --- /dev/null +++ b/manymouse/windows_wminput.c @@ -0,0 +1,713 @@ +/* + * Support for Windows via the WM_INPUT message. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include "manymouse.h" + +#if (defined(_WIN32) || defined(_WINDOWS) || defined(__CYGWIN__)) + +/* WinUser.h won't include rawinput stuff without this... */ +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include /* needed for alloca(). */ + +/* Cygwin's headers don't have WM_INPUT right now... */ +#ifndef WM_INPUT +#define WM_INPUT 0x00FF +#endif + +/* that should be enough, knock on wood. */ +#define MAX_MICE 32 + +/* + * Just trying to avoid malloc() here...we statically allocate a buffer + * for events and treat it as a ring buffer. + */ +/* !!! FIXME: tweak this? */ +#define MAX_EVENTS 1024 +static ManyMouseEvent input_events[MAX_EVENTS]; +static volatile int input_events_read = 0; +static volatile int input_events_write = 0; +static int available_mice = 0; +static int did_api_lookup = 0; +static HWND raw_hwnd = NULL; +static const char *class_name = "ManyMouseRawInputCatcher"; +static const char *win_name = "ManyMouseRawInputMsgWindow"; +static ATOM class_atom = 0; +static CRITICAL_SECTION mutex; + +typedef struct +{ + HANDLE handle; + char name[256]; +} MouseStruct; +static MouseStruct mice[MAX_MICE]; + + +/* + * The RawInput APIs only exist in Windows XP and later, so you want this + * to fail gracefully on earlier systems instead of refusing to start the + * process due to missing symbols. To this end, we do a symbol lookup on + * User32.dll, etc to get the entry points. + * + * A lot of these are available all the way back to the start of win32 in + * Windows 95 and WinNT 3.1, but just so you don't have to track down any + * import libraries, I've added those here, too. That fits well with the + * idea of just adding the sources to your build and going forward. + */ +static UINT (WINAPI *pGetRawInputDeviceList)(PRAWINPUTDEVICELIST,PUINT,UINT); +/* !!! FIXME: use unicode version */ +static UINT (WINAPI *pGetRawInputDeviceInfoA)(HANDLE,UINT,LPVOID,PUINT); +static BOOL (WINAPI *pRegisterRawInputDevices)(PCRAWINPUTDEVICE,UINT,UINT); +static LRESULT (WINAPI *pDefRawInputProc)(PRAWINPUT *,INT,UINT); +static UINT (WINAPI *pGetRawInputBuffer)(PRAWINPUT,PUINT,UINT); +static UINT (WINAPI *pGetRawInputData)(HRAWINPUT,UINT,LPVOID,PUINT,UINT); +static HWND (WINAPI *pCreateWindowExA)(DWORD,LPCTSTR,LPCTSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID); +static ATOM (WINAPI *pRegisterClassExA)(CONST WNDCLASSEX *); +static LRESULT (WINAPI *pDefWindowProcA)(HWND,UINT,WPARAM,LPARAM); +static BOOL (WINAPI *pUnregisterClassA)(LPCTSTR,HINSTANCE); +static HMODULE (WINAPI *pGetModuleHandleA)(LPCTSTR); +static BOOL (WINAPI *pPeekMessageA)(LPMSG,HWND,UINT,UINT,UINT); +static BOOL (WINAPI *pTranslateMessage)(const MSG *); +static LRESULT (WINAPI *pDispatchMessageA)(const MSG *); +static BOOL (WINAPI *pDestroyWindow)(HWND); +static void (WINAPI *pInitializeCriticalSection)(LPCRITICAL_SECTION); +static void (WINAPI *pEnterCriticalSection)(LPCRITICAL_SECTION); +static void (WINAPI *pLeaveCriticalSection)(LPCRITICAL_SECTION); +static void (WINAPI *pDeleteCriticalSection)(LPCRITICAL_SECTION); +static DWORD (WINAPI *pGetLastError)(void); +static HDEVINFO (WINAPI *pSetupDiGetClassDevsA)(LPGUID, LPCTSTR, HWND, DWORD); +static BOOL (WINAPI *pSetupDiEnumDeviceInfo)(HDEVINFO, DWORD, PSP_DEVINFO_DATA); +static BOOL (WINAPI *pSetupDiGetDeviceInstanceIdA)(HDEVINFO, PSP_DEVINFO_DATA, PTSTR, DWORD, PDWORD); +static BOOL (WINAPI *pSetupDiGetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD); +static BOOL (WINAPI *pSetupDiDestroyDeviceInfoList)(HDEVINFO); + +static int symlookup(HMODULE dll, void **addr, const char *sym) +{ + *addr = GetProcAddress(dll, sym); + if (*addr == NULL) + { + FreeLibrary(dll); + return 0; + } /* if */ + + return 1; +} /* symlookup */ + +static int find_api_symbols(void) +{ + HMODULE dll; + + if (did_api_lookup) + return 1; + + #define LOOKUP(x) { if (!symlookup(dll, (void **) &p##x, #x)) return 0; } + dll = LoadLibrary(TEXT("user32.dll")); + if (dll == NULL) + return 0; + + LOOKUP(GetRawInputDeviceInfoA); + LOOKUP(RegisterRawInputDevices); + LOOKUP(GetRawInputDeviceList); + LOOKUP(DefRawInputProc); + LOOKUP(GetRawInputBuffer); + LOOKUP(GetRawInputData); + LOOKUP(CreateWindowExA); + LOOKUP(RegisterClassExA); + LOOKUP(UnregisterClassA); + LOOKUP(DefWindowProcA); + LOOKUP(PeekMessageA); + LOOKUP(TranslateMessage); + LOOKUP(DispatchMessageA); + LOOKUP(DestroyWindow); + + dll = LoadLibrary(TEXT("kernel32.dll")); + if (dll == NULL) + return 0; + + LOOKUP(GetModuleHandleA); + LOOKUP(GetLastError); + LOOKUP(InitializeCriticalSection); + LOOKUP(EnterCriticalSection); + LOOKUP(LeaveCriticalSection); + LOOKUP(DeleteCriticalSection); + + dll = LoadLibrary(TEXT("setupapi.dll")); + if (dll == NULL) + return 0; + + LOOKUP(SetupDiGetClassDevsA); + LOOKUP(SetupDiEnumDeviceInfo); + LOOKUP(SetupDiGetDeviceInstanceIdA); + LOOKUP(SetupDiGetDeviceRegistryPropertyA); + LOOKUP(SetupDiDestroyDeviceInfoList); + + #undef LOOKUP + + did_api_lookup = 1; + return 1; +} /* find_api_symbols */ + + +/* Some simple functions to avoid C runtime dependency... */ + +static char make_upper(const char a) +{ + return ((a >= 'a') && (a <= 'z')) ? (a - ('a' - 'A')) : a; +} /* make_upper */ + +static void make_string_upper(char *str) +{ + char *ptr; + for (ptr = str; *ptr; ptr++) + *ptr = make_upper(*ptr); +} /* make_string_upper */ + +static int string_compare(const char *a, const char *b) +{ + while (1) + { + const char cha = *(a++); + const char chb = *(b++); + if (cha < chb) + return -1; + else if (cha > chb) + return 1; + else if (cha == '\0') + return 0; + } /* while */ + + return 0; +} /* string_compare */ + +static size_t string_length(const char *a) +{ + size_t retval; + for (retval = 0; *(a++); retval++) { /* spin. */ } + return retval; +} /* string_length */ + + +static void queue_event(const ManyMouseEvent *event) +{ + /* copy the event info. We'll process it in ManyMouse_PollEvent(). */ + CopyMemory(&input_events[input_events_write], event, sizeof (ManyMouseEvent)); + + input_events_write = ((input_events_write + 1) % MAX_EVENTS); + + /* Ring buffer full? Lose oldest event. */ + if (input_events_write == input_events_read) + { + /* !!! FIXME: we need to not lose mouse buttons here. */ + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + } /* if */ +} /* queue_event */ + + +static void queue_from_rawinput(const RAWINPUT *raw) +{ + int i; + const RAWINPUTHEADER *header = &raw->header; + const RAWMOUSE *mouse = &raw->data.mouse; + ManyMouseEvent event; + + if (raw->header.dwType != RIM_TYPEMOUSE) + return; + + for (i = 0; i < available_mice; i++) /* find the device for event. */ + { + if (mice[i].handle == header->hDevice) + break; + } /* for */ + + if (i == available_mice) + return; /* not found?! */ + + /* + * RAWINPUT packs a bunch of events into one, so we split it up into + * a bunch of ManyMouseEvents here and store them in an internal queue. + * Then ManyMouse_PollEvent() just shuffles items off that queue + * without any complicated processing. + */ + + event.device = i; + + pEnterCriticalSection(&mutex); + + if (mouse->usFlags & MOUSE_MOVE_ABSOLUTE) + { + /* !!! FIXME: How do we get the min and max values for absmotion? */ + event.type = MANYMOUSE_EVENT_ABSMOTION; + event.item = 0; + event.value = mouse->lLastX; + queue_event(&event); + event.item = 1; + event.value = mouse->lLastY; + queue_event(&event); + } /* if */ + + else /*if (mouse->usFlags & MOUSE_MOVE_RELATIVE)*/ + { + event.type = MANYMOUSE_EVENT_RELMOTION; + if (mouse->lLastX != 0) + { + event.item = 0; + event.value = mouse->lLastX; + queue_event(&event); + } /* if */ + + if (mouse->lLastY != 0) + { + event.item = 1; + event.value = mouse->lLastY; + queue_event(&event); + } /* if */ + } /* else if */ + + event.type = MANYMOUSE_EVENT_BUTTON; + + #define QUEUE_BUTTON(x) { \ + if (mouse->usButtonFlags & RI_MOUSE_BUTTON_##x##_DOWN) { \ + event.item = x-1; \ + event.value = 1; \ + queue_event(&event); \ + } \ + if (mouse->usButtonFlags & RI_MOUSE_BUTTON_##x##_UP) { \ + event.item = x-1; \ + event.value = 0; \ + queue_event(&event); \ + } \ + } + + QUEUE_BUTTON(1); + QUEUE_BUTTON(2); + QUEUE_BUTTON(3); + QUEUE_BUTTON(4); + QUEUE_BUTTON(5); + + #undef QUEUE_BUTTON + + if (mouse->usButtonFlags & RI_MOUSE_WHEEL) + { + if (mouse->usButtonData != 0) /* !!! FIXME: can this ever be zero? */ + { + event.type = MANYMOUSE_EVENT_SCROLL; + event.item = 0; /* !!! FIXME: horizontal wheel? */ + event.value = ( ((SHORT) mouse->usButtonData) > 0) ? 1 : -1; + queue_event(&event); + } /* if */ + } /* if */ + + pLeaveCriticalSection(&mutex); +} /* queue_from_rawinput */ + + +static void wminput_handler(WPARAM wParam, LPARAM lParam) +{ + UINT dwSize = 0; + LPBYTE lpb; + + pGetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &dwSize, + sizeof (RAWINPUTHEADER)); + + if (dwSize < sizeof (RAWINPUT)) + return; /* unexpected packet? */ + + lpb = (LPBYTE) alloca(dwSize); + if (lpb == NULL) + return; + if (pGetRawInputData((HRAWINPUT) lParam, RID_INPUT, lpb, &dwSize, + sizeof (RAWINPUTHEADER)) != dwSize) + return; + + queue_from_rawinput((RAWINPUT *) lpb); +} /* wminput_handler */ + + +static LRESULT CALLBACK RawWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (Msg == WM_INPUT) + wminput_handler(wParam, lParam); + + else if (Msg == WM_DESTROY) + return 0; + + return pDefWindowProcA(hWnd, Msg, wParam, lParam); +} /* RawWndProc */ + + +static int init_event_queue(void) +{ + HINSTANCE hInstance = pGetModuleHandleA(NULL); + WNDCLASSEX wce; + RAWINPUTDEVICE rid; + + ZeroMemory(input_events, sizeof (input_events)); + input_events_read = input_events_write = 0; + + ZeroMemory(&wce, sizeof (wce)); + wce.cbSize = sizeof(WNDCLASSEX); + wce.lpfnWndProc = RawWndProc; + wce.lpszClassName = class_name; + wce.hInstance = hInstance; + class_atom = pRegisterClassExA(&wce); + if (class_atom == 0) + return 0; + + raw_hwnd = pCreateWindowExA(0, class_name, win_name, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL); + + if (raw_hwnd == NULL) + return 0; + + pInitializeCriticalSection(&mutex); + + ZeroMemory(&rid, sizeof (rid)); + rid.usUsagePage = 1; /* GenericDesktop page */ + rid.usUsage = 2; /* GeneralDestop Mouse usage. */ + rid.dwFlags = RIDEV_INPUTSINK; + rid.hwndTarget = raw_hwnd; + if (!pRegisterRawInputDevices(&rid, 1, sizeof (rid))) + { + pDeleteCriticalSection(&mutex); + return 0; + } /* if */ + + return 1; +} /* init_event_queue */ + + +static void cleanup_window(void) +{ + if (raw_hwnd) + { + MSG Msg; + pDestroyWindow(raw_hwnd); + while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) + { + pTranslateMessage(&Msg); + pDispatchMessageA(&Msg); + } /* while */ + raw_hwnd = 0; + } /* if */ + + if (class_atom) + { + pUnregisterClassA(class_name, pGetModuleHandleA(NULL)); + class_atom = 0; + } /* if */ +} /* cleanup_window */ + + +static int get_devinfo_data(HDEVINFO devinfo, const char *devinstance, + SP_DEVINFO_DATA *data) +{ + DWORD i = 0; + const DWORD bufsize = string_length(devinstance) + 1; + char *buf = (char *) alloca(bufsize); + if (buf == NULL) + return 0; + + while (1) + { + ZeroMemory(data, sizeof (SP_DEVINFO_DATA)); + data->cbSize = sizeof (SP_DEVINFO_DATA); + if (!pSetupDiEnumDeviceInfo(devinfo, i++, data)) + { + if (pGetLastError() == ERROR_NO_MORE_ITEMS) + break; + else + continue; + } /* if */ + + if (!pSetupDiGetDeviceInstanceIdA(devinfo, data, buf, bufsize, NULL)) + continue; + + make_string_upper(buf); + if (string_compare(devinstance, buf) == 0) + return 1; /* found it! */ + } /* while */ + + return 0; /* not found. */ +} /* get_devinfo_data */ + + +static void get_dev_name_by_instance(const char *devinstance, char *name, + size_t namesize) +{ + SP_DEVINFO_DATA devdata; + const DWORD flags = DIGCF_ALLCLASSES | DIGCF_PRESENT; + HDEVINFO devinfo = pSetupDiGetClassDevsA(NULL, NULL, NULL, flags); + if (devinfo == INVALID_HANDLE_VALUE) + return; + + if (get_devinfo_data(devinfo, devinstance, &devdata)) + { + pSetupDiGetDeviceRegistryPropertyA(devinfo, &devdata, SPDRP_DEVICEDESC, + NULL, (PBYTE) name, namesize, NULL); + } /* if */ + + pSetupDiDestroyDeviceInfoList(devinfo); +} /* get_dev_name_by_instance */ + + +static void get_device_product_name(char *name, size_t namesize, char *devname) +{ + const char default_device_name[] = "Unidentified input device"; + + *name = '\0'; /* really insane default. */ + if (sizeof (default_device_name) >= namesize) + return; + + /* in case we can't stumble upon something better... */ + CopyMemory(name, default_device_name, sizeof (default_device_name)); + + /* okay, we're got the device instance. Now find the data for it. */ + get_dev_name_by_instance(devname, name, namesize); +} /* get_device_product_name */ + + +static void init_mouse(const RAWINPUTDEVICELIST *dev) +{ + const char rdp_ident[] = "ROOT\\RDP_MOU\\"; + MouseStruct *mouse = &mice[available_mice]; + char *buf = NULL; + char *ptr = NULL; + UINT ct = 0; + + if (dev->dwType != RIM_TYPEMOUSE) + return; /* keyboard or some other fruity thing. */ + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, NULL, &ct) < 0) + return; + + /* ct == is chars, not bytes, but we used the ASCII version. */ + buf = (char *) alloca(ct+1); + if (buf == NULL) + return; + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, buf, &ct) < 0) + return; + + buf[ct] = '\0'; /* make sure it's null-terminated. */ + + /* XP starts these strings with "\\??\\" ... Vista does "\\\\?\\". :/ */ + while ((*buf == '?') || (*buf == '\\')) + { + buf++; + ct--; + } /* while */ + + /* This string tap dancing gets us the device instance id. */ + for (ptr = buf; *ptr; ptr++) /* convert '#' to '\\' ... */ + { + char ch = *ptr; + if (ch == '#') + *ptr = '\\'; + else if (ch == '{') /* hit the GUID part of the string. */ + { + if (*(ptr-1) == '\\') + ptr--; + break; + } /* else if */ + } /* for */ + + *ptr = '\0'; + + make_string_upper(buf); + + /* + * Apparently there's a fake "RDP" device...I guess this is + * "Remote Desktop Protocol" for controlling the system pointer + * remotely via Windows Remote Desktop, but that's just a guess. + * At any rate, we don't want that device, so skip it if detected. + * + * Idea for this found here: + * http://link.mywwwserver.com/~jstookey/arcade/rawmouse/raw_mouse.c + */ + + /* avoiding memcmp here so we don't get a C runtime dependency... */ + if (ct >= sizeof (rdp_ident) - 1) + { + int i; + for (i = 0; i < sizeof (rdp_ident) - 1; i++) + { + if (buf[i] != rdp_ident[i]) + break; + } /* for */ + + if (i == sizeof (rdp_ident) - 1) + return; /* this is an RDP thing. Skip this device. */ + } /* if */ + + /* accept this mouse! */ + ZeroMemory(mouse, sizeof (MouseStruct)); + get_device_product_name(mouse->name, sizeof (mouse->name), buf); + mouse->handle = dev->hDevice; + available_mice++; +} /* init_mouse */ + + +static int windows_wminput_init(void) +{ + RAWINPUTDEVICELIST *devlist = NULL; + UINT ct = 0; + UINT i; + + available_mice = 0; + + if (!find_api_symbols()) /* only supported on WinXP and later. */ + return -1; + + pGetRawInputDeviceList(NULL, &ct, sizeof (RAWINPUTDEVICELIST)); + if (ct == 0) /* no devices. */ + return 0; + + devlist = (PRAWINPUTDEVICELIST) alloca(sizeof (RAWINPUTDEVICELIST) * ct); + pGetRawInputDeviceList(devlist, &ct, sizeof (RAWINPUTDEVICELIST)); + for (i = 0; i < ct; i++) + init_mouse(&devlist[i]); + + if (!init_event_queue()) + { + cleanup_window(); + available_mice = 0; + } /* if */ + + return available_mice; +} /* windows_wminput_init */ + + +static void windows_wminput_quit(void) +{ + /* unregister WM_INPUT devices... */ + RAWINPUTDEVICE rid; + ZeroMemory(&rid, sizeof (rid)); + rid.usUsagePage = 1; /* GenericDesktop page */ + rid.usUsage = 2; /* GeneralDestop Mouse usage. */ + rid.dwFlags |= RIDEV_REMOVE; + pRegisterRawInputDevices(&rid, 1, sizeof (rid)); + cleanup_window(); + available_mice = 0; + pDeleteCriticalSection(&mutex); +} /* windows_wminput_quit */ + + +static const char *windows_wminput_name(unsigned int index) +{ + return (index < available_mice) ? mice[index].name : NULL; +} /* windows_wminput_name */ + + +/* + * Windows doesn't send a WM_INPUT event when you unplug a mouse, + * so we try to do a basic query by device handle here; if the + * query fails, we assume the device has vanished and generate a + * disconnect. + */ +static int check_for_disconnects(ManyMouseEvent *ev) +{ + /* + * (i) is static so we iterate through all mice round-robin and check + * one mouse per call to ManyMouse_PollEvent(). This makes this test O(1). + */ + static unsigned int i = 0; + MouseStruct *mouse = NULL; + + if (++i >= available_mice) /* check first in case of redetect */ + i = 0; + + mouse = &mice[i]; + if (mouse->handle != NULL) /* not NULL == still plugged in. */ + { + UINT size = 0; + UINT rc = pGetRawInputDeviceInfoA(mouse->handle, RIDI_DEVICEINFO, + NULL, &size); + if (rc == (UINT) -1) /* failed...probably unplugged... */ + { + mouse->handle = NULL; + ev->type = MANYMOUSE_EVENT_DISCONNECT; + ev->device = i; + return 1; + } /* if */ + } /* if */ + + return 0; /* no disconnect event this time. */ +} /* check_for_disconnects */ + + +static int windows_wminput_poll(ManyMouseEvent *ev) +{ + MSG Msg; /* run the queue for WM_INPUT messages, etc ... */ + int found = 0; + + /* ...favor existing events in the queue... */ + pEnterCriticalSection(&mutex); + if (input_events_read != input_events_write) /* no events if equal. */ + { + CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + found = 1; + } /* if */ + pLeaveCriticalSection(&mutex); + + if (!found) + { + /* pump Windows for new hardware events... */ + while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) + { + pTranslateMessage(&Msg); + pDispatchMessageA(&Msg); + } /* while */ + + /* In case something new came in, give it to the app... */ + pEnterCriticalSection(&mutex); + if (input_events_read != input_events_write) /* no events if equal. */ + { + CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + found = 1; + } /* if */ + pLeaveCriticalSection(&mutex); + } /* if */ + + /* + * Check for disconnects if queue is totally empty and Windows didn't + * report anything new at this time. This ensures that we don't send a + * disconnect event through ManyMouse and then later give a valid + * event to the app for a device that is now missing. + */ + if (!found) + found = check_for_disconnects(ev); + + return found; +} /* windows_wminput_poll */ + +static const ManyMouseDriver ManyMouseDriver_interface = +{ + "Windows XP and later WM_INPUT interface", + windows_wminput_init, + windows_wminput_quit, + windows_wminput_name, + windows_wminput_poll +}; + +const ManyMouseDriver *ManyMouseDriver_windows = &ManyMouseDriver_interface; + +#else +const ManyMouseDriver *ManyMouseDriver_windows = 0; +#endif /* ifdef Windows blocker */ + +/* end of windows_wminput.c ... */ + diff --git a/manymouse/x11_xinput2.c b/manymouse/x11_xinput2.c new file mode 100644 index 000000000..3069aa170 --- /dev/null +++ b/manymouse/x11_xinput2.c @@ -0,0 +1,528 @@ +/* + * Support for the X11 XInput extension. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include "manymouse.h" + +/* Try to use this on everything but Windows and Mac OS by default... */ +#ifndef SUPPORT_XINPUT2 +#if ( (defined(_WIN32) || defined(__CYGWIN__)) ) +#define SUPPORT_XINPUT2 0 +#elif ( (defined(__MACH__)) && (defined(__APPLE__)) ) +#define SUPPORT_XINPUT2 0 +#else +#define SUPPORT_XINPUT2 1 +#endif +#endif + +#if SUPPORT_XINPUT2 + +#include +#include +#include +#include +#include + +/* 32 is good enough for now. */ +#define MAX_MICE 32 +#define MAX_AXIS 16 +typedef struct +{ + int device_id; + int connected; + int relative[MAX_AXIS]; + int minval[MAX_AXIS]; + int maxval[MAX_AXIS]; + char name[64]; +} MouseStruct; + +static MouseStruct mice[MAX_MICE]; +static unsigned int available_mice = 0; + +static Display *display = NULL; +static int xi2_opcode = 0; + + +/* !!! FIXME: this is cut-and-paste between a few targets now. Move it to + * !!! FIXME: manymouse.c ... + */ +/* + * Just trying to avoid malloc() here...we statically allocate a buffer + * for events and treat it as a ring buffer. + */ +/* !!! FIXME: tweak this? */ +#define MAX_EVENTS 1024 +static ManyMouseEvent input_events[MAX_EVENTS]; +static volatile int input_events_read = 0; +static volatile int input_events_write = 0; + +static void queue_event(const ManyMouseEvent *event) +{ + /* copy the event info. We'll process it in ManyMouse_PollEvent(). */ + memcpy(&input_events[input_events_write], event, sizeof (ManyMouseEvent)); + + input_events_write = ((input_events_write + 1) % MAX_EVENTS); + + /* Ring buffer full? Lose oldest event. */ + if (input_events_write == input_events_read) + { + /* !!! FIXME: we need to not lose mouse buttons here. */ + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + } /* if */ +} /* queue_event */ + + +static int dequeue_event(ManyMouseEvent *event) +{ + if (input_events_read != input_events_write) /* no events if equal. */ + { + memcpy(event, &input_events[input_events_read], sizeof (*event)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + return 1; + } /* if */ + return 0; /* no event. */ +} /* dequeue_event */ + + +/* + * You _probably_ have Xlib on your system if you're on a Unix box where you + * are planning to plug in multiple mice. That being said, we don't want + * to force a project to add Xlib to their builds, or force the end-user to + * have Xlib installed if they are otherwise running a console app that the + * evdev driver would handle. + * + * We load all Xlib symbols at runtime, and fail gracefully if they aren't + * available for some reason...ManyMouse might be able to use the evdev + * driver or at least return a zero. + * + * On Linux (and probably others), you'll need to add -ldl to your link line, + * but it's part of glibc, so this is pretty much going to be there. + */ + +static void *libx11 = NULL; +static void *libxext = NULL; +static void *libxi = NULL; + +typedef int (*XExtErrHandler)(Display *, _Xconst char *, _Xconst char *); + +static XExtErrHandler (*pXSetExtensionErrorHandler)(XExtErrHandler h) = 0; +static Display* (*pXOpenDisplay)(_Xconst char*) = 0; +static int (*pXCloseDisplay)(Display*) = 0; +static int (*pXISelectEvents)(Display*,Window,XIEventMask*,int) = 0; +static Bool (*pXQueryExtension)(Display*,_Xconst char*,int*,int*,int*) = 0; +static Status (*pXIQueryVersion)(Display*,int*,int*) = 0; +static XIDeviceInfo* (*pXIQueryDevice)(Display*,int,int*) = 0; +static void (*pXIFreeDeviceInfo)(XIDeviceInfo*) = 0; +static Bool (*pXGetEventData)(Display*,XGenericEventCookie*) = 0; +static void (*pXFreeEventData)(Display*,XGenericEventCookie*) = 0; +static int (*pXNextEvent)(Display*,XEvent*) = 0; +static int (*pXPending)(Display*) = 0; +static int (*pXFlush)(Display*) = 0; +static int (*pXEventsQueued)(Display*,int) = 0; + +static int symlookup(void *dll, void **addr, const char *sym) +{ + *addr = dlsym(dll, sym); + if (*addr == NULL) + return 0; + + return 1; +} /* symlookup */ + +static int find_api_symbols(void) +{ + void *dll = NULL; + + #define LOOKUP(x) { if (!symlookup(dll, (void **) &p##x, #x)) return 0; } + dll = libx11 = dlopen("libX11.so.6", RTLD_GLOBAL | RTLD_LAZY); + if (dll == NULL) + return 0; + + LOOKUP(XOpenDisplay); + LOOKUP(XCloseDisplay); + LOOKUP(XGetEventData); + LOOKUP(XFreeEventData); + LOOKUP(XQueryExtension); + LOOKUP(XNextEvent); + LOOKUP(XPending); + LOOKUP(XFlush); + LOOKUP(XEventsQueued); + + dll = libxext = dlopen("libXext.so.6", RTLD_GLOBAL | RTLD_LAZY); + if (dll == NULL) + return 0; + + LOOKUP(XSetExtensionErrorHandler); + + dll = libxi = dlopen("libXi.so.6", RTLD_GLOBAL | RTLD_LAZY); + if (dll == NULL) + return 0; + + LOOKUP(XISelectEvents); + LOOKUP(XIQueryVersion); + LOOKUP(XIQueryDevice); + LOOKUP(XIFreeDeviceInfo); + + #undef LOOKUP + + return 1; +} /* find_api_symbols */ + + +static void xinput2_cleanup(void) +{ + if (display != NULL) + { + pXCloseDisplay(display); + display = NULL; + } /* if */ + + memset(mice, '\0', sizeof (mice)); + available_mice = 0; + + #define LIBCLOSE(lib) { if (lib != NULL) { dlclose(lib); lib = NULL; } } + LIBCLOSE(libxi); + LIBCLOSE(libxext); + LIBCLOSE(libx11); + #undef LIBCLOSE + + memset(input_events, '\0', sizeof (input_events)); + input_events_read = input_events_write = 0; +} /* xinput2_cleanup */ + + +static int init_mouse(MouseStruct *mouse, const XIDeviceInfo *devinfo) +{ + XIAnyClassInfo **classes = devinfo->classes; + int axis = 0; + int i = 0; + + /* + * we only look at "slave" devices. "Master" pointers are the logical + * cursors, "slave" pointers are the hardware that back them. + * "Floating slaves" are hardware that don't back a cursor. + */ + + if ((devinfo->use != XISlavePointer) && (devinfo->use != XIFloatingSlave)) + return 0; /* not a device we care about. */ + else if (strstr(devinfo->name, "XTEST pointer") != NULL) + return 0; /* skip this nonsense. It's for the XTEST extension. */ + + mouse->device_id = devinfo->deviceid; + mouse->connected = 1; + + for (i = 0; i < devinfo->num_classes; i++) + { + if ((classes[i]->type == XIValuatorClass) && (axis < MAX_AXIS)) + { + const XIValuatorClassInfo *v = (XIValuatorClassInfo*) classes[i]; + mouse->relative[axis] = (v->mode == XIModeRelative); + mouse->minval[axis] = (int) v->min; + mouse->maxval[axis] = (int) v->max; + axis++; + } /* if */ + } /* for */ + + strncpy(mouse->name, devinfo->name, sizeof (mouse->name)); + mouse->name[sizeof (mouse->name) - 1] = '\0'; + return 1; +} /* init_mouse */ + + +static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL; +static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason) +{ + /* prevent Xlib spew to stderr for missing extensions. */ + return (strcmp(reason, "missing") == 0) ? 0 : Xext_handler(d, ext, reason); +} /* xext_errhandler */ + + +static int register_for_events(Display *dpy) +{ + XIEventMask evmask; + unsigned char mask[3] = { 0, 0, 0 }; + + XISetMask(mask, XI_HierarchyChanged); + XISetMask(mask, XI_RawMotion); + XISetMask(mask, XI_RawButtonPress); + XISetMask(mask, XI_RawButtonRelease); + + evmask.deviceid = XIAllDevices; + evmask.mask_len = sizeof (mask); + evmask.mask = mask; + + /* !!! FIXME: retval? */ + pXISelectEvents(dpy, DefaultRootWindow(dpy), &evmask, 1); + return 1; +} /* register_for_events */ + + +static int x11_xinput2_init_internal(void) +{ + const char *ext = "XInputExtension"; + XIDeviceInfo *device_list = NULL; + int device_count = 0; + int available = 0; + int event = 0; + int error = 0; + int major = 2; + int minor = 0; + int i = 0; + + xinput2_cleanup(); /* just in case... */ + + if (getenv("MANYMOUSE_NO_XINPUT2") != NULL) + return -1; + + if (!find_api_symbols()) + return -1; /* couldn't find all needed symbols. */ + + display = pXOpenDisplay(NULL); + if (display == NULL) + return -1; /* no X server at all */ + + Xext_handler = pXSetExtensionErrorHandler(xext_errhandler); + available = (pXQueryExtension(display, ext, &xi2_opcode, &event, &error) && + (pXIQueryVersion(display, &major, &minor) != BadRequest)); + pXSetExtensionErrorHandler(Xext_handler); + Xext_handler = NULL; + + if (!available) + return -1; /* no XInput2 support. */ + + /* + * Register for events first, to prevent a race where we unplug a + * device between when we queried for the list and when we start + * listening for changes. + */ + if (!register_for_events(display)) + return -1; + + device_list = pXIQueryDevice(display, XIAllDevices, &device_count); + for (i = 0; i < device_count; i++) + { + MouseStruct *mouse = &mice[available_mice]; + if (init_mouse(mouse, &device_list[i])) + available_mice++; + } /* for */ + pXIFreeDeviceInfo(device_list); + + return available_mice; +} /* x11_xinput2_init_internal */ + + +static int x11_xinput2_init(void) +{ + int retval = x11_xinput2_init_internal(); + if (retval < 0) + xinput2_cleanup(); + return retval; +} /* x11_xinput2_init */ + + +static void x11_xinput2_quit(void) +{ + xinput2_cleanup(); +} /* x11_xinput2_quit */ + + +static const char *x11_xinput2_name(unsigned int index) +{ + return (index < available_mice) ? mice[index].name : NULL; +} /* x11_xinput2_name */ + + +static int find_mouse_by_devid(const int devid) +{ + int i; + const MouseStruct *mouse = mice; + + for (i = 0; i < available_mice; i++, mouse++) + { + if (mouse->device_id == devid) + return (mouse->connected) ? i : -1; + } /* for */ + + return -1; +} /* find_mouse_by_devid */ + + +static int get_next_x11_event(XEvent *xev) +{ + int available = 0; + + pXFlush(display); + if (pXEventsQueued(display, QueuedAlready)) + available = 1; + else + { + /* XPending() blocks if there's no data, so select() first. */ + struct timeval nowait; + const int fd = ConnectionNumber(display); + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + memset(&nowait, '\0', sizeof (nowait)); + if (select(fd+1, &fdset, NULL, NULL, &nowait) == 1) + available = pXPending(display); + } /* else */ + + if (available) + { + memset(xev, '\0', sizeof (*xev)); + pXNextEvent(display, xev); + return 1; + } /* if */ + + return 0; +} /* get_next_x11_event */ + + +static void pump_events(void) +{ + ManyMouseEvent event; + const int opcode = xi2_opcode; + const XIRawEvent *rawev = NULL; + const XIHierarchyEvent *hierev = NULL; + int mouse = 0; + XEvent xev; + int i = 0; + + while (get_next_x11_event(&xev)) + { + /* All XI2 events are "cookie" events...which need extra tapdance. */ + if (xev.xcookie.type != GenericEvent) + continue; + else if (xev.xcookie.extension != opcode) + continue; + else if (!pXGetEventData(display, &xev.xcookie)) + continue; + + switch (xev.xcookie.evtype) + { + case XI_RawMotion: + rawev = (const XIRawEvent *) xev.xcookie.data; + mouse = find_mouse_by_devid(rawev->deviceid); + if (mouse != -1) + { + const double *values = rawev->raw_values; + int top = rawev->valuators.mask_len * 8; + if (top > MAX_AXIS) + top = MAX_AXIS; + + for (i = 0; i < top; i++) + { + if (XIMaskIsSet(rawev->valuators.mask, i)) + { + const int value = (int) *values; + if (mice[mouse].relative[i]) + event.type = MANYMOUSE_EVENT_RELMOTION; + else + event.type = MANYMOUSE_EVENT_ABSMOTION; + event.device = mouse; + event.item = i; + event.value = value; + event.minval = mice[mouse].minval[i]; + event.maxval = mice[mouse].maxval[i]; + if ((!mice[mouse].relative[i]) || (value)) + queue_event(&event); + values++; + } /* if */ + } /* for */ + } /* if */ + break; + + case XI_RawButtonPress: + case XI_RawButtonRelease: + rawev = (const XIRawEvent *) xev.xcookie.data; + mouse = find_mouse_by_devid(rawev->deviceid); + if (mouse != -1) + { + const int button = rawev->detail; + const int pressed = (xev.xcookie.evtype==XI_RawButtonPress); + + /* gah, XInput2 still maps the wheel to buttons. */ + if ((button >= 4) && (button <= 7)) + { + if (pressed) /* ignore "up" for these "buttons" */ + { + event.type = MANYMOUSE_EVENT_SCROLL; + event.device = mouse; + + if ((button == 4) || (button == 5)) + event.item = 0; + else + event.item = 1; + + if ((button == 4) || (button == 6)) + event.value = 1; + else + event.value = -1; + + queue_event(&event); + } /* if */ + } /* if */ + else + { + event.type = MANYMOUSE_EVENT_BUTTON; + event.device = mouse; + event.item = button-1; + event.value = pressed; + queue_event(&event); + } /* else */ + } /* if */ + break; + + case XI_HierarchyChanged: + hierev = (const XIHierarchyEvent *) xev.xcookie.data; + for (i = 0; i < hierev->num_info; i++) + { + if (hierev->info[i].flags & XISlaveRemoved) + { + mouse = find_mouse_by_devid(hierev->info[i].deviceid); + if (mouse != -1) + { + mice[mouse].connected = 0; + event.type = MANYMOUSE_EVENT_DISCONNECT; + event.device = mouse; + queue_event(&event); + } /* if */ + } /* if */ + } /* for */ + break; + } /* switch */ + + pXFreeEventData(display, &xev.xcookie); + } /* while */ +} /* pump_events */ + +static int x11_xinput2_poll(ManyMouseEvent *event) +{ + if (dequeue_event(event)) /* ...favor existing events in the queue... */ + return 1; + + pump_events(); /* pump runloop for new hardware events... */ + return dequeue_event(event); /* see if anything had shown up... */ +} /* x11_xinput2_poll */ + +static const ManyMouseDriver ManyMouseDriver_interface = +{ + "X11 XInput2 extension", + x11_xinput2_init, + x11_xinput2_quit, + x11_xinput2_name, + x11_xinput2_poll +}; + +const ManyMouseDriver *ManyMouseDriver_xinput2 = &ManyMouseDriver_interface; + +#else +const ManyMouseDriver *ManyMouseDriver_xinput2 = 0; +#endif /* SUPPORT_XINPUT2 blocker */ + +/* end of x11_xinput2.c ... */ + diff --git a/resource/resource.h b/resource/resource.h new file mode 100644 index 000000000..ed19ed12d --- /dev/null +++ b/resource/resource.h @@ -0,0 +1,5 @@ +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +#define IDI_ICON3 103 diff --git a/resource/singe.ico b/resource/singe.ico new file mode 100644 index 000000000..98fc0b4cd Binary files /dev/null and b/resource/singe.ico differ diff --git a/resource/singe.rc b/resource/singe.rc new file mode 100644 index 000000000..956b777f1 --- /dev/null +++ b/resource/singe.rc @@ -0,0 +1,51 @@ +// Generated by ResEdit 1.5.4 +// Copyright (C) 2006-2010 +// http://www.resedit.net + +#include +#include +#include +#include "resource.h" + + + + +// +// Icon resources +// +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +IDI_ICON3 ICON "singe.ico" + + + +// +// Version Information resources +// +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,1,0,7 + PRODUCTVERSION 0,1,0,7 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN + FILEFLAGSMASK 0x00000017 + FILEFLAGS 0x00000002 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904b0" + { + VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine" + VALUE "FileVersion", "0, 1, 0, 7" + VALUE "InternalName", "daphne" + VALUE "LegalCopyright", "Scott Duensing. Based on work by Matt Ownby." + VALUE "OriginalFilename", "singe.exe" + VALUE "ProductName", "Singe Application" + VALUE "ProductVersion", "1.18" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04B0 + } +} diff --git a/singe_changelog.txt b/singe_changelog.txt new file mode 100644 index 000000000..174cb031d --- /dev/null +++ b/singe_changelog.txt @@ -0,0 +1,165 @@ +========================================= +Singe Changelog +========================================= + +v1.18 - Mice Update: Added support for multiple mice. Singe can now track + up to ^_^ mice (but why would you want that many?). Keep in mind there + is a performance hit when tracking multiple cursors. + For the programming oriented, function OnMouseMoved gains + an additional parameter, like this: + + OnMouseMoved(intX, intY, relX, relY, mouseID) + + Singe will return an integer value called mouseID. Use this + to keep track of your mice. + + + - Added parameter "-nomouse". Disables mouse from the command line + + - Alpha blending issue fixed. + + - Fixed bug crash related to sounds still playing during shutdown. + + - New Singe Functions + + // mouseSetMode() Enables/Disable multiple mice. + // e.g. lua code, + // + // mouseSetMode(MANY_MOUSE) + // mouseSetMode(SINGLE_MOUSE) + // + // Where those constant values are as follows: + // + // SINGLE_MOUSE = 100 + // MANY_MOUSE = 200 + // + // Note: SINGLE_MOUSE is the default mode. + // Only call this function to read multiple mice. + + // mouseDisable() Disable mouse from within lua code. + // e.g. lua code, + // + // mouseDisable() + // + // + + // mouseEnable() Enables mouse from within lua code. + // e.g. lua code, + // + // mouseEnable() + // + // + + // mouseHowMany() Returns the number of mice attached to + // the computer. For use with multiple mice situations only. + // NOTES: If "-single_mouse" command line switch + // was used to launch Singe, then return value will be -1. + // + // e.g. lua code, + // + // local intMiceDetected = mouseHowMany() + // + // + + // discPauseAtFrame() - Skips video to a given frame and stays there (pauses playback). + // e.g. lua code, + // + // discPauseAtFrame(3494) + + // singeDisablePauseKey() - Disables the pause key (usually letter "P" on the keyboard.) + // e.g. lua code, + // + // singeDisablePauseKey() + // + // Use this when you don't want players pausing your game. + // Specially useful for situations where letting the player pause the game + // may potentially mess up your singe program, a pause menu, a time sensitive range, etc. + // + +v1.17 - Large File Support - Singe can now read mpegs over 2GBs in size. + + + Matt's YUV mod applied to version 1.2.14 of the SDL library. + +v1.16 - Sound support update: New functions for more robust sound handling. + + soundPause() + soundResume() + soundIsPlaying() + soundGetVolume/soundSetVolume() + soundFullStop() + + // soundPause() Pauses a sample currently playing + // in the sound queue. + // User must feed the sound handle on the lua side. + // e.g. lua code, + // + // thisHandle = soundPlay(thisSound) + // soundPause(thisHandle) + // + // Function returns an integer value ranging from 0 to 63. + + // soundResume() Instructs Daphne to resume playback + // of a previously paused sound. + // User must feed the sound handle on the lua side. + // e.g. lua code, + // + // thisHandle = soundPlay(mySound) + // soundPause(thisHandle) + // soundResume(thisHandle) + // + // Function returns true if sample was unpaused, false otherwise. + + // soundIsPlaying() Checks to see if a certain sound has finished playing. + // User must feed the sound handle on the lua side. + // e.g. lua code, + // + // thisHandle = soundPlay(mySound) + // if (soundIsPlaying(thisSound)) then do something ... end + // + // Function returns true if sample is still playing, false otherwise. + // + + // soundGetVolume/soundSetVolume() Allows manipulation of sample volume. + // Valid values range from 0 to 63 + // e.g. lua code, + // + // soundSetVolume(32) + // + // Function returns nothing. + // + + // soundFullStop() Clears the audio queue of any samples actively playing. + // No parameters needed. Function returns nothing. + // e.g. lua code, + // + // soundFullStop() + // + +v1.15 - As of version 1.15 Singe is officially a fork of Daphne. It only runs singe games. + + + Command Line has been greatly simplified. To run a Singe game type: + + singe.exe c:\path.to.my.script\somegame.singe + + Singe will assume the framefile will be "somegame.txt". If your framefile has + a different name, then use the -framefile parameter as you would in Daphne. + + + Additional functions: + + singeGetScriptPath() + singeSetGameName() + + // singeGetScriptPath() Returns the path to the singe script. + // e.g. lua code, + // + // sGameDirectory = singeGetScriptPath() + // + + // singeSetGameName() Adds the name of the singe game to the window's title bar. + // Valid value is a string no longer than 25 characters. + // e.g. lua code, + // + // singeSetGameName("My FMV game") + // + // Function returns nothing. + diff --git a/singe_vs2008.ncb b/singe_vs2008.ncb new file mode 100644 index 000000000..0fdba3b14 Binary files /dev/null and b/singe_vs2008.ncb differ diff --git a/singe_vs2008.sln b/singe_vs2008.sln new file mode 100644 index 000000000..c1fd486a1 --- /dev/null +++ b/singe_vs2008.sln @@ -0,0 +1,35 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daphne", "daphne_vs2008.vcproj", "{D6F69305-8810-439B-A6E1-554175951DE3}" + ProjectSection(ProjectDependencies) = postProject + {7F8CEA42-F687-4755-BD58-54A6B25659A7} = {7F8CEA42-F687-4755-BD58-54A6B25659A7} + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0} = {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vldp2", "vldp2_vs2008.vcproj", "{9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "singe", "game\singe\singe_vs2008.vcproj", "{7F8CEA42-F687-4755-BD58-54A6B25659A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6F69305-8810-439B-A6E1-554175951DE3}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Debug|Win32.Build.0 = Debug|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Release|Win32.ActiveCfg = Release|Win32 + {D6F69305-8810-439B-A6E1-554175951DE3}.Release|Win32.Build.0 = Release|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Debug|Win32.Build.0 = Debug|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Release|Win32.ActiveCfg = Release|Win32 + {9F8120A6-B6C8-4CBF-9D9B-45AF83F61EA0}.Release|Win32.Build.0 = Release|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Debug|Win32.ActiveCfg = Debug|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Debug|Win32.Build.0 = Debug|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Release|Win32.ActiveCfg = Release|Win32 + {7F8CEA42-F687-4755-BD58-54A6B25659A7}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/singe_vs2008.suo b/singe_vs2008.suo new file mode 100644 index 000000000..604322438 Binary files /dev/null and b/singe_vs2008.suo differ diff --git a/sound/Makefile b/sound/Makefile new file mode 100644 index 000000000..a5b7f2aec --- /dev/null +++ b/sound/Makefile @@ -0,0 +1,27 @@ +# sub Makefile for SOUND folder + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = sound.o samples.o mix.o + +.SUFFIXES: .cpp + +all: ${OBJS} mix_mmx-asm + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +# MMX audio mixing function (conditional upon whether USE_MMX is defined) +mix_mmx-asm: mix_mmx-gas.s +ifeq ($(USE_MMX),1) + as mix_mmx-gas.s -o mix_mmx-gas.o +endif + +clean: + rm -f ${OBJS} *.d + diff --git a/sound/mix.cpp b/sound/mix.cpp new file mode 100644 index 000000000..c21cdb17f --- /dev/null +++ b/sound/mix.cpp @@ -0,0 +1,87 @@ +/* + * mix.cpp + * + * Copyright (C) 2007 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// mix.cpp + +#include "sound.h" +#include "../io/mpo_mem.h" +#include "mix.h" + +#ifdef DEBUG +#include +#endif + +// if we aren't using the MMX version + +#ifndef USE_MMX +struct mix_s *g_pMixBufs = NULL; +Uint8 *g_pSampleDst = 0; +unsigned int g_uBytesToMix = 0; +#endif + +// A C version of mix_mmx +// mix_mmx is 2.5 times as fast on Pentium 4 +// NOTE : we always want this defined, even when using MMX, for the purpose of testing (see releasetest) +void mix_c() +{ + unsigned int uSamplesToMix = g_uBytesToMix >> 1; + Uint8 *stream = g_pSampleDst; + unsigned int sample = 0, val_to_store = 0; + + for (sample = 0; sample < uSamplesToMix; sample += 2) + { + int mixed_sample_1 = 0, mixed_sample_2 = 0; // left/right channels + struct mix_s *cur = g_pMixBufs; + + // mix all sound chips + while (cur) + { + mixed_sample_1 += LOAD_LIL_SINT16(((short *) cur->pMixBuf) + sample); + mixed_sample_2 += LOAD_LIL_SINT16(((short *) cur->pMixBuf) + sample + 1); + cur = cur->pNext; + } + + DO_CLIP(mixed_sample_1); + DO_CLIP(mixed_sample_2); + + // note: sample2 needs to be on top because this is little endian, hence LSB + val_to_store = + (((unsigned short) mixed_sample_2) << 16) | ((unsigned short) mixed_sample_1); + + STORE_LIL_UINT32(stream, val_to_store); + stream += 4; + } +} + +#ifdef USE_MMX + +#ifdef DEBUG +// debug version of mix MMX that does safety checking before the call. This obviously won't be used +// during release builds. +void debug_mix_mmx() +{ + assert(((g_uBytesToMix % 8) == 0) && (g_uBytesToMix >= 8)); // mix MMX does 8 bytes at a time + mix_mmx(); +} +#endif // DEBUG + +#endif // NATIVE_CPU_X86 diff --git a/sound/mix.h b/sound/mix.h new file mode 100644 index 000000000..96027b910 --- /dev/null +++ b/sound/mix.h @@ -0,0 +1,98 @@ +/* + * mix.h + * + * Copyright (C) 2007 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// mix.h + +#ifndef MIX_H +#define MIX_H + +#ifdef MAC_OSX +#include "mmxdefs.h" +#endif + +#include // for datatype defs + +// IMPORTANT: the MMX code depends on this structure beginning as it is displayed here! +// Be very cautious about changing this struct! +struct mix_s +{ + void *pMixBuf; + struct mix_s *pNext; +}; + +// TO USE THE MIX FUNCTIONS: +// 1 - set g_pMixBufs to a pointer to a populated mix_s struct (that contains all your streams) +// 2 - set g_pSampleDst to the destination stream +// 3 - set g_uBytesToMix to how many bytes long all lines are (they all must be the same length). +// IMPORTANT : g_uBytesToMix must be a multiple of 8, and must be >= 8! +// 4 - run g_mix_func() and you're done! + +// we always want this function defined for the purpose of testing (releasetest.cpp) +void mix_c(); + +// Here we make some definitions so that the MMX/C code use identical syntax and variables +#ifdef USE_MMX + +// For some reason, OSX was being retarded and insisted on putting _'s in front of all +// assembly language variables. So we've compensated for this insane behavior. + +#if defined(MAC_OSX) || defined(WIN32) +extern "C" void mix_mmx(); +extern "C" mix_s *asm_pMixBufs; +extern "C" Uint8 *asm_pSampleDst; +extern "C" Uint32 asm_uBytesToMix; +#define g_pMixBufs asm_pMixBufs +#define g_pSampleDst asm_pSampleDst +#define g_uBytesToMix asm_uBytesToMix +#else +extern "C" void _mix_mmx(); +extern "C" mix_s *_asm_pMixBufs; +extern "C" Uint8 *_asm_pSampleDst; +extern "C" Uint32 _asm_uBytesToMix; +#define g_pMixBufs _asm_pMixBufs +#define g_pSampleDst _asm_pSampleDst +#define g_uBytesToMix _asm_uBytesToMix +#define mix_mmx _mix_mmx +#endif // MAC_OSX + +// debug version gets some extra (slower) error checking +#ifdef DEBUG +#define g_mix_func debug_mix_mmx +void debug_mix_mmx(); +#else +// here is the fast release version +#define g_mix_func mix_mmx +#endif + +#else + +// here is where we go if we're not using MMX + +extern mix_s *g_pMixBufs; +extern Uint8 *g_pSampleDst; +extern Uint32 g_uBytesToMix; +#define g_mix_func mix_c +#endif // USE_MMX + +///////////////////////////// + +#endif diff --git a/sound/mix_mmx-gas.s b/sound/mix_mmx-gas.s new file mode 100644 index 000000000..cdf478e86 --- /dev/null +++ b/sound/mix_mmx-gas.s @@ -0,0 +1,79 @@ +# MMX 16-bit signed audio MIX function +# by Matt Ownby - May 7th, 2007 +# For GNU Assembler + +.data + +.globl _asm_pSampleDst +_asm_pSampleDst: + .space 8 + +.globl _asm_pMixBufs +_asm_pMixBufs: + .space 4 + +.globl _asm_uBytesToMix +_asm_uBytesToMix: + .space 4 + +#################################### + +.text + +.globl _mix_mmx +_mix_mmx: + + push %ebp # needs to be preserved + push %esi # points to sample2 + push %ebx # # of iterations we are to do + push %ecx # # of iterations we have done + push %edx # points to sample1 + # eax points to the destination buffer, but eax doesn't need to be preserved because + # it is assumed to hold the return value + + #################### + + movl _asm_uBytesToMix, %ebx + xorl %ecx, %ecx # ecx = 0 + movl _asm_pSampleDst, %eax + +MainLoop: + # NOTE : for optimization purposes, we assume that asm_pMixBufs is never NULL + movl _asm_pMixBufs, %edx + + pxor %mm0, %mm0 ; mm0 = 0 + +MoreStreams: + # get pMixBuf + mov (%edx), %esi + + # edx = edx->next pointer + mov 4(%edx), %edx + + # add bytes together with each other, 16-bit signed with 'saturation' (clipping) + paddsw (%esi,%ecx), %mm0 + + # is edx 0? + test $-1, %edx + jnz MoreStreams + + movq %mm0, (%eax, %ecx) # store final result back to system memory + + add $8, %ecx # advance index over the 8 bytes we've just handled + cmp %ebx, %ecx # is our current index less than the total iterations ? + + jl MainLoop # if we have more iterations to do, then loop + + ##################### + + emms + + pop %edx + pop %ecx + pop %ebx + pop %esi + pop %ebp + + ret + +#################################################### diff --git a/sound/mix_mmx-masm.asm b/sound/mix_mmx-masm.asm new file mode 100644 index 000000000..75f50c2a8 --- /dev/null +++ b/sound/mix_mmx-masm.asm @@ -0,0 +1,96 @@ +; MMX MIX function +; by Matt Ownby +; For MASM (Microschlop) only + +.486 +.MMX + +.model flat, c + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.DATA + +ALIGN 8 + +PUBLIC asm_pSampleDst +asm_pSampleDst dq 0 + +; This is a pointer to a struct that _must_ start like this: +; struct mix_s { +; void *ptrStream; +; struct mix_s *ptrNext; +; ... +; }; +; So it's sort of a linked list struct that this ASM code will iterate through to do mixing. +; The last stream should have ptrNext set to NULL. +PUBLIC asm_pMixBufs +asm_pMixBufs dd 0 + +PUBLIC asm_uBytesToMix +asm_uBytesToMix dd 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.CODE + +PUBLIC mix_mmx +mix_mmx PROC NEAR + + push ebp ; needs to be preserved + push esi ; points to asm_pMixBufs->pMixBuf + push ebx ; # of iterations we are to do + push ecx ; # of iterations we have done + push edx ; points to asm_pMixBufs + ; eax points to asm_pSampleDst, but eax doesn't need to be preserved because + ; it is assumed to hold the return value + + ;;;;;;;;;;;;;;;;;;;; + + mov ebx, asm_uBytesToMix + xor ecx, ecx + mov eax, dword ptr[asm_pSampleDst] + +MainLoop: + ; NOTE : for optimization purposes, we assume that asm_pMixBufs is never NULL + mov edx, dword ptr[asm_pMixBufs] + + pxor mm0, mm0 ; mm0 = 0 + +MoreStreams: + ; get pMixBuf + mov esi, [edx] + + ; edx = edx->next pointer + mov edx, dword ptr[edx+4] + + ; is this faster? + paddsw mm0, [esi+ecx] + + test edx, -1 + ; if we have another stream to mix, then loop + jnz MoreStreams + + movq [eax+ecx], mm0 ; store final result back to system memory + + add ecx, 8 ; advance index over the 8 bytes we've just handled + cmp ecx, ebx ; is our current index less than the total iterations ? + + jl MainLoop ; if we have more iterations to do, then loop + + ;;;;;;;;;;;;;;;;;;;;; + + emms + + pop edx + pop ecx + pop ebx + pop esi + pop ebp + + ret +mix_mmx ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +END diff --git a/sound/samples.cpp b/sound/samples.cpp new file mode 100644 index 000000000..2b0ec448c --- /dev/null +++ b/sound/samples.cpp @@ -0,0 +1,346 @@ +// samples.cpp + +#include "../game/game.h" // to get sound names +#include "../io/conout.h" +#include "../io/mpo_mem.h" // for endian-independent macros +#include // for memset +#include "samples.h" + +#ifdef DEBUG +#include +#endif + +#include +using namespace std; + +struct sample_data_s +{ + // holds audio buffer + Uint8 *pu8Buf; + + // holds audio length + Uint32 uLength; + + // how many channels (1=mono, 2=stereo) this sample has + unsigned int uChannels; + + // position of sample if playing + unsigned int uPos; + + // whether this dynamic sample is active (playing) or not + bool bActive; + + // activate this flag to make a sample end early + bool bEndEarly; + + // if this is not NULL, it will get called when the sample has finished playing + void (*finishedCallback)(Uint8 *pu8Buf, unsigned int uSampleIdx); +}; + +// temporary holding struct so that main thread can issue callbacks instead of the audio thread +struct sample_callback_s +{ + void (*finishedCallback)(Uint8 *pu8Buf, unsigned int uSampleIdx); + Uint8 *pu8Buf; + unsigned int uSampleIdx; +}; + +// MUST BE PROTECTED BY MUTEX! +queue g_qCallbacks; + +// this number can be any size, but there's no reason to make it huge +const unsigned int MAX_DYNAMIC_SAMPLES = 32; // Raised from 8 by RDG2010 + +struct sample_data_s g_SampleStates[MAX_DYNAMIC_SAMPLES]; + +// so that we don't need to scan through to find a free slot in the dynamic samples array +unsigned int g_uNextSampleIdx = 0; + +// init callback +int samples_init(unsigned int unused) +{ + int iResult = 0; + unsigned int u = 0; + + // make sure these are all initialized + for (u = 0; u < MAX_DYNAMIC_SAMPLES; ++u) + { + sample_data_s *s = &g_SampleStates[u]; + s->pu8Buf = NULL; + s->uLength = 0; + s->uPos = 0; + s->uChannels = 0; + s->bActive = false; + s->finishedCallback = NULL; + } + + return iResult; +} + +void samples_shutdown(int unused) +{ +} + +// called from sound mixer to get audio stream +// NOTE : This runs on the audio thread!!! +void samples_get_stream(Uint8 *stream, int length, int unused) +{ +#ifdef DEBUG + assert (length % 4 == 0); // make sure it's divisible by 4 +#endif + + // (each sample is 4 bytes, which is why we divide length by 4) + unsigned int uTotalSamples = length >> 2; + + // clear buffer so that our addition will work + memset(stream, 0, length); + + unsigned int u = 0; + + // check to see if any sample is playing ... + for (u = 0; u < MAX_DYNAMIC_SAMPLES; ++u) + { + sample_data_s *data = &g_SampleStates[u]; + + if (data->bActive) + { + Uint8 *ptrStream = stream; + + // do each sample + for (unsigned int uSample = 0; uSample < uTotalSamples; ++uSample) + { + if (data->bEndEarly) data->uPos = data->uLength; // Jumps the pointer to the end of the sample so that it ends immediately. + + // if there is still some sample data to be mixed to this stream + if (data->uPos < data->uLength) + { + int iMixedSample1 = LOAD_LIL_SINT16((Sint16 *) ptrStream); + int iMixedSample2 = LOAD_LIL_SINT16(((Sint16 *) ptrStream) + 1); + + Sint16 i16Sample1 = LOAD_LIL_SINT16(data->pu8Buf + data->uPos); + iMixedSample1 += i16Sample1; + data->uPos += 2; + + // if this is a stereo sample + if (data->uChannels == 2) + { + iMixedSample2 += LOAD_LIL_SINT16(data->pu8Buf + data->uPos); + data->uPos += 2; + } + // else this is a mono sample, so just duplicate the last sample we read in + else + { + iMixedSample2 += i16Sample1; + } + + DO_CLIP(iMixedSample1); // prevent overflow + DO_CLIP(iMixedSample2); + + // yes, sample2 should be the most significant, sample1 least significant.. releasetest tests this + unsigned int val_to_store = (((Uint16) iMixedSample2) << 16) | (Uint16) iMixedSample1; + STORE_LIL_UINT32(ptrStream, val_to_store); + ptrStream += 4; + } + // else this sample is done, so get rid of the entry ... + else + { + data->bActive = false; + + // if caller has requested to be notified when this sample is done ... + if (data->finishedCallback != NULL) + { + sample_callback_s cb; + cb.finishedCallback = data->finishedCallback; + cb.pu8Buf = data->pu8Buf; + cb.uSampleIdx = u; + + // NOTE : I am _assuming_ the SDL_LockAudio has already been called which is why I don't do it here. + // The callback needs to be queued up so that the main thread can issue it (the audio thread can't issue it without causing instability) + g_qCallbacks.push(cb); + } + break; + } + } // end going through stream buffer + } // end while we have states to be addressed + } // end looping through all sample slots +} + +int samples_play_sample(Uint8 *pu8Buf, unsigned int uLength, unsigned int uChannels, int iSlot, + void (*finishedCallback)(Uint8 *pu8Buf, unsigned int uSlot)) +{ + int iResult = -1; + sample_data_s *state = NULL; + + // range check + if ((uChannels == 1) || (uChannels == 2)) + { + // about to access shared variables + SDL_LockAudio(); + + // if we should automatically find a free slot + if (iSlot < 0) + { + unsigned int uStartIdx = g_uNextSampleIdx; // this value will always be incremented one call behind... + + while (state == NULL) + { + state = &g_SampleStates[g_uNextSampleIdx]; + iResult = g_uNextSampleIdx; // assume this slot is ok until proven otherwise + + // if this sample is currently active, we can't use it, and must move on ... + if (state->bActive) + { + state = NULL; + } + + ++g_uNextSampleIdx; // increment slot value for the next call to this funciton... + + // wraparound + if (g_uNextSampleIdx >= MAX_DYNAMIC_SAMPLES) + { + g_uNextSampleIdx = 0; + } + + // If we've come full circle, break out of the loop and see if we found + // an available slot + if (g_uNextSampleIdx == uStartIdx) + { + break; + } + } + + // if state is NULL, it means that there are no available slots + if (!state) + { + iResult = -2; + } + } + // else if iSlot is in range, use it ... + else if ((unsigned int) iSlot < MAX_DYNAMIC_SAMPLES) + { + state = &g_SampleStates[iSlot]; + iResult = iSlot; + } + // else iSlot is out of range ... + + // if we found a state that we can modify + if (state != NULL) + { + state->bActive = true; + state->bEndEarly = false; + state->pu8Buf = pu8Buf; + state->uLength = uLength; + state->uChannels = uChannels; + state->uPos = 0; + state->finishedCallback = finishedCallback; + } + // else there's an error so do nothing ... + + SDL_UnlockAudio(); + + } // end if channels are ok + // else channels are out of range + + return iResult; +} + +bool samples_is_sample_playing(unsigned int uSlot) +{ + bool bResult = false; + if (uSlot < MAX_DYNAMIC_SAMPLES) + { + // about to access shared variables + SDL_LockAudio(); + bResult = g_SampleStates[uSlot].bActive; + SDL_UnlockAudio(); + } + else + { + //printline("SINGE: samples_is_sample_playing() was called with an out-of-range parameter"); + } + return bResult; +} + +bool samples_set_state(unsigned int uSlot, bool thisState) +{ + // This functions pauses or resumes a sample + // by manipulating bActive in sample_data_s struct. + bool bResult = false; + if (uSlot < MAX_DYNAMIC_SAMPLES) + { + // about to access shared variables + SDL_LockAudio(); + g_SampleStates[uSlot].bActive = thisState; + SDL_UnlockAudio(); + bResult = true; + } + else + { + printline("ERROR: samples_set_state() was called with an out-of-range parameter"); + } + return bResult; + +} + +bool samples_end_early(unsigned int uSlot) +{ + // This function stops a sample from playing + // by manipulating bEndEarly in sample_data_s struct. + // Turning this boolean on will make the sample end early. + bool bResult = false; + if (uSlot < MAX_DYNAMIC_SAMPLES) + { + // about to access shared variables + SDL_LockAudio(); + g_SampleStates[uSlot].bEndEarly = true; + //g_SampleStates[uSlot].bActive = false; + SDL_UnlockAudio(); + bResult = true; + } + else + { + printline("ERROR: samples_end_early() was called with an out-of-range parameter"); + } + return bResult; + +} + +void samples_flush_queue() +{ + // This function stops ALL active samples from playing + // by manipulating bEndEarly in sample_data_s struct. + // Turning this boolean on will make the sample end early. + for (unsigned int uSlot = 0; uSlot < MAX_DYNAMIC_SAMPLES; ++uSlot) + { + + sample_data_s *data = &g_SampleStates[uSlot]; + if (data->bActive) + { + // about to access shared variables + SDL_LockAudio(); + g_SampleStates[uSlot].bEndEarly = true; + SDL_UnlockAudio(); + } + } + +} + +void samples_do_queued_callbacks() +{ + // about to access shared variables + SDL_LockAudio(); + + // do all the callbacks that are queued up + while (!g_qCallbacks.empty()) + { + sample_callback_s cb = g_qCallbacks.front(); + + // call the callback here + cb.finishedCallback(cb.pu8Buf, cb.uSampleIdx); + + // remove this item from the queue + g_qCallbacks.pop(); + } + + SDL_UnlockAudio(); +} diff --git a/sound/samples.h b/sound/samples.h new file mode 100644 index 000000000..9c2ddc641 --- /dev/null +++ b/sound/samples.h @@ -0,0 +1,61 @@ +/* + * samples.h + * + * Copyright (C) 2006 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SAMPLES_H +#define SAMPLES_H + +#include // for data-type defs + +// init callback +int samples_init(unsigned int unused); + +// shutdown +void samples_shutdown(int shutdown); + +// called from sound mixer to get audio stream +void samples_get_stream(Uint8 *stream, int length, int internal_id); + +// Plays a sample +// The sample's audio specs must match our the audio device's specs +// 'uLength' is how long the sample is IN BYTES (so 4-bytes = 1 sample for 16-bit stereo) +// 'uChannels' is how many channels the sample has (must be 1 for mono or 2 for stereo) +// 'iSlot' specifies which slot to play the sample in, or -1 to just pick the next available one +// Returns the slot that the sample is playing in, or +// -1 if uChannels or iSlot is out of range, or +// -2 if there are no slots available +int samples_play_sample(Uint8 *pu8Buf, unsigned int uLength, unsigned int uChannels = AUDIO_CHANNELS, int iSlot = -1, + void (*finishedCallback)(Uint8 *pu8Buf, unsigned int uSlot) = NULL); + +// returns true if the sample indicated by 'uSlot' is currently playing +// or false if the sample isn't playing +bool samples_is_sample_playing(unsigned int uSlot); + +// This is a hack (for now) to ensure that any callbacks that were queued get fired by the main thread (instead of the audio thread). +// For now it must be manually called as often as you want your callbacks to be called. +// (in the future this will be automated) +void samples_do_queued_callbacks(); + +bool samples_set_state(unsigned int, bool); // by rdg -- give Singe the ability to pause/resume samples +bool samples_end_early(unsigned int); // Stops an active sample +void samples_flush_queue(); // Stops all active samples + +#endif // SAMPLES_H diff --git a/sound/sound.cpp b/sound/sound.cpp new file mode 100644 index 000000000..bf01baca4 --- /dev/null +++ b/sound/sound.cpp @@ -0,0 +1,882 @@ +/* +* sound.cpp +* +* Copyright (C) 2001 Matt Ownby +* +* This file is part of DAPHNE, a laserdisc arcade game emulator +* +* DAPHNE 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. +* +* DAPHNE 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 +*/ + + +// DAPHNE +// The sound code in this file uses SDL + +#ifdef DEBUG +#include +#endif + +#include +#include + +#include "SDL.h" +#include "SDL_audio.h" + +#include "sound.h" +//#include "sn_intf.h" +//#include "pc_beeper.h" +//#include "gisound.h" +//#include "dac.h" +//#include "tonegen.h" +#include "samples.h" +#include "mix.h" +#include "../io/conout.h" +#include "../io/mpo_mem.h" +#include "../io/numstr.h" +#include "../game/game.h" +#include "../daphne.h" +#include "../ldp-out/ldp-vldp.h" // added by JFA for -startsilent + +sample_s g_samples[MAX_NUM_SOUNDS] = { { 0 } }; +sample_s g_sample_saveme; // the special saveme wav which is loaded independently of any game + +bool g_sound_enabled = true; // whether sound is enabled + +bool g_bSoundMuted = false; // whether sound is muted + +struct sounddef *g_soundchip_head = NULL; // pointer to the first sound chip in our linked list of chips's +unsigned int g_uSoundChipNextID = 0; // the idea that the next soundchip to get added will get (also usually indicates how many sound chips have been added, but not if a soundchip gets deleted) + +// callback to actually do the mixing +void (*g_soundmix_callback)(Uint8* stream, int length) = mixNone; + +// The # of samples in the sound buffer +// Matt prefers 1024 but some people (cough Warren) can't handle it haha +// but now it can be changed from the command line +Uint16 g_u16SoundBufSamples = 2048; + +// # of bytes each individual sound chip should be allocated for its buffer +unsigned int g_uSoundChipBufSize = g_u16SoundBufSamples * AUDIO_BYTES_PER_SAMPLE; + +// the volume (user adjustable) of the VLDP audio stream +unsigned int g_uVolumeVLDP = AUDIO_MAX_VOLUME; + +// the volume (user adjustable) of all over sound streams besides VLDP +unsigned int g_uVolumeNonVLDP = AUDIO_MAX_VOLUME; + +int cur_wave = 0; // the current wave being played (0 to NUM_DL_BEEPS-1) +bool g_sound_initialized = false; // whether the sound will work if we try to play it + +// Macros to help automatically verify that our locks and unlocks are correct +#ifdef DEBUG +bool g_bAudioLocked = false; +#define LOCK_AUDIO assert (!g_bAudioLocked); g_bAudioLocked = true; SDL_LockAudio +#define UNLOCK_AUDIO assert (g_bAudioLocked); g_bAudioLocked = false; SDL_UnlockAudio +#else +#define LOCK_AUDIO SDL_LockAudio +#define UNLOCK_AUDIO SDL_UnlockAudio +#endif // lock audio macros + +// added by JFA for -startsilent +void set_sound_mute(bool bMuted) +{ + g_bSoundMuted = bMuted; + + // only proceed if sound has been initialized + if (g_sound_initialized) + { + LOCK_AUDIO(); + // this should set the mixing callback back to something that isn't muted + update_soundchip_volumes(); + UNLOCK_AUDIO(); + } +} +// end edit + +void set_soundbuf_size(Uint16 newbufsize) +{ + g_u16SoundBufSamples = newbufsize; + g_uSoundChipBufSize = newbufsize * AUDIO_BYTES_PER_SAMPLE; + + // re-allocate all sound buffers since the size has changed + struct sounddef *cur = g_soundchip_head; + while (cur) + { + delete cur->buffer; + cur->buffer = new Uint8 [g_uSoundChipBufSize]; + memset(cur->buffer, 0, g_uSoundChipBufSize); + cur->buffer_pointer = cur->buffer; + cur->bytes_left = g_uSoundChipBufSize; + cur = cur->next_soundchip; + } +} + +static SDL_AudioSpec specDesired, specObtained; + +bool sound_init() +// returns a true on success, false on failure +{ + + bool result = false; + int audio_rate = AUDIO_FREQ; // rate to mix audio at. This cannot be changed without resampling all .wav's and all .ogg's + + Uint16 audio_format = AUDIO_FORMAT; + int audio_channels = AUDIO_CHANNELS; + + printline("Initializing sound system ... "); + + // if the user has not disabled sound from the command line + if (is_sound_enabled()) + { + // if SDL audio initialization was successful + if (SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0) + { + specDesired.callback = audio_callback; + specDesired.channels = audio_channels; + specDesired.format = audio_format; + specDesired.freq = audio_rate; + specDesired.samples = g_u16SoundBufSamples; + specDesired.userdata = NULL; + + // this stuff doesn't need to be filled in supposedly ... + specDesired.padding = 0; + specDesired.size = 0; + + // if we can open the audio device + if (SDL_OpenAudio(&specDesired, &specObtained) >= 0) + { + // make sure we got what we asked for + if ((specObtained.channels == audio_channels) && + (specObtained.format == audio_format) && + (specObtained.freq == audio_rate) && + (specObtained.callback == audio_callback)) + { + // if we can load all our waves, we're set + + // If we are supposed to start without playing any sound, then set muted bool here. + // It must come here because add_soundchip (which comes right afterwards) will set the sound mixing callback. + if (get_startsilent()) + { + g_bSoundMuted = true; + } + + // right before initialization, add the samples 'sound chip', which can (and should be) + // only added once, so we need not track its ID (we call its functions directly) + struct sounddef soundchip; + soundchip.type = SOUNDCHIP_SAMPLES; + add_soundchip(&soundchip); + + // initialize sound chips + init_soundchip(); + + if (specObtained.samples != g_u16SoundBufSamples) + { + string strWarning = "WARNING : requested " + numstr::ToStr(g_u16SoundBufSamples) + + " samples for sound buffer, but got " + numstr::ToStr(specObtained.samples) + " samples"; + printline(strWarning.c_str()); + + // reset memory allocations + set_soundbuf_size(specObtained.samples); + } + + result = true; + g_sound_initialized = true; + + // enable the audio callback (this should come last to be safe) + SDL_PauseAudio(0); // start mixing! :) + + } // end if audio specs are correct + else + { + printline("ERROR: unable to obtain desired audio configuration"); + } + } // end if audio device could be opened ... + + // if audio device could not be opened (ie no sound card) + else + { + outstr("WARNING: Audio device could not be opened: "); + printline(SDL_GetError()); + g_sound_enabled = false; + } + } // end if sound initializtion worked + } // end if sound is enabled + + // if sound isn't enabled, then we act is if sound initialization worked so daphne doesn't quit + if (!is_sound_enabled()) + { + result = true; + } + + return(result); + +} + +// shuts down the sound subsystem +void sound_shutdown() +{ + // shutdown sound only if we previously initialized it + if (g_sound_initialized) + { + printline("Shutting down sound system..."); + SDL_PauseAudio(1); + SDL_CloseAudio(); + free_waves(); + shutdown_soundchip(); + g_sound_initialized = 0; + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } +} + +// plays a sample, returns true on success +bool sound_play(Uint32 whichone) +{ + bool result = false; + + // only play a sound if sound has been initialized (and if whichone points to a valid wav) + if (is_sound_enabled() && (whichone < MAX_NUM_SOUNDS)) + { + samples_play_sample(g_samples[whichone].pu8Buf, g_samples[whichone].uLength, g_samples[whichone].uChannels); + result = true; + } + + return(result); + +} + +// plays the 'saveme' sound +bool sound_play_saveme() +{ + bool result = false; + + if (is_sound_enabled()) + { + samples_play_sample(g_sample_saveme.pu8Buf, g_sample_saveme.uLength); + result = true; + } + + return result; +} + +// loads the wave files into the wave structure +// returns 0 if failure, or non-zero if success +int load_waves() +{ + + Uint32 i = 0; + int result = 1; + string filename = ""; + SDL_AudioSpec spec; + + for (; (i < g_game->get_num_sounds()) && result; i++) + { + filename = "sound/"; + filename += g_game->get_sound_name(i); + + // initialize so that shutting down succeeds + g_samples[i].pu8Buf = NULL; + g_samples[i].uLength = 0; + + // if loading the .wav file succeeds + if (SDL_LoadWAV(filename.c_str(), &spec, &g_samples[i].pu8Buf, &g_samples[i].uLength)) + { + // make sure audio specs are correct + if (((spec.channels == AUDIO_CHANNELS) || (spec.channels == 1)) && + (spec.freq == AUDIO_FREQ) && + (spec.format == AUDIO_S16)) + { + g_samples[i].uChannels = spec.channels; + } + // else specs are not correct + else + { + outstr("ERROR: Audio specs are not correct for "); + printline(filename.c_str()); + result = 0; + } + } // end if loading worked ... + + // TODO : add .OGG loading support in here + + else + { + outstr("ERROR: Could not open sample file "); + printline(filename.c_str()); + result = 0; + } + } + + // load "saveme" sound in + if (!SDL_LoadWAV("sound/saveme.wav", &spec, &g_sample_saveme.pu8Buf, &g_sample_saveme.uLength)) + { + printline("Loading 'saveme.wav' failed..."); + result = 0; + } + + // if something went wrong, eject ... + if (!result) + { + free_waves(); + } + + return(result); + +} + +// free all allocated waves +void free_waves() +{ + unsigned int i = 0; + + for (; i < g_game->get_num_sounds(); i++) + { + // don't de-allocate a sound if it hasn't been allocated + if (g_samples[i].pu8Buf) + { + SDL_FreeWAV(g_samples[i].pu8Buf); + g_samples[i].pu8Buf = NULL; + } + } + + if (g_sample_saveme.pu8Buf) + { + SDL_FreeWAV(g_sample_saveme.pu8Buf); + g_sample_saveme.pu8Buf = NULL; + } +} + +int get_sound_initialized() +{ + return(g_sound_initialized); +} + +void set_sound_enabled_status (bool value) +{ + g_sound_enabled = value; +} + +bool is_sound_enabled() +{ + return g_sound_enabled; +} + +// NOTE : this is called by the game driver, so it can be called even if sound is disabled +unsigned int add_soundchip(struct sounddef *candidate) +{ + LOCK_AUDIO(); // safety precaution, we don't want callback running during this function + + struct sounddef *cur = NULL; + + // if this is the first sound chip to be added to the list + if (!g_soundchip_head) + { + g_soundchip_head = new struct sounddef; // allocate a new sound chip, assume allocation is successful + cur = g_soundchip_head; // point to the new sound chip so we can populate it with info + } + // else we have to move to the end of the list + else + { + cur = g_soundchip_head; + + // go to the last sound chip in the list + while (cur->next_soundchip) + { + cur = cur->next_soundchip; + } + + cur->next_soundchip = new struct sounddef; // allocate a new sound chip at the end of our list + cur = cur->next_soundchip; // point to the new sound chip so we can populate it with info + } + + // now we must copy over the relevant info + memcpy(cur, candidate, sizeof(struct sounddef)); // copy entire thing over + cur->id = g_uSoundChipNextID; + cur->internal_id = 0; // sensible initial value + + // This function will be called before the user has a chance to modify the volumes, + // so we will initialize them all to sensible defaults. + cur->uDriverVolume[0] = cur->uDriverVolume[1] = + cur->uBaseVolume[0] = cur->uBaseVolume[1] = + cur->uVolume[0] = cur->uVolume[1] = AUDIO_MAX_VOLUME; + + ++g_uSoundChipNextID; + + cur->next_soundchip = NULL; + cur->bNeedsConstantUpdates = false; // sensible default + // create a buffer for each chip + cur->buffer = new Uint8 [g_uSoundChipBufSize]; + cur->buffer_pointer = cur->buffer; + cur->bytes_left = g_uSoundChipBufSize; + cur->init_callback = NULL; + cur->shutdown_callback = NULL; + cur->stream_callback = NULL; + cur->writedata_callback = NULL; + cur->write_ctrl_data_callback = NULL; + + memset(cur->buffer, 0, g_uSoundChipBufSize); + + // now we must assign the appropriate callbacks + switch (cur->type) + { + case SOUNDCHIP_SAMPLES: + cur->init_callback = samples_init; + cur->shutdown_callback = samples_shutdown; + cur->stream_callback = samples_get_stream; + break; + case SOUNDCHIP_VLDP: + // we only need to define stream_callback, everything else is handled by ldp-vldp + cur->stream_callback = ldp_vldp_audio_callback; + break; + + default: + printline("FATAL ERROR : unknown sound chip added"); + set_quitflag(); // force user to deal with this problem + break; + } + + // calculate mixing callback, adjust volume, recalculate rshift + // NOTE : this should come last in this function + update_soundchip_volumes(); + + UNLOCK_AUDIO(); + + return cur->id; +} + +bool delete_soundchip(unsigned int id) +{ + bool bSuccess = false; + struct sounddef *cur = g_soundchip_head; + struct sounddef *prev = NULL; + + LOCK_AUDIO(); + // if 1 or more sound chips exists ... + while (cur) + { + struct sounddef *pNext = cur->next_soundchip; + + // if we found a match, then delete it... + if (cur->id == id) + { + // if there is a shutdown callback defined, call it + if (cur->shutdown_callback) + { + cur->shutdown_callback(cur->internal_id); + } + + // if cur != g_soundchip_head in other words ... + if (prev != NULL) + { + // restore the chain that we're about to break + prev->next_soundchip = cur->next_soundchip; + } + + delete [] cur->buffer; + delete cur; + + // if we just deleted the head, then make the next soundchip be the head + if (cur == g_soundchip_head) + { + g_soundchip_head = pNext; + } + + bSuccess = true; + break; + } + prev = cur; + cur = cur->next_soundchip; + } + UNLOCK_AUDIO(); + + return bSuccess; +} + +void init_soundchip() +{ +#ifdef DEBUG + assert(is_sound_enabled()); +#endif + LOCK_AUDIO(); // safety precaution, we don't want callback running during this function + if (g_soundchip_head) + { + struct sounddef *cur = g_soundchip_head; + + while (cur) + { + // only initialize if the callback exists + if (cur->init_callback) + { + cur->internal_id = cur->init_callback(cur->hz); + if (cur->internal_id == -1) + { + printline("sound.cpp Error : sound chip failed to initialize"); + set_quitflag(); // force dev to deal with this problem + } + // else everything initialized correctly + } + cur = cur->next_soundchip; + } + } + UNLOCK_AUDIO(); +} + +// Mixing callback +// USED WHEN : all audio is muted +void mixMute(Uint8 *stream, int length) +{ + memset(stream, 0, length); +} + +// Mixing callback +// USED WHEN: there is only 1 sound chip, then there is no need to do any mixing +void mixNone(Uint8 *stream, int length) +{ + if (g_soundchip_head != NULL) + { + memcpy(stream, g_soundchip_head->buffer, length); + } +} + +// Mixing callback +// USED WHEN: there are more than 1 sound chip, but all volumes are maximum +void mixWithMaxVolume(Uint8 *stream, int length) +{ +#ifdef DEBUG + assert(g_soundchip_head); +#endif // DEBUG + + // this is a dangerous trick (casting one struct to another) in order to get us extra speed + g_pMixBufs = (struct mix_s *) g_soundchip_head; + g_pSampleDst = stream; + g_uBytesToMix = length; + g_mix_func(); + + /* + struct sounddef *cur; + + // mix all sound chip buffers together + // NOTE : this algorithm is accurate but NOT OPTIMIZED and probably should be optimized, + // because it is called constantly. + for (int sample = 0; sample < (length >> 1); sample += 2) + { + Sint32 mixed_sample_1 = 0, mixed_sample_2 = 0; // left/right channels + cur = g_soundchip_head; + while (cur) + { + mixed_sample_1 += LOAD_LIL_SINT16(((Sint16 *) cur->buffer) + sample); + mixed_sample_2 += LOAD_LIL_SINT16(((Sint16 *) cur->buffer) + sample + 1); + cur = cur->next_soundchip; + } + + DO_CLIP(mixed_sample_1); + DO_CLIP(mixed_sample_2); + + // note: sample2 needs to be on top because this is little endian, hence LSB + Uint32 val_to_store = (((Uint16) mixed_sample_2) << 16) | (Uint16) mixed_sample_1; + + STORE_LIL_UINT32(stream, val_to_store); + stream += 4; + } + */ +} + +// Mixing callback +// USED WHEN: there are more than 1 sound chip, and volumes are variable +// (this is the slowest callback) +void mixWithMults(Uint8 *stream, int length) +{ + struct sounddef *cur; + + // mix all sound chip buffers together + // NOTE : this algorithm is accurate but NOT OPTIMIZED and probably should be optimized, + // because it is called constantly. + for (int sample = 0; sample < (length >> 1); sample += 2) + { + Sint32 mixed_sample_1 = 0, mixed_sample_2 = 0; // left/right channels, 32-bit to support adding many 16-bit samples + cur = g_soundchip_head; + while (cur) + { + // multiply by the volume and then dividing by the max volume (by shifting right, which is much faster) + mixed_sample_1 += (Sint16) ((LOAD_LIL_SINT16(((Sint16 *) cur->buffer) + sample) * cur->uVolume[0]) >> AUDIO_MAX_VOL_POWER); + mixed_sample_2 += (Sint16) ((LOAD_LIL_SINT16(((Sint16 *) cur->buffer) + sample + 1) * cur->uVolume[1]) >> AUDIO_MAX_VOL_POWER); + cur = cur->next_soundchip; + } + + DO_CLIP(mixed_sample_1); + DO_CLIP(mixed_sample_2); + + Uint32 val_to_store = (((Uint16) mixed_sample_2) << 16) | (Uint16) mixed_sample_1; + STORE_LIL_UINT32(stream, val_to_store); + stream += 4; + } +} + +void audio_callback ( void *data, Uint8 *stream, int length ) +{ + // now go through the sound chips and mix them in + struct sounddef *cur = g_soundchip_head; + + // fill remaining buffer space for each sound chip + while (cur) + { +#ifdef DEBUG + assert(cur->stream_callback != NULL); // every sound chip will have to supply this +#endif + cur->stream_callback(cur->buffer_pointer, cur->bytes_left, cur->internal_id); + cur->buffer_pointer = cur->buffer; + cur->bytes_left = g_uSoundChipBufSize; + cur = cur->next_soundchip; + } + + // do the actual mixing now + g_soundmix_callback(stream, length); +} + +void audio_writedata(Uint8 id, Uint8 data) +{ + // if sound isn't initialized, then the soundchips aren't initialized either + if (g_sound_initialized) + { + LOCK_AUDIO(); // safety precaution, we don't want callback running during this function + struct sounddef *cur = g_soundchip_head; + while (cur) + { + if (cur->id == id) + { + cur->writedata_callback(data, cur->internal_id); + } + cur = cur->next_soundchip; + } + UNLOCK_AUDIO(); + } +} + +// in case audio_writedata doesn't cut it ... +void audio_write_ctrl_data(unsigned int uCtrl, unsigned int uData, Uint8 id) +{ + // if sound isn't initialized, then the soundchips aren't initialized either + if (g_sound_initialized) + { + LOCK_AUDIO(); + struct sounddef *cur = g_soundchip_head; + while (cur) + { + if (cur->id == id) + { + cur->write_ctrl_data_callback(uCtrl, uData, cur->internal_id); + } + cur = cur->next_soundchip; + } + UNLOCK_AUDIO(); + } +} + +void set_soundchip_volume(Uint8 id, unsigned int uChannel, unsigned int uVolume) +{ + struct sounddef *cur = g_soundchip_head; + while (cur) + { + if (cur->id == id) + { + set_soundchip_volume(cur, uChannel, uVolume); + break; + } + cur = cur->next_soundchip; + } +} + +void set_soundchip_volume(struct sounddef *cur, unsigned int uChannel, unsigned int uVolume) +{ + // safety check + if (uChannel < AUDIO_CHANNELS) + { + // safety check + if (uVolume <= AUDIO_MAX_VOLUME) + { + cur->uDriverVolume[uChannel] = uVolume; + LOCK_AUDIO(); + update_soundchip_volumes(); + UNLOCK_AUDIO(); + } + else + { + printline("sound.cpp, set_soundchip_volume() ERROR: volume is out of range, shutting down"); + set_quitflag(); // force dev to deal with this :) + } + } + // channel was out of range + else + { + printline("sound.cpp, set_soundchip_volume() ERROR : channel is out of range"); + set_quitflag(); // force dev to fix this + } +} + + +void set_soundchip_vldp_volume(unsigned int uVolume) +{ + if (uVolume <= AUDIO_MAX_VOLUME) + { + g_uVolumeVLDP = uVolume; + LOCK_AUDIO(); + update_soundchip_volumes(); + UNLOCK_AUDIO(); + } + else + { + printline("WARNING : request VLDP volume is out of range"); + } +} + +void set_soundchip_nonvldp_volume(unsigned int uVolume) +{ + if (uVolume <= AUDIO_MAX_VOLUME) + { + g_uVolumeNonVLDP = uVolume; + LOCK_AUDIO(); + update_soundchip_volumes(); + UNLOCK_AUDIO(); + } + else + { + printline("WARNING : request non-VLDP volume is out of range"); + } +} + +unsigned int get_soundchip_nonvldp_volume() +{ + return g_uVolumeNonVLDP; +} + +// IMPORTANT : assumes LOCK_AUDIO has already been called!!!! +void update_soundchip_volumes() +{ + bool bNonMaxVolume = false; + unsigned int uSoundchipCount = 0; + +#ifdef DEBUG + assert (g_bAudioLocked == true); +#endif + + // If sound is not muted then do some calculations + if (!g_bSoundMuted) + { + + struct sounddef *cur = g_soundchip_head; + while (cur) + { + // if this isn't a VLDP chip ... + if (cur->type != SOUNDCHIP_VLDP) + { + cur->uBaseVolume[0] = cur->uBaseVolume[1] = g_uVolumeNonVLDP; + } + // else this is the VLDP chip + else + { + cur->uBaseVolume[0] = cur->uBaseVolume[1] = g_uVolumeVLDP; + } + + for (unsigned int uChannel = 0; uChannel < 2; ++uChannel) + { + // The actual volume must take into account the user-defined BaseVolume, + // in case the user requested that the volume be 50% of whatever it would normally be. + // If the base volume is AUDIO_MAX_VOLUME, then the new volume becomes uVolume + cur->uVolume[uChannel] = (cur->uDriverVolume[uChannel] * cur->uBaseVolume[uChannel]) / AUDIO_MAX_VOLUME; + + // if we've wound up with a volume that is less than the max + if (cur->uVolume[uChannel] < AUDIO_MAX_VOLUME) + { + bNonMaxVolume = true; + } + } + + cur = cur->next_soundchip; + ++uSoundchipCount; + } + + // if we need to use the most expensive mixing callback... + if (bNonMaxVolume) + { + g_soundmix_callback = mixWithMults; + } + else if (uSoundchipCount > 1) + { + g_soundmix_callback = mixWithMaxVolume; + } + // just 1 soundchip? we can mix super fast in that case + else + { + g_soundmix_callback = mixNone; + } + + } // end if sound is not muted + // else sound is muted + else + { + g_soundmix_callback = mixMute; + } + +} + +void shutdown_soundchip() +{ +#ifdef DEBUG + assert(g_sound_initialized); +#endif + LOCK_AUDIO(); // safety precaution, we don't want callback running during this function + struct sounddef *cur = g_soundchip_head; + while (cur) + { + // if there is a shutdown callback defined, call it + if (cur->shutdown_callback) + { + cur->shutdown_callback(cur->internal_id); + } + struct sounddef *temp = cur; + cur = cur->next_soundchip; + delete [] temp->buffer; + delete temp; + } + UNLOCK_AUDIO(); +} + +void update_soundbuffer() +{ + // we don't want to update the sound buffer, if sound isn't initialized + if (g_sound_initialized) + { + // to ensure that the audio callback doesn't get called while we're in this function + LOCK_AUDIO(); + struct sounddef *cur = g_soundchip_head; + while (cur) + { + // only update if needed, to save CPU cycles + if (cur->bNeedsConstantUpdates) + { + if (cur->bytes_left >= G_1MS_BUF_SIZE) + { + cur->stream_callback(cur->buffer_pointer, G_1MS_BUF_SIZE, cur->internal_id); + cur->bytes_left -= G_1MS_BUF_SIZE; + cur->buffer_pointer += G_1MS_BUF_SIZE; + } + // else we throw away the new data + // should we handle this some other way? + } + // else doesn't need to be updated so often, so don't do it ... + cur = cur->next_soundchip; + } + UNLOCK_AUDIO(); + } +} diff --git a/sound/sound.h b/sound/sound.h new file mode 100644 index 000000000..917b7a541 --- /dev/null +++ b/sound/sound.h @@ -0,0 +1,205 @@ +/* + * sound.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SOUND_H +#define SOUND_H + +#ifdef WIN32 +#include +#else +#include +#endif + +// header file for sound.c + +// max # of samples any game can handle (make this number as small as possible) +#define MAX_NUM_SOUNDS 50 + +// frequency all our audio runs at. +// In order to change this value, all .wav's and .ogg's will need to be resampled, which +// is quite involved. Other parts of the code may assume the frequency is 44100 too (such as ldp-vldp-audio.cpp) +#define AUDIO_FREQ 44100 + +// stereo sound +#define AUDIO_CHANNELS 2 + +// stereo, 16-bit sound has 4 bytes per sample +#define AUDIO_BYTES_PER_SAMPLE 4 + +// volume for each stream can be between 0-64 +// (keep this as a power of 2, see AUDIO_MAX_VOL_POWER) +#define AUDIO_MAX_VOLUME 64 + +// if 2^AUDIO_MAX_VOL_POWER = AUDIO_MAX_VOLUME +#define AUDIO_MAX_VOL_POWER 6 + +// SDL audio format (16-bit signed, little endian) +// This is true even for big-endian platforms +#define AUDIO_FORMAT AUDIO_S16LSB + +// how many audio bytes needed to fill 1 millisecond of space +static const unsigned int G_1MS_BUF_SIZE = (AUDIO_FREQ * AUDIO_BYTES_PER_SAMPLE) / 1000; + +enum { SOUNDCHIP_UNDEFINED, SOUNDCHIP_SAMPLES, SOUNDCHIP_VLDP, SOUNDCHIP_SN76496, SOUNDCHIP_AY_3_8910, + SOUNDCHIP_PC_BEEPER, SOUNDCHIP_DAC, SOUNDCHIP_TONEGEN }; + +struct sample_s +{ + // how many channels (1 = mono, 2 = stereo) that this sample has + unsigned int uChannels; + + // length of the sample ... + unsigned int uLength; + + // the sample's buffer + Uint8 *pu8Buf; +}; + +// macro to do 16-bit clipping +#define DO_CLIP(i) if (i > 32767) { i = 32767; } else if (i < -32768) { i = -32768; } + +struct sounddef +{ + // *** THIS SECTION IS DEFINED INTERNALLY + // IMPORTANT: buffer and next_soundchip MUST come first, because they must match + // the structure mix_s defined in mix.h; this is so we can use our MMX optimized + // audio mixing function. + Uint8* buffer; // pointer to buffer used by this sound chip + struct sounddef *next_soundchip; // pointer to the next sound chip in this linked list + + Uint8* buffer_pointer; // pointer to where we are in the buffer + Uint32 bytes_left; // number of bytes left in buffer + unsigned int id; // used so game drivers can call audio_writedata (if there are multiple sound chips being used) + int internal_id; // internal ID that the sound chips returns when init_callback is called + unsigned int uVolume[AUDIO_CHANNELS]; // don't modify this value directly, use set_soundchip_volume() to do it ... + + // This is the volume that the game driver has requested (if no request, this is AUDIO_MAX_VOLUME). + // It is not affected by set_soundchip_volume. uVolume is calculated based on this value. + unsigned int uDriverVolume[AUDIO_CHANNELS]; + + // This is the volume that the user has requested (if no request, this is AUDIO_MAX_VOLUME). + // It is not affected by set_soundchip_volume. uVolume is calculated based on this value. + unsigned int uBaseVolume[AUDIO_CHANNELS]; + + // callback to initialize the sound chip. + // The callback returns an internal ID which is used in all the other callbacks to + // refer to the sound chip that has been created. + // On success a number >= 0 will be returned. If there is an error, -1 will be returned. + int (*init_callback)(Uint32 freq_hz); + void (*shutdown_callback)(int internal_id); // callback to shutdown the sound chip + void (*writedata_callback)(Uint8 data, int internal_id); // callback to write data to the sound chip + + // optional callback for those sound chips that take a 'ctrl' byte to write 'data' to, + // such as the PC beeper which writes data to specific ports. It's up to the game driver + // to decide whether to use this callback or not. + // NOTE : the arguments are unsigned int's for speed, but they usually will probably be Uint8's + void (*write_ctrl_data_callback)(unsigned int uCtrl, unsigned int uData, int internal_id); + + void (*stream_callback)(Uint8* stream, int length, int internal_id); // callback to write stream to buffer + + // *** THIS SECTION IS DEFINED WHEN SOUND CHIP IS ADDED + int type; // type of sound chip (See enum's) + Uint32 hz; // speed of sound chip in Hz + + // Should be true if sound quality of chip is better the more often it is updated. + // An example is Super Don's sound chip. + // Should be false if sound doesn't change no matter how fast it is updated. + // An example is VLDP which has constant pre-defined audio. + // FIXME : in the future this should be changed to define how frequent of updates are + // needed, because the less frequent of updates, the better. + bool bNeedsConstantUpdates; +}; + +// adds a new soundchip and returns the ID +unsigned int add_soundchip(struct sounddef *); // add a new cpu + +// deletes a soundchip that has previously been added +bool delete_soundchip(unsigned int id); + +void init_soundchip(); // inits all the sound chips + +// Mixing callback +// USED WHEN : all audio is muted +void mixMute(Uint8 *stream, int length); + +// Mixing callback +// USED WHEN: there is only 1 sound chip, then there is no need to do any mixing +// (fastest) +void mixNone(Uint8 *stream, int length); + +// Mixing callback +// USED WHEN: there are more than 1 sound chip, but all volumes are maximum +// (pretty fast) +void mixWithMaxVolume(Uint8 *stream, int length); + +// Mixing callback +// USED WHEN: there are more than 1 sound chip, and volumes are variable +// (this is the slowest callback, only use it if you must) +void mixWithMults(Uint8 *stream, int length); + +void audio_callback ( void *, Uint8 *, int); // audio callback for SDLMixer +void audio_writedata(Uint8, Uint8); + +// for game driver to send commands to sound chip +void audio_write_ctrl_data(unsigned int uCtrl, unsigned int uData, Uint8 id); + +// Used to set the volume of an audio stream. Valid volume values are 0 to AUDIO_MAX_VOLUME. +// 'id' is the id returned by add_soundchip() +// 'channel' is which audio channel to the set the volume for (0 = left, 1 = right I think) +// WARNING : setting the volume to anything lower than AUDIO_MAX_VOLUME may incur a (small?) +// performance penalty and should be avoided if there is little benefit to adjusting +// the volume. +// If there is an error, the logfile will be notified and the quitflag may be set :) +void set_soundchip_volume(Uint8 id, unsigned int uChannel, unsigned int uVolume); + +// helper function for the other set_soundchip_volume +void set_soundchip_volume(struct sounddef *cur, unsigned int uChannel, unsigned int uVolume); + +// so the user can override the default VLDP volume +void set_soundchip_vldp_volume(unsigned int uVolume); + +// so the user can override the default volume of all soundchips besides VLDP +void set_soundchip_nonvldp_volume(unsigned int uVolume); +unsigned int get_soundchip_nonvldp_volume(); // rdg + +// Recalculates uVolume based on values of drivervolume and basevolume +// Also calculates which rshift and callback to use +void update_soundchip_volumes(); + +void shutdown_soundchip(); +void update_soundbuffer(); // update the sound buffers with 1 ms worth of data +void set_soundbuf_size(Uint16 newbufsize); +bool sound_init(); +void sound_shutdown(); +bool sound_play(Uint32 whichone); +bool sound_play_saveme(); +int load_waves(); +void free_waves(); +int get_sound_initialized(); +void set_sound_mute(bool bMuted); // added by JFA for -startsilent +void set_sound_enabled_status (bool value); +bool is_sound_enabled(); + +// (re)calculates the right-shift value to be used to mix sounds (for fast division) +void sound_recalc_rshift(); + +#endif diff --git a/timer/Makefile b/timer/Makefile new file mode 100644 index 000000000..3b7fcdd97 --- /dev/null +++ b/timer/Makefile @@ -0,0 +1,21 @@ +# sub Makefile for TIMER folder + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = timer.o + +.SUFFIXES: .cpp + +all: ${OBJS} + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +clean: + rm -f ${OBJS} *.d + diff --git a/timer/timer.cpp b/timer/timer.cpp new file mode 100644 index 000000000..09e5f20ca --- /dev/null +++ b/timer/timer.cpp @@ -0,0 +1,67 @@ +/* + * timer.cpp + * + * Copyright (C) 1999-2006 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// by Matt Ownby, 11 August 1999 + +// Purpose: To provide a way for our emulator to track very precise time +// Second purpose: To keep this source code portable + +#include "timer.h" + +// returns the elapsed time (in milliseconds) since the current +// time and previous_time (which is also in milliseconds) +unsigned int elapsed_ms_time(unsigned int previous_time) +{ + return(GET_TICKS() - previous_time); +} + +unsigned int GetTicksFunc() +{ + return GET_TICKS(); +} + +#ifdef GP2X +unsigned int g_uLastTicks = 0; +unsigned int g_uExtraMs = 0; + +unsigned int GP2X_GetTicks(unsigned int uMiniTicks) +{ + // gp2x's mini ticks can be converted to ms by dividing by 7372.8, but we used 7373 for speed + const unsigned int DIVIDER = 7373; + + // # of milliseconds in one cycle before 32-bit timer wraps around + const unsigned int CYCLE_MS = 0xFFFFFFFF / DIVIDER; + + unsigned int uTicks = uMiniTicks / DIVIDER; + + // has wraparound occurred? + if (uMiniTicks < g_uLastTicks) + { + g_uExtraMs += CYCLE_MS; // add one cycle to the extra + } + + g_uLastTicks = uTicks; + uTicks += g_uExtraMs; // add whatever extra we've accumulated + + return uTicks; +} +#endif // GP2X diff --git a/timer/timer.h b/timer/timer.h new file mode 100644 index 000000000..fdfc12a22 --- /dev/null +++ b/timer/timer.h @@ -0,0 +1,59 @@ +#ifndef TIMER_H +#define TIMER_H + +/* + * timer.h + * + * Copyright (C) 1999-2006 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + + +// header file for timestuff.c + +#include + +#ifndef GP2X +// not GP2X code ... +#define GET_TICKS SDL_GetTicks +#define MAKE_DELAY SDL_Delay +#else + +// GP2X CODE HERE + +extern "C" +{ +unsigned int SDL_GP2X_GetMiniTicks(); +} + +unsigned int GP2X_GetTicks(unsigned int uMiniTicks); +#define GET_TICKS(dummy) GP2X_GetTicks(SDL_GP2X_GetMiniTicks()) +#define MAKE_DELAY SDL_Delay +#endif // GP2X + +unsigned int elapsed_ms_time(unsigned int previous_time); + +// wrapper function to refer to GET_TICKS macro (in case the macro does not do a single function call!) +unsigned int GetTicksFunc(); + +// legacy functions +#define refresh_ms_time GET_TICKS +#define make_delay MAKE_DELAY + +#endif // TIMER_H + diff --git a/video/Makefile b/video/Makefile new file mode 100644 index 000000000..732811c4e --- /dev/null +++ b/video/Makefile @@ -0,0 +1,34 @@ +# sub Makefile for VIDEO folder + +%.d : %.cpp + set -e; $(CXX) -MM $(CFLAGS) $< \ + | sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \ + [ -s $@ ] || rm -f $@ + +OBJS = video.o SDL_Console.o SDL_DrawText.o \ + SDL_ConsoleCommands.o palette.o rgb2yuv.o blend.o + +.SUFFIXES: .cpp + +all: ${OBJS} rgb2yuv-asm blend_mmx-asm + +include $(OBJS:.o=.d) + +.cpp.o: + ${CXX} ${CFLAGS} -c $< -o $@ + +# this assembly language code is MMX only, so we have a conditional here +# so that non-MMX cpu's don't choke here ... +rgb2yuv-asm: rgb2yuv-gas.s +ifeq ($(USE_MMX),1) + as rgb2yuv-gas.s -o rgb2yuv-gas.o +endif + +blend_mmx-asm: blend_mmx-gas.s +ifeq ($(USE_MMX),1) + as blend_mmx-gas.s -o blend_mmx-gas.o +endif + +clean: + rm -f ${OBJS} *.d + diff --git a/video/SDL_Console.cpp b/video/SDL_Console.cpp new file mode 100644 index 000000000..45e1c208f --- /dev/null +++ b/video/SDL_Console.cpp @@ -0,0 +1,467 @@ +/* SDL_Console.c + * Written By: Garrett Banuk + * This is free, just be sure to give me credit when using it + * in any of your programs. + */ + + +#include +#include + +#include +// Mac OSX doesn't have a malloc.h +//#include + +#include +#include +//#include "sdl_input.h" // MATT added +//#include "bitmap.h" // MATT added +#include "SDL_Console.h" +#include "SDL_DrawText.h" + +#ifdef WIN32 +#pragma warning (disable:4244) // disable the warning about possible loss of data +#endif + +//extern SDL_Surface *G_screen; // MATT added, functions aren't working +//extern int G_consoledown; // MATT added, functions aren't working + +static char **ConsoleLines = NULL; +static char **CommandLines = NULL; +static int TotalConsoleLines = 0; /* Total number of lines in the console */ +static int ConsoleScrollBack = 0; /* How much the users scrolled back in the console */ +static int TotalCommands = 0; /* Number of commands in the Back Commands */ +static int FontNumber; /* This is the number of the font for the console */ +static int Line_Buffer; /* The number of lines in the console */ +static int BackX, BackY; /* Background images x and y coords */ +static SDL_Surface *ConsoleSurface; /* Surface for the console text */ +static SDL_Surface *OutputScreen; /* This is the screen to draw to */ +static SDL_Surface *Border = NULL; /* Sides, bottom and corners of the console border */ +static SDL_Surface *BackgroundImage = NULL; /* Background image for the console */ +static SDL_Surface *InputBackground; /* Dirty rectangle to draw over behind the users background */ + + +/* Takes keys from the keyboard and inputs them to the console */ +void ConsoleEvents(SDL_Event *event) +{ + + static int StringLocation = 0; /* Current character location in the current string */ + static int CommandScrollBack = 0; /* How much the users scrolled back in the command lines */ + SDL_Rect inputbackground; + + + switch(event->type) + { + case SDL_KEYDOWN: + switch(event->key.keysym.sym) + { + case SDLK_PAGEUP: + if(ConsoleScrollBack < TotalConsoleLines && ConsoleScrollBack < Line_Buffer) + { + ConsoleScrollBack++; + UpdateConsole(); + } + break; + case SDLK_PAGEDOWN: + if(ConsoleScrollBack>0) + { + ConsoleScrollBack--; + UpdateConsole(); + } + break; + case SDLK_END: + ConsoleScrollBack = 0; + UpdateConsole(); + break; + case SDLK_UP: + if(CommandScrollBack < TotalCommands ) + { + /* move back a line in the command strings and copy the command to the current input string */ + CommandScrollBack++; + memset(ConsoleLines[0], 0, CHARS_PER_LINE); + strcpy(ConsoleLines[0], CommandLines[CommandScrollBack]); + StringLocation = strlen( CommandLines[CommandScrollBack]); + UpdateConsole(); + } + break; + case SDLK_DOWN: + if(CommandScrollBack > 0) + { + /* move forward a line in the command strings and copy the command to the current input string*/ + CommandScrollBack--; + memset(ConsoleLines[0], 0, CHARS_PER_LINE); + strcpy(ConsoleLines[0], CommandLines[CommandScrollBack]); + StringLocation = strlen(ConsoleLines[CommandScrollBack]); + UpdateConsole(); + } + break; + case SDLK_BACKSPACE: + if(StringLocation > 0) + { + ConsoleLines[0][StringLocation-1] = '\0'; + StringLocation--; + inputbackground.x = 0; + inputbackground.y = ConsoleSurface->h-FontHeight(FontNumber); + inputbackground.w = ConsoleSurface->w; + inputbackground.h = FontHeight(FontNumber); + SDL_BlitSurface(InputBackground, NULL, ConsoleSurface, &inputbackground); + SDLDrawText(ConsoleLines[0], ConsoleSurface, FontNumber, 4, ConsoleSurface->h-FontHeight(FontNumber)); + } + break; + case SDLK_TAB: + TabCompletion( ConsoleLines[0], &StringLocation ); + break; + case SDLK_RETURN: + NewLineCommand(); + /* copy the input into the past commands strings */ + strcpy(CommandLines[0], ConsoleLines[0]); + strcpy(ConsoleLines[1], ConsoleLines[0]); + CommandExecute(ConsoleLines[0]); + /* zero out the current string and get it ready for new input */ + memset(ConsoleLines[0], 0, CHARS_PER_LINE); + CommandScrollBack = -1; + StringLocation = 0; + UpdateConsole(); + break; + default: + if(StringLocation < CHARS_PER_LINE-1 && event->key.keysym.unicode) + { + ConsoleLines[0][StringLocation] = event->key.keysym.unicode; + StringLocation++; + inputbackground.x = 0; + inputbackground.y = ConsoleSurface->h-FontHeight(FontNumber); + inputbackground.w = ConsoleSurface->w; + inputbackground.h = FontHeight(FontNumber); + SDL_BlitSurface(InputBackground, NULL, ConsoleSurface, &inputbackground); + SDLDrawText(ConsoleLines[0], ConsoleSurface, FontNumber, 4, ConsoleSurface->h-FontHeight(FontNumber)); + } + break; + } + break; + default: + break; + } +} + + +/* Updates the console buffer */ +void UpdateConsole() +{ + int loop; + int Screenline = OutputScreen->h/2/FontHeight(FontNumber); + SDL_Rect DestRect; + + + SDL_FillRect(ConsoleSurface, NULL, 0); + + /* draw the background image if there is one */ + if(BackgroundImage) + { + DestRect.x = BackX; + DestRect.y = BackY; + DestRect.w = BackgroundImage->w; + DestRect.h = BackgroundImage->h; + SDL_BlitSurface(BackgroundImage, NULL, ConsoleSurface, &DestRect); + } + + /* Draw the text */ + for( loop=0; loop 0 ) + for( loop=4; loopw-FontWidth(FontNumber)*2; loop+=FontWidth(FontNumber)*2) + SDLDrawText("^ ", ConsoleSurface, FontNumber, loop, ConsoleSurface->h-FontHeight(FontNumber)); + else + SDLDrawText(ConsoleLines[0], ConsoleSurface, FontNumber, 4, ConsoleSurface->h-FontHeight(FontNumber)); + +} + +/* Draws the console buffer to the screen */ +void DrawConsole() +{ + int loop; + SDL_Rect DestRect = {0, 0, ConsoleSurface->w, ConsoleSurface->h}; + + + SDL_BlitSurface(ConsoleSurface, NULL, OutputScreen, &DestRect); + + /* Now draw a border */ + if(Border) + { + DestRect.x = 0; + DestRect.y = ConsoleSurface->h; + DestRect.w = Border->w; + DestRect.h = Border->h; + + for(loop=0; loop<=OutputScreen->w/Border->w; loop++) + { + DestRect.x = Border->w*loop; + SDL_BlitSurface(Border, NULL, OutputScreen, &DestRect); + } + } + + +} + + +/* Initializes the console strings */ +int ConsoleInit(const char *FontName, SDL_Surface *DisplayScreen, int lines) +{ + int loop; + SDL_Surface *Temp; + + OutputScreen = DisplayScreen; + Line_Buffer = lines; + + /* malloc memory for the console lines. */ + ConsoleLines = (char **)malloc(sizeof(char *)*Line_Buffer); + CommandLines = (char **)malloc(sizeof(char *)*Line_Buffer); + + for(loop=0; loop<=Line_Buffer-1; loop++) + { + ConsoleLines[loop] = (char*)calloc( CHARS_PER_LINE, sizeof(char)); + CommandLines[loop] = (char*)calloc( CHARS_PER_LINE, sizeof(char)); + } + + /* load the console surface */ + Temp = SDL_AllocSurface(SDL_SWSURFACE, OutputScreen->w, OutputScreen->h/2, OutputScreen->format->BitsPerPixel, 0, 0, 0, 0); + if(Temp == NULL) + { + printf("Error Console.c:ConsoleInit()\n\tCouldn't create the ConsoleSurface\n"); + return 1; + } + ConsoleSurface = SDL_DisplayFormat(Temp); + SDL_FreeSurface(Temp); + SDL_FillRect(ConsoleSurface, NULL, 0); + + /* Load the consoles font */ + if( -1 == (FontNumber = LoadFont(FontName, TRANS_FONT))) + { + printf("Could not load the font \"%s\" for the console!\n", FontName); + return 1; + } + + /* Load the dirty rectangle for user input */ + Temp = SDL_AllocSurface(SDL_SWSURFACE, OutputScreen->w, FontHeight(FontNumber), OutputScreen->format->BitsPerPixel, 0, 0, 0, 0); + if(Temp == NULL) + { + printf("Error Console.c:ConsoleInit()\n\tCouldn't create the input background\n"); + return 1; + } + InputBackground = SDL_DisplayFormat(Temp); + SDL_FreeSurface(Temp); + SDL_FillRect(InputBackground, NULL, 0); + + + ConOut("Console initialised." ); + ListCommands(); + + + + return 0; +} + +// MATT added this to fix the memory leaks +void ConsoleShutdown() +{ + + int loop = 0; + + for(loop=0; loop<=Line_Buffer-1; loop++) + { + if (ConsoleLines && ConsoleLines[loop]) + { + free(ConsoleLines[loop]); + ConsoleLines[loop] = 0; + } + if (CommandLines && CommandLines[loop]) + { + free(CommandLines[loop]); + ConsoleLines[loop] = 0; + } + } + + if (ConsoleLines) + { + free(ConsoleLines); + ConsoleLines = 0; + } + if (CommandLines) + { + free(CommandLines); + CommandLines = 0; + } +} + +/* Increments the console line */ +void NewLineConsole() +{ + int loop; + char *temp = ConsoleLines[Line_Buffer-1]; + + for(loop=Line_Buffer-1; loop>1; loop--) + ConsoleLines[loop] = ConsoleLines[loop-1]; + + ConsoleLines[1] = temp; + + memset( ConsoleLines[1], 0, CHARS_PER_LINE); + TotalConsoleLines++; +} + + +/* Increments the command lines */ +void NewLineCommand() +{ + int loop; + char *temp = CommandLines[Line_Buffer-1]; + + for(loop=Line_Buffer-1; loop>0; loop--) + CommandLines[loop] = CommandLines[loop-1]; + + CommandLines[0] = temp; + + memset( CommandLines[0], 0, CHARS_PER_LINE); + TotalCommands++; +} + + +/* Outputs text to the console (in game and stdout), up to 256 chars can be entered + * '\n' characters only take effect on stdout. + */ +void ConOut(const char *str, ... ) +{ + va_list marker; + char temp[256]; + + + va_start(marker, str); + vsprintf(temp, str, marker); + va_end(marker); + + if(ConsoleLines) + { + strncpy(ConsoleLines[1], temp, CHARS_PER_LINE); + ConsoleLines[1][CHARS_PER_LINE-1] = '\0'; + NewLineConsole(); + UpdateConsole(); + } + + /* And print to stdout */ + // MATT : we don't want stdout.txt file createdin windows +#ifdef UNIX + // MPO : updated, printing to stdout will be done in conout.cpp insteead +// printf("%s\n", temp); +#endif +} + +// MATT added this function to print a string but not add a newline to the end +// It's the same as ConOut with small modifications +void ConOutstr(char *s) +{ + if(ConsoleLines) + { + strncpy(ConsoleLines[1], s, CHARS_PER_LINE); + ConsoleLines[1][CHARS_PER_LINE-1] = '\0'; + UpdateConsole(); + } + +// don't print until we line feed or else we will get multiple prints +// printf("%s", s); +} + +/* Sets a border for the console, the parameter is NULL the border will + * be unloaded */ +int SetConsoleBorder(const char *border) +{ + SDL_Surface *temp; + + + if(border == NULL && Border != NULL) + { + SDL_FreeSurface(Border); + Border = NULL; + return 0; + } + + if(NULL == (temp = SDL_LoadBMP(border))) + { + ConOut("Cannot load border %s.", border); + return 1; + } + if(Border != NULL) + SDL_FreeSurface(Border); + + Border = SDL_DisplayFormat(temp); + SDL_FreeSurface(temp); + + SDL_SetColorKey(Border, SDL_SRCCOLORKEY, Border->format->Rmask|Border->format->Bmask); + + if(ConsoleSurface->format->alpha) + SDL_SetAlpha(Border, SDL_SRCALPHA, ConsoleSurface->format->alpha); + + + return 0; +} + + +/* Sets the alpha level of the console, 0 turns off alpha blending */ +void ConsoleAlpha( unsigned char alpha ) +{ + + if(alpha > 0 && alpha <= 200) + { + SDL_SetAlpha(ConsoleSurface, SDL_SRCALPHA, alpha); + if(Border) SDL_SetAlpha(Border, SDL_SRCALPHA, alpha); + } + else if(alpha == 0) + { + SDL_SetAlpha(ConsoleSurface, 0, alpha); + if(Border) SDL_SetAlpha(Border, 0, alpha); + } + UpdateConsole(); +} + + +/* Adds background image to the console */ +int ConsoleBackground(const char *image, int x, int y) +{ + SDL_Surface *temp; + SDL_Rect backgroundsrc, backgrounddest; + + + if(image == NULL && BackgroundImage != NULL) + { + SDL_FreeSurface(BackgroundImage); + BackgroundImage = NULL; + SDL_FillRect(InputBackground, NULL, 0); + return 0; + } + + if(NULL == (temp = SDL_LoadBMP(image))) + { + ConOut("Cannot load background %s.", image); + return 1; + } + if(BackgroundImage != NULL) + SDL_FreeSurface(BackgroundImage); + + BackgroundImage = SDL_DisplayFormat(temp); + SDL_FreeSurface(temp); + BackX = x; + BackY = y; + + backgroundsrc.x = 0; + backgroundsrc.y = ConsoleSurface->h-FontHeight(FontNumber)-BackY; + backgroundsrc.w = BackgroundImage->w; + backgroundsrc.h = InputBackground->h; + + backgrounddest.x = BackX; + backgrounddest.y = 0; + backgrounddest.w = BackgroundImage->w; + backgrounddest.h = FontHeight(FontNumber); + + SDL_FillRect(InputBackground, NULL, 0); + SDL_BlitSurface(BackgroundImage, &backgroundsrc, InputBackground, &backgrounddest); + + return 0; +} diff --git a/video/SDL_Console.h b/video/SDL_Console.h new file mode 100644 index 000000000..9f6ef71bc --- /dev/null +++ b/video/SDL_Console.h @@ -0,0 +1,32 @@ +#ifndef SDL_Console_H +#define SDL_Console_H + + +#include "SDL_ConsoleCommands.h" + + +#define CHARS_PER_LINE 128 + +#ifdef __cplusplus +extern "C" { +#endif + +void ConsoleEvents(SDL_Event *event); +void DrawConsole(); +void UpdateConsole(); +int ConsoleInit(const char *FontName, SDL_Surface *DisplayScreen, int lines); +void ConsoleShutdown(); // MATT added +void NewLineConsole(); +void NewLineCommand(); +void ConOut(const char *str, ... ); +void ConOutstr(char *); // MATT added +int SetConsoleBorder(const char *borderset); +void ConsoleAlpha( unsigned char alpha ); +int ConsoleBackground(const char *image, int x, int y); + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/video/SDL_ConsoleCommands.cpp b/video/SDL_ConsoleCommands.cpp new file mode 100644 index 000000000..8edfa03ae --- /dev/null +++ b/video/SDL_ConsoleCommands.cpp @@ -0,0 +1,105 @@ +/* SDL_Console.c + * Written By: Garrett Banuk + * This is free, just be sure to give me credit when using it + * in any of your programs. + */ + + +#include +#include +#include +#include +#include "SDL_Console.h" +#include "SDL_ConsoleCommands.h" + + +/* Linked list of all the commands. */ +static CommandInfo *Commands = NULL; + + +/* executes the command passed in from the string */ +void CommandExecute(char *BackStrings ) +{ + char Command[CHARS_PER_LINE]; + CommandInfo *CurrentCommand = Commands; + + /* Get the command out of the string */ + if(EOF == sscanf(BackStrings, "%s", Command)) + return; + + NewLineConsole(); + + /* Find the command nd execute the function associated with it */ + while(CurrentCommand) + { + if(0 == strcmp(Command, CurrentCommand->CommandWord)) + { + CurrentCommand->CommandCallback(BackStrings+strlen(Command)); + return; + } + CurrentCommand = CurrentCommand->NextCommand; + } + + /* Command wasn't found */ + ConOut("Bad Command"); + +} + +/* Use this to add commands. + * Pass in a pointer to a funtion that will take a string which contains the + * arguments passed to the command. Second parameter is the command to execute + * on. + */ +void AddCommand( void(*CommandCallback)(char *Parameters),const char *CommandWord) +{ + CommandInfo **CurrentCommand = &Commands; + + + while(*CurrentCommand) + CurrentCommand = &((*CurrentCommand)->NextCommand); + + + /* Add a command to the list */ + *CurrentCommand = (CommandInfo*)malloc(sizeof(CommandInfo)); + (*CurrentCommand)->CommandCallback = CommandCallback; + (*CurrentCommand)->CommandWord = (char*)malloc(strlen(CommandWord)+1); + strcpy((*CurrentCommand)->CommandWord, CommandWord); + (*CurrentCommand)->NextCommand = NULL; + + +} + +/* tab completes commands, not perfect finds the first matching command */ +void TabCompletion(char *CommandLine, int *location ) +{ + CommandInfo *CurrentCommand = Commands; + + + while(CurrentCommand) + { + if(0 == strncmp(CommandLine, CurrentCommand->CommandWord, strlen(CommandLine))) + { + strcpy(CommandLine, CurrentCommand->CommandWord); + CommandLine[strlen(CurrentCommand->CommandWord)] = ' '; + *location = strlen(CurrentCommand->CommandWord)+1; + UpdateConsole(); + return; + } + CurrentCommand = CurrentCommand->NextCommand; + } +} + + +/* Lists all the commands to be used in the console */ +void ListCommands() +{ + CommandInfo *CurrentCommand = Commands; + + ConOut(" "); + while(CurrentCommand) + { + ConOut("%s", CurrentCommand->CommandWord); + CurrentCommand = CurrentCommand->NextCommand; + } + +} diff --git a/video/SDL_ConsoleCommands.h b/video/SDL_ConsoleCommands.h new file mode 100644 index 000000000..934c778e0 --- /dev/null +++ b/video/SDL_ConsoleCommands.h @@ -0,0 +1,26 @@ +#ifndef SDL_ConsoleCommands_H +#define SDL_ConsoleCommands_H + + + +typedef struct CommandInfo_td +{ + void (*CommandCallback)(char *Parameters); + char *CommandWord; + struct CommandInfo_td *NextCommand; +} CommandInfo; + +#ifdef __cplusplus +extern "C" { +#endif + +void CommandExecute(char *BackStrings); +void AddCommand(void (*CommandCallback)(char *Parameters),const char *CommandWord); +void TabCompletion(char* CommandLine, int *location); +void ListCommands(); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/video/SDL_DrawText.cpp b/video/SDL_DrawText.cpp new file mode 100644 index 000000000..1b3549d11 --- /dev/null +++ b/video/SDL_DrawText.cpp @@ -0,0 +1,160 @@ +/* SDL_Console.c + * Written By: Garrett Banuk + * This is free, just be sure to give me credit when using it + * in any of your programs. + */ + +#include +#include +#include +#include +#include "SDL_DrawText.h" + +#ifdef WIN32 +#pragma warning (disable:4244) // disable the warning about possible loss of data +#endif + +static int TotalFonts = 0; +/* Linked list of fonts */ +static BitFont *BitFonts = NULL; + + + +/* Loads the font into a new struct + * returns -1 as an error else it returns the number + * of the font for the user to use + */ +int LoadFont(const char *BitmapName, int flags) +{ + int FontNumber = 0; + BitFont **CurrentFont = &BitFonts; + SDL_Surface *Temp; + + while(*CurrentFont) + { + CurrentFont = &((*CurrentFont)->NextFont); + FontNumber++; + } + + /* load the font bitmap */ + if(NULL == (Temp = SDL_LoadBMP(BitmapName))) + { + printf("Error Cannot load file %s\n", BitmapName ); + return -1; + } + + /* Add a font to the list */ + *CurrentFont = (BitFont*)malloc(sizeof(BitFont)); + + (*CurrentFont)->FontSurface = SDL_DisplayFormat(Temp); + SDL_FreeSurface(Temp); + + (*CurrentFont)->CharWidth = (*CurrentFont)->FontSurface->w/256; + (*CurrentFont)->CharHeight = (*CurrentFont)->FontSurface->h; + (*CurrentFont)->FontNumber = FontNumber; + (*CurrentFont)->NextFont = NULL; + + TotalFonts++; + + /* Set font as transparent if the flag is set */ + if(flags & TRANS_FONT) + { + /* This line was left in in case of problems getting the pixel format */ + /* SDL_SetColorKey((*CurrentFont)->FontSurface, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0xFF00FF); */ + SDL_SetColorKey((*CurrentFont)->FontSurface, SDL_SRCCOLORKEY|SDL_RLEACCEL, + (*CurrentFont)->FontSurface->format->Rmask|(*CurrentFont)->FontSurface->format->Bmask); + } + +// printf("Loaded font \"%s\". Width:%d, Height:%d\n", BitmapName, (*CurrentFont)->CharWidth, (*CurrentFont)->CharHeight ); + return FontNumber; +} + + +/* Takes the font type, coords, and text to draw to the surface*/ +void SDLDrawText(const char *string, SDL_Surface *surface, int FontType, int x, int y ) +{ + int loop; + int characters; + SDL_Rect SourceRect, DestRect; + BitFont *CurrentFont; + + + CurrentFont = FontPointer(FontType); + + /* see how many characters can fit on the screen */ + if(x>surface->w || y>surface->h) return; + + if(strlen(string) < (unsigned int) (surface->w-x)/CurrentFont->CharWidth) + characters = strlen(string); + else + characters = (surface->w-x)/CurrentFont->CharWidth; + + DestRect.x = x; + DestRect.y = y; + DestRect.w = CurrentFont->CharWidth; + DestRect.h = CurrentFont->CharHeight; + + SourceRect.y = 0; + SourceRect.w = CurrentFont->CharWidth; + SourceRect.h = CurrentFont->CharHeight; + + /* Now draw it */ + for(loop=0; loopCharWidth; + SDL_BlitSurface(CurrentFont->FontSurface, &SourceRect, surface, &DestRect); + + DestRect.x += CurrentFont->CharWidth; + } + +} + + +/* Returns the height of the font numbers character + * returns 0 if the fontnumber was invalid */ +int FontHeight( int FontNumber ) +{ + BitFont *CurrentFont; + + CurrentFont = FontPointer(FontNumber); + if(CurrentFont) + return CurrentFont->CharHeight; + else + return 0; +} + +/* Returns the width of the font numbers charcter */ +int FontWidth( int FontNumber ) +{ + BitFont *CurrentFont; + + CurrentFont = FontPointer(FontNumber); + if(CurrentFont) + return CurrentFont->CharWidth; + else + return 0; +} + +/* Returns a pointer to the font struct of the number + * returns NULL if theres an error + */ +BitFont* FontPointer(int FontNumber) +{ + int fontamount = 0; + BitFont *CurrentFont = BitFonts; + + + while(fontamountFontNumber == FontNumber) + return CurrentFont; + else + { + CurrentFont = CurrentFont->NextFont; + fontamount++; + } + } + + return NULL; + +} diff --git a/video/SDL_DrawText.h b/video/SDL_DrawText.h new file mode 100644 index 000000000..72054aef3 --- /dev/null +++ b/video/SDL_DrawText.h @@ -0,0 +1,31 @@ +#ifndef SDL_DrawText_h +#define SDL_DrawText_h + + +#define TRANS_FONT 1 + + +typedef struct BitFont_td +{ + SDL_Surface *FontSurface; + int CharWidth; + int CharHeight; + int FontNumber; + struct BitFont_td *NextFont; +} BitFont; + +#ifdef __cplusplus +extern "C" { +#endif + +void SDLDrawText(const char *string, SDL_Surface *surface, int FontType, int x, int y ); +int LoadFont(const char *BitmapName, int flags ); +int FontHeight( int FontNumber ); +int FontWidth( int FontNumber ); +BitFont* FontPointer(int FontNumber ); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/video/blend.cpp b/video/blend.cpp new file mode 100644 index 000000000..90846319d --- /dev/null +++ b/video/blend.cpp @@ -0,0 +1,68 @@ +/* + * blend.cpp + * + * Copyright (C) 2005 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// blend.cpp + +#include "blend.h" + +#ifdef DEBUG +#include +#endif + +// if we aren't using the MMX version + +#ifndef USE_MMX +Uint8 *g_blend_line1 = 0; +Uint8 *g_blend_line2 = 0; +Uint8 *g_blend_dest = 0; +unsigned int g_blend_iterations = 0; +#endif + +// A C version of blend_mmx +// blend_mmx is about 4X as fast as this C version +// NOTE : we always want this defined, even when using MMX, for the purpose of testing (see releasetest) +void blend_c() +{ + register Uint8 *ptr1 = g_blend_line1; + register Uint8 *ptr2 = g_blend_line2; + + for (unsigned int col = 0; col < g_blend_iterations; col++) + { + g_blend_dest[col] = (Uint8) ((*ptr1 + *ptr2) >> 1); // average fields together + ptr1++; + ptr2++; + } +} + +#ifdef USE_MMX + +#ifdef DEBUG +// debug version of blend MMX that does safety checking before the call. This obviously won't be used +// during release builds. +void debug_blend_mmx() +{ + assert(((g_blend_iterations % 8) == 0) && (g_blend_iterations >= 8)); // blend MMX does 8 at a time + blend_mmx(); +} +#endif // DEBUG + +#endif // NATIVE_CPU_X86 diff --git a/video/blend.h b/video/blend.h new file mode 100644 index 000000000..cc3894902 --- /dev/null +++ b/video/blend.h @@ -0,0 +1,92 @@ +/* + * blend.h + * + * Copyright (C) 2005 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// blend.h + + +#ifndef BLEND_H +#define BLEND_H + +#ifdef MAC_OSX +#include "mmxdefs.h" +#endif + +#include // for datatype defs + +// TO USE THE BLEND FUNCTIONS: +// 1 - set g_blend_line1 to the first line of bytes to be averaged +// 2 - set g_blend_line2 to the second line of bytes to be averaged +// 3 - set g_blend_dest to the line of bytes that will be the destination +// 4 - set g_blend_iterations to how many bytes long all lines are (they all must be the same length). +// IMPORTANT : g_blend_iterations must be a multiple of 8, and must be >= 8! +// 5 - run g_blend_func() and you're done! + +// we always want this function defined for the purpose of testing (releasetest.cpp) +void blend_c(); + +// Here we make some definitions so that the MMX/C code use identical syntax and variables +#ifdef USE_MMX + +#if defined (MAC_OSX) || defined (WIN32) +extern "C" void blend_mmx(); +extern "C" Uint8 *asm_line1; +extern "C" Uint8 *asm_line2; +extern "C" Uint8 *asm_dest; +extern "C" Uint32 asm_iterations; +#define g_blend_line1 asm_line1 +#define g_blend_line2 asm_line2 +#define g_blend_dest asm_dest +#define g_blend_iterations asm_iterations +#else +extern "C" void _blend_mmx(); +extern "C" Uint8 *_asm_line1; +extern "C" Uint8 *_asm_line2; +extern "C" Uint8 *_asm_dest; +extern "C" Uint32 _asm_iterations; +#define g_blend_line1 _asm_line1 +#define g_blend_line2 _asm_line2 +#define g_blend_dest _asm_dest +#define g_blend_iterations _asm_iterations +#define blend_mmx _blend_mmx +#endif // MAC_OSX + +// debug version gets some extra (slower) error checking +#ifdef DEBUG +#define g_blend_func debug_blend_mmx +void debug_blend_mmx(); +#else +// here is the fast release version +#define g_blend_func blend_mmx +#endif + +#else + +extern Uint8 *g_blend_line1; +extern Uint8 *g_blend_line2; +extern Uint8 *g_blend_dest; +extern Uint32 g_blend_iterations; +#define g_blend_func blend_c +#endif // USE_MMX + +///////////////////////////// + +#endif diff --git a/video/blend_mmx-gas.s b/video/blend_mmx-gas.s new file mode 100644 index 000000000..3629de599 --- /dev/null +++ b/video/blend_mmx-gas.s @@ -0,0 +1,89 @@ +# MMX BLEND function +# by Matt Ownby - Feb 10th, 2004 +# For GNU Assembler + +.data + +.globl _asm_line1 +_asm_line1: + .space 8 + +.globl _asm_line2 +_asm_line2: + .space 8 + +.globl _asm_dest +_asm_dest: + .space 8 + +.globl _asm_iterations +_asm_iterations: + .space 4 + +#################################### + +.text + +.globl _blend_mmx +_blend_mmx: + + push %ebp # needs to be preserved + push %esi # points to asm_line2 + push %ebx # # of iterations we are to do + push %ecx # # of iterations we have done + push %edx # points to asm_line1 + # eax points to asm_dest, but eax doesn't need to be preserved because + # it is assumed to hold the return value + + #################### + + movl _asm_iterations, %ebx + xorl %ecx, %ecx + pxor %mm7, %mm7 + pxor %mm6, %mm6 + movl _asm_line1, %edx + movl _asm_line2, %esi + movl _asm_dest, %eax + +MainLoop: + movq (%edx,%ecx), %mm0 # load 8 bytes from asm_line1 + movq %mm0, %mm2 + + punpcklbw %mm6, %mm0 # convert to 16-bit, preserve bottom + punpckhbw %mm7, %mm2 # convert to 16-bit, preserve top + + movq (%esi,%ecx), %mm1 # load 8 bytes from asm_line2 + movq %mm1, %mm3 + + punpcklbw %mm6, %mm1 # convert to 16-bit, preserve bottom + punpckhbw %mm7, %mm3 # convert to 16-bit, preserve top + + # add bytes together with each other + paddw %mm1, %mm0 + paddw %mm3, %mm2 + + # divide results by 2 (average together) + psrlw $1, %mm0 + psrlw $1, %mm2 + + packuswb %mm2, %mm0 # merge unpacked 16-bit words into 8 packed bytes + movq %mm0, (%eax, %ecx) # store final result back to system memory + + add $8, %ecx # advance index over the 8 bytes we've just handled + cmp %ebx, %ecx # is our current index less than the total iterations ? + + jl MainLoop # if we have more iterations to do, then loop + + ##################### + + emms + + pop %edx + pop %ecx + pop %ebx + pop %esi + pop %ebp + + ret + +#################################################### diff --git a/video/blend_mmx-masm.asm b/video/blend_mmx-masm.asm new file mode 100644 index 000000000..8fd724817 --- /dev/null +++ b/video/blend_mmx-masm.asm @@ -0,0 +1,97 @@ +; MMX BLEND function +; by Matt Ownby +; For MASM (Microschlop) only + +.486 +.MMX + +.model flat, c + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.DATA + +ALIGN 8 + +PUBLIC asm_line1 +asm_line1 dq 0 + +PUBLIC asm_line2 +asm_line2 dq 0 + +PUBLIC asm_dest +asm_dest dq 0 + +PUBLIC asm_iterations +asm_iterations dd 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.CODE + +PUBLIC blend_mmx +blend_mmx PROC NEAR + + push ebp ; needs to be preserved + push esi ; points to asm_line2 + push ebx ; # of iterations we are to do + push ecx ; # of iterations we have done + push edx ; points to asm_line1 + ; eax points to asm_dest, but eax doesn't need to be preserved because + ; it is assumed to hold the return value + + ;;;;;;;;;;;;;;;;;;;; + + mov ebx, asm_iterations + xor ecx, ecx + pxor mm7, mm7 + pxor mm6, mm6 + mov edx, dword ptr[asm_line1] + mov esi, dword ptr[asm_line2] + mov eax, dword ptr[asm_dest] + +MainLoop: + movq mm0, [edx+ecx] ; load 8 bytes from asm_line1 + movq mm2, mm0 + + punpcklbw mm0, mm6 ; convert to 16-bit, preserve bottom + punpckhbw mm2, mm7 ; convert to 16-bit, preserve top + + movq mm1, [esi+ecx] ; load 8 bytes from asm_line2 + movq mm3, mm1 + + punpcklbw mm1, mm6 ; convert to 16-bit, preserve bottom + punpckhbw mm3, mm7 ; convert to 16-bit, preserve top + + ; add bytes together with each other + paddw mm0, mm1 + paddw mm2, mm3 + + ; divide results by 2 (average together) + psrlw mm0, 1 + psrlw mm2, 1 + + packuswb mm0, mm2 ; merge unpacked 16-bit words into 8 packed bytes + movq [eax+ecx], mm0 ; store final result back to system memory + + add ecx, 8 ; advance index over the 8 bytes we've just handled + cmp ecx, ebx ; is our current index less than the total iterations ? + + jl MainLoop ; if we have more iterations to do, then loop + + ;;;;;;;;;;;;;;;;;;;;; + + emms + + pop edx + pop ecx + pop ebx + pop esi + pop ebp + + ret +blend_mmx ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +END \ No newline at end of file diff --git a/video/palette.cpp b/video/palette.cpp new file mode 100644 index 000000000..f9262275d --- /dev/null +++ b/video/palette.cpp @@ -0,0 +1,219 @@ +/* + * palette.cpp + * + * Copyright (C) 2002 Mark Broadhead + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include "../game/game.h" +#include "../io/conout.h" // for printline +#include "palette.h" +#include "rgb2yuv.h" +#include "../video/video.h" +#include "../ldp-out/ldp-vldp-gl.h" // for palette changing + +#ifdef DEBUG +#include +#endif + +unsigned int g_palette_size = 0; +SDL_Color *g_rgb_palette = NULL; + +// color palette lookup table (to make OpenGL texture conversions faster) +Uint32 g_uRGBAPalette[256]; + +t_yuv_color *g_yuv_palette = NULL; + +bool g_palette_modified = true; + +// call this function once to set size of game palette +bool palette_initialize (unsigned int num_colors) +{ + bool result = true; + + g_palette_size = num_colors; + // we can only have 256 max since all our surfaces are 8-bit + /* + if (num_colors > 256) + { + printline("palette_initialize error: Too many colors > 256!"); + result = false; + } +*/ + if (result) + { + g_rgb_palette = new SDL_Color[num_colors]; + g_yuv_palette = new t_yuv_color[num_colors]; + } + + if (!((g_rgb_palette) && (g_yuv_palette) + )) + { + printline("palette_initialize error: Could not allocate palette arrays!"); + palette_shutdown(); + result = false; + } + else + { + // set all colors to unmodified and black + for (unsigned int x = 0; x < g_palette_size; x++) + { + // set RGB values to black + g_rgb_palette[x].r = g_rgb_palette[x].g = g_rgb_palette[x].b = 0; + + g_uRGBAPalette[x] = 0xFF000000; // initialize to opaque black + + // set YUV values to black + g_yuv_palette[x].y = 0; + g_yuv_palette[x].u = g_yuv_palette[x].v = 0x7F; + g_yuv_palette[x].transparent = false; + } + + // Default color #0 to be transparent + // Game drivers can change this individually. + palette_set_transparency(0, true); + } + + return result; +} + +void palette_set_transparency(unsigned int uColorIndex, bool transparent) +{ +#ifdef DEBUG + // sanity check + assert(uColorIndex < g_palette_size); +#endif + + g_yuv_palette[uColorIndex].transparent = transparent; + + if (transparent) + { + g_uRGBAPalette[uColorIndex] &= 0x00FFFFFF; // set alpha channel to 0 + } + else + { + g_uRGBAPalette[uColorIndex] |= 0xFF000000; // set alpha channel to FF + } + +#ifdef USE_OPENGL + // TODO : change this to 'g_palette_modified = true' once we're in a better position to test. + // if we're using OpenGL, we need to update the palette texture + if (get_use_opengl()) + { + on_palette_change_gl(); + } +#endif + +} + +// call this function when a color has changed +void palette_set_color (unsigned int color_num, SDL_Color color_value) +{ + +#ifdef DEBUG + assert (color_num < g_palette_size); +#endif + + // make sure the color has really been modified because the RGB2YUV calculations are expensive + if ((g_rgb_palette[color_num].r != color_value.r) || (g_rgb_palette[color_num].g != color_value.g) || (g_rgb_palette[color_num].b != color_value.b)) + { + g_rgb_palette[color_num] = color_value; + g_palette_modified = true; + + // change R,G,B, values, but don't change A + g_uRGBAPalette[color_num] = (g_uRGBAPalette[color_num] & 0xFF000000) | + color_value.r | (color_value.g << 8) | + (color_value.b << 16); + + // MATT : seems to make more sense to calculate the YUV value of the color here + rgb2yuv_input[0] = g_rgb_palette[color_num].r; + rgb2yuv_input[1] = g_rgb_palette[color_num].g; + rgb2yuv_input[2] = g_rgb_palette[color_num].b; + rgb2yuv(); + g_yuv_palette[color_num].y = rgb2yuv_result_y; + g_yuv_palette[color_num].v = rgb2yuv_result_v; + g_yuv_palette[color_num].u = rgb2yuv_result_u; + } + +} + +// call this function right before drawing the current overlay +void palette_finalize() +{ + if (g_palette_modified) + { + // update color palette for all the surfaces that we are using + for (int i = 0;; i++) + { + SDL_Surface *video_overlay = g_game->get_video_overlay(i); + + // if we have a video overlay to set the colors no ... + if (video_overlay) + { + SDL_SetColors(video_overlay, g_rgb_palette, 0, g_palette_size); + } + else + { + break; + } + } + + if (g_game->IsFullScaleEnabled()) + { + SDL_SetColors(g_game->get_scaled_video_overlay(), g_rgb_palette, 0, g_palette_size); + } + +#ifdef USE_OPENGL + // if we're using OpenGL, we need to update the palette texture + if (get_use_opengl()) + { + on_palette_change_gl(); + } +#endif + + } + + g_palette_modified = false; +} + +// call this function on video shutdown +void palette_shutdown (void) +{ + if (g_rgb_palette) + { + delete [] g_rgb_palette; + g_rgb_palette = NULL; + } + if (g_yuv_palette) + { + delete [] g_yuv_palette; + g_yuv_palette = NULL; + } + +} + +// this function is here temporarily while the game drivers are switch to this new method +t_yuv_color *get_yuv_palette(void) +{ + return g_yuv_palette; +} + +Uint32 *get_rgba_palette(void) +{ + return g_uRGBAPalette; +} diff --git a/video/palette.h b/video/palette.h new file mode 100644 index 000000000..fe935f53e --- /dev/null +++ b/video/palette.h @@ -0,0 +1,47 @@ +/* + * palette.h + * + * Copyright (C) 2002 Mark Broadhead + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +typedef struct +{ + Uint8 y; + Uint8 v; + Uint8 u; + bool transparent; +} t_yuv_color; + +// Among other things, sets color #0 to be transparent. You can change this +// by calling palette_set_transparency. +bool palette_initialize (unsigned int num_colors); + +//void palette_set_transparent_color (SDL_Color color_value); +//void palette_set_transparent_number(int color_number); + +// sets whether a color (from 0-255) is transparent or not. +// The default is for color #0 to be transparent, and this will be +// set in palette_initialize. +void palette_set_transparency(unsigned int uColorIndex, bool transparent); + +void palette_set_color (unsigned int color_num, SDL_Color color_value); +void palette_finalize (); +void palette_shutdown (void); +t_yuv_color *get_yuv_palette(void); +Uint32 *get_rgba_palette(void); diff --git a/video/rgb2yuv-gas.s b/video/rgb2yuv-gas.s new file mode 100644 index 000000000..1ef7c5d44 --- /dev/null +++ b/video/rgb2yuv-gas.s @@ -0,0 +1,141 @@ +# MMX RGB2YUV conversion function +# by Matt Ownby +# For GAS (GNU Assembler) + +# This function is equivalent to this C code from Intel: +# +# Y = (unsigned char) (((9798*R)+(19235*G)+(3736*B))/32768); +# U = (unsigned char) ((((-5537*R)+(-10878*G)+(16384*B))/32768) + 128); +# V = (unsigned char) ((((16384*R)+(-13729*G)+(-2664*B))/32768) + 128); + +################################################################################ + +# C function prototype is: + +# extern "C" void asm_rgb2yuv(); + +# This function is controlled through global variables (because I found that to be the fastest). +# To set the RGB values that you want converted, you write three 8-bit values (R, G, and B) to +# an array of 16-bit shorts (I found this to be the fastest). +# As far as you're concerned, the array you write to looks like this: +# +# extern "C" unsigned short asm_rgb2yuv_input[3]; +# +# (it actually is 64-bits but the last element is ignored) +# +# Here's some example C code to set your input: +# +# unsigned char rgb[3] = { 255, 0, 0 }; // a red color for example (notice it's 8-bit!!) +# asm_rgb2yuv_input[0] = rgb[0]; +# asm_rgb2yuv_input[1] = rgb[1]; +# asm_rgb2yuv_input[2] = rgb[2]; +# asm_rgb2yuv(); // do the calculation here +# +# OK after you've done your calculation, the 8-bit YUV results will be written to three global +# variables: +# +# extern "C" unsigned char asm_rgb2yuv_result_y; +# extern "C" unsigned char asm_rgb2yuv_result_u; +# extern "C" unsigned char asm_rgb2yuv_result_v; +# +# NOTE : these are actually 64-bits in size, but only the first byte matters. +# Also, you might want to change these to unsigned int for better cpu efficiency. +# I made them unsigned char to illustrate that they were 8-bit results. +# +# So to continue my C program example, you might do something like this +# +# printf("The results of that conversion are Y: %u, U: %u, V: %u\n", +# asm_rgb2yuv_result_y, asm_rgb2yuv_result_u, asm_rgb2yuv_result_v); +# +# I hope this all makes sense. Good luck! +# --Matt +# +# PS : This is my first attempt at MMX programming so if it is lousy, sorry :) + +.data + +the_offset: + .long 128 + .long 128 + +ystuff_q: + .word 9798 + .word 19235 + .word 3736 + .word 0 + +ustuff_q: + .word -5537 + .word -10878 + .word 16384 + .word 0 + +vstuff_q: + .word 16384 + .word -13729 + .word -2664 + .word 0 + +.globl _asm_rgb2yuv_input +_asm_rgb2yuv_input: + .space 8 + +.globl _asm_rgb2yuv_result_y +_asm_rgb2yuv_result_y: + .space 8 + +.globl _asm_rgb2yuv_result_u +_asm_rgb2yuv_result_u: + .space 8 + +.globl _asm_rgb2yuv_result_v +_asm_rgb2yuv_result_v: + .space 8 + + +.text + +.globl _asm_rgb2yuv +_asm_rgb2yuv: + + pushl %ebp + + movq _asm_rgb2yuv_input,%mm1 + movq the_offset,%mm7 + + # Calculate Y + movq ystuff_q,%mm0 + pmaddwd %mm1,%mm0 + movq %mm0,%mm2 + psrlq $32,%mm2 + paddd %mm2,%mm0 + psrad $15,%mm0 # divide by 32768 + movq %mm0, _asm_rgb2yuv_result_y + + # Calculate U + movq ustuff_q,%mm0 + pmaddwd %mm1,%mm0 + movq %mm0,%mm2 + psrlq $32,%mm2 + paddd %mm2,%mm0 + psrad $15,%mm0 # divide by 32768 + paddd %mm7,%mm0 # add 128 + movq %mm0, _asm_rgb2yuv_result_u + + # Calculate V + movq vstuff_q,%mm0 + pmaddwd %mm1,%mm0 + movq %mm0,%mm2 + psrlq $32,%mm2 + paddd %mm2,%mm0 + psrad $15,%mm0 # divide by 32768 + paddd %mm7,%mm0 # add 128 + movq %mm0, _asm_rgb2yuv_result_v + + ##################### + + emms + + popl %ebp + + ret diff --git a/video/rgb2yuv-masm.asm b/video/rgb2yuv-masm.asm new file mode 100644 index 000000000..8edb3371d --- /dev/null +++ b/video/rgb2yuv-masm.asm @@ -0,0 +1,130 @@ +; MMX RGB2YUV conversion function +; by Matt Ownby +; For MASM (Microschlop) only + +; This function is equivalent to this C code from Intel: +; +; Y = (unsigned char) (((9798*R)+(19235*G)+(3736*B))/32768); +; U = (unsigned char) ((((-5537*R)+(-10878*G)+(16384*B))/32768) + 128); +; V = (unsigned char) ((((16384*R)+(-13729*G)+(-2664*B))/32768) + 128); + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; C function prototype is: + +; extern "C" void asm_rgb2yuv(); + +; This function is controlled through global variables (because I found that to be the fastest). +; To set the RGB values that you want converted, you write three 8-bit values (R, G, and B) to +; an array of 16-bit shorts (I found this to be the fastest). +; As far as you're concerned, the array you write to looks like this: +; +; extern "C" unsigned short asm_rgb2yuv_input[3]; +; +; (it actually is 64-bits but the last element is ignored) +; +; Here's some example C code to set your input: +; +; unsigned char rgb[3] = { 255, 0, 0 }; // a red color for example (notice it's 8-bit!!) +; asm_rgb2yuv_input[0] = rgb[0]; +; asm_rgb2yuv_input[1] = rgb[1]; +; asm_rgb2yuv_input[2] = rgb[2]; +; asm_rgb2yuv(); // do the calculation here +; +; OK after you've done your calculation, the 8-bit YUV results will be written to three global +; variables: +; +; extern "C" unsigned char asm_rgb2yuv_result_y; +; extern "C" unsigned char asm_rgb2yuv_result_u; +; extern "C" unsigned char asm_rgb2yuv_result_v; +; +; NOTE : these are actually 64-bits in size, but only the first byte matters. +; Also, you might want to change these to unsigned int for better cpu efficiency. +; I made them unsigned char to illustrate that they were 8-bit results. +; +; So to continue my C program example, you might do something like this +; +; printf("The results of that conversion are Y: %u, U: %u, V: %u\n", +; asm_rgb2yuv_result_y, asm_rgb2yuv_result_u, asm_rgb2yuv_result_v); +; +; I hope this all makes sense. Good luck! +; --Matt +; +; PS : This is my first attempt at MMX programming so if it is lousy, sorry :) + +.486 +.MMX + +.model flat, c + +.DATA + +ALIGN 8 + +the_offset dq 0000008000000080h +ystuff_q dq 00000E984B232646h ; 9798, 19235, and 3736 from the equation +ustuff_q dq 00004000D582EA5Fh ; -5537, -10878, and 16384 from the equation +vstuff_q dq 0000F598CA5F4000h ; 16384, -13729, and -2664 from the equation + +PUBLIC asm_rgb2yuv_input +asm_rgb2yuv_input dq 0 + +PUBLIC asm_rgb2yuv_result_y +asm_rgb2yuv_result_y dq 0 + +PUBLIC asm_rgb2yuv_result_u +asm_rgb2yuv_result_u dq 0 + +PUBLIC asm_rgb2yuv_result_v +asm_rgb2yuv_result_v dq 0 + +.CODE + +PUBLIC asm_rgb2yuv +asm_rgb2yuv PROC NEAR + + push ebp ; required to preserve ebp, I'm not sure where exactly it gets changed + + ;;;;;;;;;;;;;;;;;;;; + + movq mm1, asm_rgb2yuv_input + movq mm7, the_offset + + ; Calculate Y + movq mm0, ystuff_q + pmaddwd mm0, mm1 + movq mm2, mm0 + psrlq mm2, 32 + paddd mm0, mm2 + psrad mm0, 15 ; divide by 32768 + movq asm_rgb2yuv_result_y, mm0 + + ; Calculate U + movq mm0, ustuff_q + pmaddwd mm0, mm1 + movq mm2, mm0 + psrlq mm2, 32 + paddd mm0, mm2 + psrad mm0, 15 ; divide by 32768 + paddd mm0, mm7 ; add 128 + movq asm_rgb2yuv_result_u, mm0 + + ; Calculate V + movq mm0, vstuff_q + pmaddwd mm0, mm1 + movq mm2, mm0 + psrlq mm2, 32 + paddd mm0, mm2 + psrad mm0, 15 ; divide by 32768 + paddd mm0, mm7 ; add 128 + movq asm_rgb2yuv_result_v, mm0 + + ;;;;;;;;;;;;;;;;;;;;; + + emms + + pop ebp + + ret +asm_rgb2yuv ENDP +END diff --git a/video/rgb2yuv.cpp b/video/rgb2yuv.cpp new file mode 100644 index 000000000..cea3ca25f --- /dev/null +++ b/video/rgb2yuv.cpp @@ -0,0 +1,302 @@ +/* + * rgb2yuv.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +#include "rgb2yuv.h" + +// if we aren't using the assembly version, then use the C version instead +#ifndef USE_MMX + +// these are int's so they are the optimal size for the CPU to work with +unsigned int rgb2yuv_input[3] = { 0 }; // 8-bit values +unsigned int rgb2yuv_result_y = 0; // 8-bit +unsigned int rgb2yuv_result_u = 0; // 8-bit +unsigned int rgb2yuv_result_v = 0; // 8-bit + +#define R rgb2yuv_input[0] +#define G rgb2yuv_input[1] +#define B rgb2yuv_input[2] + +#define Y rgb2yuv_result_y +#define U rgb2yuv_result_u +#define V rgb2yuv_result_v + +static const long mul_3736[256]={ + 0, 3736, 7472, 11208, 14944, 18680, 22416, 26152, + 29888, 33624, 37360, 41096, 44832, 48568, 52304, 56040, + 59776, 63512, 67248, 70984, 74720, 78456, 82192, 85928, + 89664, 93400, 97136, 100872, 104608, 108344, 112080, 115816, + 119552, 123288, 127024, 130760, 134496, 138232, 141968, 145704, + 149440, 153176, 156912, 160648, 164384, 168120, 171856, 175592, + 179328, 183064, 186800, 190536, 194272, 198008, 201744, 205480, + 209216, 212952, 216688, 220424, 224160, 227896, 231632, 235368, + 239104, 242840, 246576, 250312, 254048, 257784, 261520, 265256, + 268992, 272728, 276464, 280200, 283936, 287672, 291408, 295144, + 298880, 302616, 306352, 310088, 313824, 317560, 321296, 325032, + 328768, 332504, 336240, 339976, 343712, 347448, 351184, 354920, + 358656, 362392, 366128, 369864, 373600, 377336, 381072, 384808, + 388544, 392280, 396016, 399752, 403488, 407224, 410960, 414696, + 418432, 422168, 425904, 429640, 433376, 437112, 440848, 444584, + 448320, 452056, 455792, 459528, 463264, 467000, 470736, 474472, + 478208, 481944, 485680, 489416, 493152, 496888, 500624, 504360, + 508096, 511832, 515568, 519304, 523040, 526776, 530512, 534248, + 537984, 541720, 545456, 549192, 552928, 556664, 560400, 564136, + 567872, 571608, 575344, 579080, 582816, 586552, 590288, 594024, + 597760, 601496, 605232, 608968, 612704, 616440, 620176, 623912, + 627648, 631384, 635120, 638856, 642592, 646328, 650064, 653800, + 657536, 661272, 665008, 668744, 672480, 676216, 679952, 683688, + 687424, 691160, 694896, 698632, 702368, 706104, 709840, 713576, + 717312, 721048, 724784, 728520, 732256, 735992, 739728, 743464, + 747200, 750936, 754672, 758408, 762144, 765880, 769616, 773352, + 777088, 780824, 784560, 788296, 792032, 795768, 799504, 803240, + 806976, 810712, 814448, 818184, 821920, 825656, 829392, 833128, + 836864, 840600, 844336, 848072, 851808, 855544, 859280, 863016, + 866752, 870488, 874224, 877960, 881696, 885432, 889168, 892904, + 896640, 900376, 904112, 907848, 911584, 915320, 919056, 922792, + 926528, 930264, 934000, 937736, 941472, 945208, 948944, 952680 + }; + +static const long mul_9798[256]={ + 0, 9798, 19596, 29394, 39192, 48990, 58788, 68586, + 78384, 88182, 97980, 107778, 117576, 127374, 137172, 146970, + 156768, 166566, 176364, 186162, 195960, 205758, 215556, 225354, + 235152, 244950, 254748, 264546, 274344, 284142, 293940, 303738, + 313536, 323334, 333132, 342930, 352728, 362526, 372324, 382122, + 391920, 401718, 411516, 421314, 431112, 440910, 450708, 460506, + 470304, 480102, 489900, 499698, 509496, 519294, 529092, 538890, + 548688, 558486, 568284, 578082, 587880, 597678, 607476, 617274, + 627072, 636870, 646668, 656466, 666264, 676062, 685860, 695658, + 705456, 715254, 725052, 734850, 744648, 754446, 764244, 774042, + 783840, 793638, 803436, 813234, 823032, 832830, 842628, 852426, + 862224, 872022, 881820, 891618, 901416, 911214, 921012, 930810, + 940608, 950406, 960204, 970002, 979800, 989598, 999396, 1009194, + 1018992, 1028790, 1038588, 1048386, 1058184, 1067982, 1077780, 1087578, + 1097376, 1107174, 1116972, 1126770, 1136568, 1146366, 1156164, 1165962, + 1175760, 1185558, 1195356, 1205154, 1214952, 1224750, 1234548, 1244346, + 1254144, 1263942, 1273740, 1283538, 1293336, 1303134, 1312932, 1322730, + 1332528, 1342326, 1352124, 1361922, 1371720, 1381518, 1391316, 1401114, + 1410912, 1420710, 1430508, 1440306, 1450104, 1459902, 1469700, 1479498, + 1489296, 1499094, 1508892, 1518690, 1528488, 1538286, 1548084, 1557882, + 1567680, 1577478, 1587276, 1597074, 1606872, 1616670, 1626468, 1636266, + 1646064, 1655862, 1665660, 1675458, 1685256, 1695054, 1704852, 1714650, + 1724448, 1734246, 1744044, 1753842, 1763640, 1773438, 1783236, 1793034, + 1802832, 1812630, 1822428, 1832226, 1842024, 1851822, 1861620, 1871418, + 1881216, 1891014, 1900812, 1910610, 1920408, 1930206, 1940004, 1949802, + 1959600, 1969398, 1979196, 1988994, 1998792, 2008590, 2018388, 2028186, + 2037984, 2047782, 2057580, 2067378, 2077176, 2086974, 2096772, 2106570, + 2116368, 2126166, 2135964, 2145762, 2155560, 2165358, 2175156, 2184954, + 2194752, 2204550, 2214348, 2224146, 2233944, 2243742, 2253540, 2263338, + 2273136, 2282934, 2292732, 2302530, 2312328, 2322126, 2331924, 2341722, + 2351520, 2361318, 2371116, 2380914, 2390712, 2400510, 2410308, 2420106, + 2429904, 2439702, 2449500, 2459298, 2469096, 2478894, 2488692, 2498490, +}; + +static const long mul_19235[256]={ + 0, 19235, 38470, 57705, 76940, 96175, 115410, 134645, + 153880, 173115, 192350, 211585, 230820, 250055, 269290, 288525, + 307760, 326995, 346230, 365465, 384700, 403935, 423170, 442405, + 461640, 480875, 500110, 519345, 538580, 557815, 577050, 596285, + 615520, 634755, 653990, 673225, 692460, 711695, 730930, 750165, + 769400, 788635, 807870, 827105, 846340, 865575, 884810, 904045, + 923280, 942515, 961750, 980985, 1000220, 1019455, 1038690, 1057925, + 1077160, 1096395, 1115630, 1134865, 1154100, 1173335, 1192570, 1211805, + 1231040, 1250275, 1269510, 1288745, 1307980, 1327215, 1346450, 1365685, + 1384920, 1404155, 1423390, 1442625, 1461860, 1481095, 1500330, 1519565, + 1538800, 1558035, 1577270, 1596505, 1615740, 1634975, 1654210, 1673445, + 1692680, 1711915, 1731150, 1750385, 1769620, 1788855, 1808090, 1827325, + 1846560, 1865795, 1885030, 1904265, 1923500, 1942735, 1961970, 1981205, + 2000440, 2019675, 2038910, 2058145, 2077380, 2096615, 2115850, 2135085, + 2154320, 2173555, 2192790, 2212025, 2231260, 2250495, 2269730, 2288965, + 2308200, 2327435, 2346670, 2365905, 2385140, 2404375, 2423610, 2442845, + 2462080, 2481315, 2500550, 2519785, 2539020, 2558255, 2577490, 2596725, + 2615960, 2635195, 2654430, 2673665, 2692900, 2712135, 2731370, 2750605, + 2769840, 2789075, 2808310, 2827545, 2846780, 2866015, 2885250, 2904485, + 2923720, 2942955, 2962190, 2981425, 3000660, 3019895, 3039130, 3058365, + 3077600, 3096835, 3116070, 3135305, 3154540, 3173775, 3193010, 3212245, + 3231480, 3250715, 3269950, 3289185, 3308420, 3327655, 3346890, 3366125, + 3385360, 3404595, 3423830, 3443065, 3462300, 3481535, 3500770, 3520005, + 3539240, 3558475, 3577710, 3596945, 3616180, 3635415, 3654650, 3673885, + 3693120, 3712355, 3731590, 3750825, 3770060, 3789295, 3808530, 3827765, + 3847000, 3866235, 3885470, 3904705, 3923940, 3943175, 3962410, 3981645, + 4000880, 4020115, 4039350, 4058585, 4077820, 4097055, 4116290, 4135525, + 4154760, 4173995, 4193230, 4212465, 4231700, 4250935, 4270170, 4289405, + 4308640, 4327875, 4347110, 4366345, 4385580, 4404815, 4424050, 4443285, + 4462520, 4481755, 4500990, 4520225, 4539460, 4558695, 4577930, 4597165, + 4616400, 4635635, 4654870, 4674105, 4693340, 4712575, 4731810, 4751045, + 4770280, 4789515, 4808750, 4827985, 4847220, 4866455, 4885690, 4904925, +}; + + +static const long mul_18514[512]={ + -4739584, -4721070, -4702556, -4684042, -4665528, -4647014, -4628500, -4609986, + -4591472, -4572958, -4554444, -4535930, -4517416, -4498902, -4480388, -4461874, + -4443360, -4424846, -4406332, -4387818, -4369304, -4350790, -4332276, -4313762, + -4295248, -4276734, -4258220, -4239706, -4221192, -4202678, -4184164, -4165650, + -4147136, -4128622, -4110108, -4091594, -4073080, -4054566, -4036052, -4017538, + -3999024, -3980510, -3961996, -3943482, -3924968, -3906454, -3887940, -3869426, + -3850912, -3832398, -3813884, -3795370, -3776856, -3758342, -3739828, -3721314, + -3702800, -3684286, -3665772, -3647258, -3628744, -3610230, -3591716, -3573202, + -3554688, -3536174, -3517660, -3499146, -3480632, -3462118, -3443604, -3425090, + -3406576, -3388062, -3369548, -3351034, -3332520, -3314006, -3295492, -3276978, + -3258464, -3239950, -3221436, -3202922, -3184408, -3165894, -3147380, -3128866, + -3110352, -3091838, -3073324, -3054810, -3036296, -3017782, -2999268, -2980754, + -2962240, -2943726, -2925212, -2906698, -2888184, -2869670, -2851156, -2832642, + -2814128, -2795614, -2777100, -2758586, -2740072, -2721558, -2703044, -2684530, + -2666016, -2647502, -2628988, -2610474, -2591960, -2573446, -2554932, -2536418, + -2517904, -2499390, -2480876, -2462362, -2443848, -2425334, -2406820, -2388306, + -2369792, -2351278, -2332764, -2314250, -2295736, -2277222, -2258708, -2240194, + -2221680, -2203166, -2184652, -2166138, -2147624, -2129110, -2110596, -2092082, + -2073568, -2055054, -2036540, -2018026, -1999512, -1980998, -1962484, -1943970, + -1925456, -1906942, -1888428, -1869914, -1851400, -1832886, -1814372, -1795858, + -1777344, -1758830, -1740316, -1721802, -1703288, -1684774, -1666260, -1647746, + -1629232, -1610718, -1592204, -1573690, -1555176, -1536662, -1518148, -1499634, + -1481120, -1462606, -1444092, -1425578, -1407064, -1388550, -1370036, -1351522, + -1333008, -1314494, -1295980, -1277466, -1258952, -1240438, -1221924, -1203410, + -1184896, -1166382, -1147868, -1129354, -1110840, -1092326, -1073812, -1055298, + -1036784, -1018270, -999756, -981242, -962728, -944214, -925700, -907186, + -888672, -870158, -851644, -833130, -814616, -796102, -777588, -759074, + -740560, -722046, -703532, -685018, -666504, -647990, -629476, -610962, + -592448, -573934, -555420, -536906, -518392, -499878, -481364, -462850, + -444336, -425822, -407308, -388794, -370280, -351766, -333252, -314738, + -296224, -277710, -259196, -240682, -222168, -203654, -185140, -166626, + -148112, -129598, -111084, -92570, -74056, -55542, -37028, -18514, + 0, 18514, 37028, 55542, 74056, 92570, 111084, 129598, + 148112, 166626, 185140, 203654, 222168, 240682, 259196, 277710, + 296224, 314738, 333252, 351766, 370280, 388794, 407308, 425822, + 444336, 462850, 481364, 499878, 518392, 536906, 555420, 573934, + 592448, 610962, 629476, 647990, 666504, 685018, 703532, 722046, + 740560, 759074, 777588, 796102, 814616, 833130, 851644, 870158, + 888672, 907186, 925700, 944214, 962728, 981242, 999756, 1018270, + 1036784, 1055298, 1073812, 1092326, 1110840, 1129354, 1147868, 1166382, + 1184896, 1203410, 1221924, 1240438, 1258952, 1277466, 1295980, 1314494, + 1333008, 1351522, 1370036, 1388550, 1407064, 1425578, 1444092, 1462606, + 1481120, 1499634, 1518148, 1536662, 1555176, 1573690, 1592204, 1610718, + 1629232, 1647746, 1666260, 1684774, 1703288, 1721802, 1740316, 1758830, + 1777344, 1795858, 1814372, 1832886, 1851400, 1869914, 1888428, 1906942, + 1925456, 1943970, 1962484, 1980998, 1999512, 2018026, 2036540, 2055054, + 2073568, 2092082, 2110596, 2129110, 2147624, 2166138, 2184652, 2203166, + 2221680, 2240194, 2258708, 2277222, 2295736, 2314250, 2332764, 2351278, + 2369792, 2388306, 2406820, 2425334, 2443848, 2462362, 2480876, 2499390, + 2517904, 2536418, 2554932, 2573446, 2591960, 2610474, 2628988, 2647502, + 2666016, 2684530, 2703044, 2721558, 2740072, 2758586, 2777100, 2795614, + 2814128, 2832642, 2851156, 2869670, 2888184, 2906698, 2925212, 2943726, + 2962240, 2980754, 2999268, 3017782, 3036296, 3054810, 3073324, 3091838, + 3110352, 3128866, 3147380, 3165894, 3184408, 3202922, 3221436, 3239950, + 3258464, 3276978, 3295492, 3314006, 3332520, 3351034, 3369548, 3388062, + 3406576, 3425090, 3443604, 3462118, 3480632, 3499146, 3517660, 3536174, + 3554688, 3573202, 3591716, 3610230, 3628744, 3647258, 3665772, 3684286, + 3702800, 3721314, 3739828, 3758342, 3776856, 3795370, 3813884, 3832398, + 3850912, 3869426, 3887940, 3906454, 3924968, 3943482, 3961996, 3980510, + 3999024, 4017538, 4036052, 4054566, 4073080, 4091594, 4110108, 4128622, + 4147136, 4165650, 4184164, 4202678, 4221192, 4239706, 4258220, 4276734, + 4295248, 4313762, 4332276, 4350790, 4369304, 4387818, 4406332, 4424846, + 4443360, 4461874, 4480388, 4498902, 4517416, 4535930, 4554444, 4572958, + 4591472, 4609986, 4628500, 4647014, 4665528, 4684042, 4702556, 4721070 +}; + +static const long mul_23364[512]={ + -5981184, -5957820, -5934456, -5911092, -5887728, -5864364, -5841000, -5817636, + -5794272, -5770908, -5747544, -5724180, -5700816, -5677452, -5654088, -5630724, + -5607360, -5583996, -5560632, -5537268, -5513904, -5490540, -5467176, -5443812, + -5420448, -5397084, -5373720, -5350356, -5326992, -5303628, -5280264, -5256900, + -5233536, -5210172, -5186808, -5163444, -5140080, -5116716, -5093352, -5069988, + -5046624, -5023260, -4999896, -4976532, -4953168, -4929804, -4906440, -4883076, + -4859712, -4836348, -4812984, -4789620, -4766256, -4742892, -4719528, -4696164, + -4672800, -4649436, -4626072, -4602708, -4579344, -4555980, -4532616, -4509252, + -4485888, -4462524, -4439160, -4415796, -4392432, -4369068, -4345704, -4322340, + -4298976, -4275612, -4252248, -4228884, -4205520, -4182156, -4158792, -4135428, + -4112064, -4088700, -4065336, -4041972, -4018608, -3995244, -3971880, -3948516, + -3925152, -3901788, -3878424, -3855060, -3831696, -3808332, -3784968, -3761604, + -3738240, -3714876, -3691512, -3668148, -3644784, -3621420, -3598056, -3574692, + -3551328, -3527964, -3504600, -3481236, -3457872, -3434508, -3411144, -3387780, + -3364416, -3341052, -3317688, -3294324, -3270960, -3247596, -3224232, -3200868, + -3177504, -3154140, -3130776, -3107412, -3084048, -3060684, -3037320, -3013956, + -2990592, -2967228, -2943864, -2920500, -2897136, -2873772, -2850408, -2827044, + -2803680, -2780316, -2756952, -2733588, -2710224, -2686860, -2663496, -2640132, + -2616768, -2593404, -2570040, -2546676, -2523312, -2499948, -2476584, -2453220, + -2429856, -2406492, -2383128, -2359764, -2336400, -2313036, -2289672, -2266308, + -2242944, -2219580, -2196216, -2172852, -2149488, -2126124, -2102760, -2079396, + -2056032, -2032668, -2009304, -1985940, -1962576, -1939212, -1915848, -1892484, + -1869120, -1845756, -1822392, -1799028, -1775664, -1752300, -1728936, -1705572, + -1682208, -1658844, -1635480, -1612116, -1588752, -1565388, -1542024, -1518660, + -1495296, -1471932, -1448568, -1425204, -1401840, -1378476, -1355112, -1331748, + -1308384, -1285020, -1261656, -1238292, -1214928, -1191564, -1168200, -1144836, + -1121472, -1098108, -1074744, -1051380, -1028016, -1004652, -981288, -957924, + -934560, -911196, -887832, -864468, -841104, -817740, -794376, -771012, + -747648, -724284, -700920, -677556, -654192, -630828, -607464, -584100, + -560736, -537372, -514008, -490644, -467280, -443916, -420552, -397188, + -373824, -350460, -327096, -303732, -280368, -257004, -233640, -210276, + -186912, -163548, -140184, -116820, -93456, -70092, -46728, -23364, + 0, 23364, 46728, 70092, 93456, 116820, 140184, 163548, + 186912, 210276, 233640, 257004, 280368, 303732, 327096, 350460, + 373824, 397188, 420552, 443916, 467280, 490644, 514008, 537372, + 560736, 584100, 607464, 630828, 654192, 677556, 700920, 724284, + 747648, 771012, 794376, 817740, 841104, 864468, 887832, 911196, + 934560, 957924, 981288, 1004652, 1028016, 1051380, 1074744, 1098108, + 1121472, 1144836, 1168200, 1191564, 1214928, 1238292, 1261656, 1285020, + 1308384, 1331748, 1355112, 1378476, 1401840, 1425204, 1448568, 1471932, + 1495296, 1518660, 1542024, 1565388, 1588752, 1612116, 1635480, 1658844, + 1682208, 1705572, 1728936, 1752300, 1775664, 1799028, 1822392, 1845756, + 1869120, 1892484, 1915848, 1939212, 1962576, 1985940, 2009304, 2032668, + 2056032, 2079396, 2102760, 2126124, 2149488, 2172852, 2196216, 2219580, + 2242944, 2266308, 2289672, 2313036, 2336400, 2359764, 2383128, 2406492, + 2429856, 2453220, 2476584, 2499948, 2523312, 2546676, 2570040, 2593404, + 2616768, 2640132, 2663496, 2686860, 2710224, 2733588, 2756952, 2780316, + 2803680, 2827044, 2850408, 2873772, 2897136, 2920500, 2943864, 2967228, + 2990592, 3013956, 3037320, 3060684, 3084048, 3107412, 3130776, 3154140, + 3177504, 3200868, 3224232, 3247596, 3270960, 3294324, 3317688, 3341052, + 3364416, 3387780, 3411144, 3434508, 3457872, 3481236, 3504600, 3527964, + 3551328, 3574692, 3598056, 3621420, 3644784, 3668148, 3691512, 3714876, + 3738240, 3761604, 3784968, 3808332, 3831696, 3855060, 3878424, 3901788, + 3925152, 3948516, 3971880, 3995244, 4018608, 4041972, 4065336, 4088700, + 4112064, 4135428, 4158792, 4182156, 4205520, 4228884, 4252248, 4275612, + 4298976, 4322340, 4345704, 4369068, 4392432, 4415796, 4439160, 4462524, + 4485888, 4509252, 4532616, 4555980, 4579344, 4602708, 4626072, 4649436, + 4672800, 4696164, 4719528, 4742892, 4766256, 4789620, 4812984, 4836348, + 4859712, 4883076, 4906440, 4929804, 4953168, 4976532, 4999896, 5023260, + 5046624, 5069988, 5093352, 5116716, 5140080, 5163444, 5186808, 5210172, + 5233536, 5256900, 5280264, 5303628, 5326992, 5350356, 5373720, 5397084, + 5420448, 5443812, 5467176, 5490540, 5513904, 5537268, 5560632, 5583996, + 5607360, 5630724, 5654088, 5677452, 5700816, 5724180, 5747544, 5770908, + 5794272, 5817636, 5841000, 5864364, 5887728, 5911092, 5934456, 5957820 +}; + +// Function contributed by 'Buddabing' +void rgb2yuv() +{ + Y = ((mul_9798[R]+mul_19235[G]+mul_3736[B])>>15); + U = ((mul_18514[B-Y+256]>>15)+128); + V = ((mul_23364[R-Y+256]>>15)+128); +} + + +/* +// a faster, less accurate version of the RGB->YUV conversion formula +// (faster because no floating point is used) +void rgb2yuv() +{ + rgb2yuv_result_y = (unsigned char) (((9798*R) + (19235*G) + (3736*B)) >> 15); + rgb2yuv_result_u = (unsigned char) ((((B-rgb2yuv_result_y)*18514) >> 15) + 128); + rgb2yuv_result_v = (unsigned char) ((((R-rgb2yuv_result_y)*23364) >> 15) + 128); +} +*/ + +#endif // not MMX_RGB2YUV diff --git a/video/rgb2yuv.h b/video/rgb2yuv.h new file mode 100644 index 000000000..b7c916afa --- /dev/null +++ b/video/rgb2yuv.h @@ -0,0 +1,70 @@ +/* + * rgb2yuv.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef RGB2YUV_H +#define RGB2YUV_H + +#ifdef MAC_OSX +#include "mmxdefs.h" +#endif + +#ifdef USE_MMX + +#define rgb2yuv asm_rgb2yuv +#define rgb2yuv_input asm_rgb2yuv_input +#define rgb2yuv_result_y asm_rgb2yuv_result_y +#define rgb2yuv_result_u asm_rgb2yuv_result_u +#define rgb2yuv_result_v asm_rgb2yuv_result_v + +#if defined(MAC_OSX) || defined(WIN32) +extern "C" void asm_rgb2yuv(); +extern "C" unsigned short asm_rgb2yuv_input[3]; // this must be a short due to the way the MMX code is laid out +extern "C" unsigned char asm_rgb2yuv_result_y; +extern "C" unsigned char asm_rgb2yuv_result_u; +extern "C" unsigned char asm_rgb2yuv_result_v; +#else +extern "C" void _asm_rgb2yuv(); +extern "C" unsigned short _asm_rgb2yuv_input[3]; // this must be a short due to the way the MMX code is laid out +extern "C" unsigned char _asm_rgb2yuv_result_y; +extern "C" unsigned char _asm_rgb2yuv_result_u; +extern "C" unsigned char _asm_rgb2yuv_result_v; +#define asm_rgb2yuv _asm_rgb2yuv +#define asm_rgb2yuv_input _asm_rgb2yuv_input +#define asm_rgb2yuv_result_y _asm_rgb2yuv_result_y +#define asm_rgb2yuv_result_u _asm_rgb2yuv_result_u +#define asm_rgb2yuv_result_v _asm_rgb2yuv_result_v +#endif // OSX/WIN32 + +#else + +// the C version of this routine +void rgb2yuv(); +extern unsigned int rgb2yuv_input[3]; // 8-bit +extern unsigned int rgb2yuv_result_y; // 8-bit +extern unsigned int rgb2yuv_result_u; // 8-bit +extern unsigned int rgb2yuv_result_v; // 8-bit + +#endif + +///////////////////////////// + +#endif diff --git a/video/tms9128nl.cpp b/video/tms9128nl.cpp new file mode 100644 index 000000000..948cbc263 --- /dev/null +++ b/video/tms9128nl.cpp @@ -0,0 +1,959 @@ +/* + * tms9128nl.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// undefine this to get rid of debug messages, or 1 to view them +//#define TMS_DEBUG 1 + +#include +#include "SDL_DrawText.h" +#include "tms9128nl.h" +#include "palette.h" +#include "video.h" +#include "../game/game.h" +#include "../io/conout.h" +#include "../ldp-out/ldp.h" // to check to see if blitting is allowed +#include +#include + +static unsigned char g_vidbuf[TMS9128NL_OVERLAY_W * TMS9128NL_OVERLAY_H]; // video buffer needed because we clobber the SDL_Surface buffer when we do real-time scaling +static unsigned char vidmem[32767] = { 0 }; // video memory +static unsigned char lowbyte = 0; +static unsigned char highbyte = 0; +static unsigned int rvidindex; +static unsigned int wvidindex; +static int toggleflag = 0; //keep track of low / high byte +static int g_vidmode = 0; //keep track of video mode +static int viddisp = 1; //enable video display 0=off 1=on +static int vidreg[8] = { 0 }; //registers 0-7 +static int rowdiv = 40; //text mode + +unsigned char g_tms_pnt_addr = 0; // pattern name table address +unsigned char g_tms_ct_addr = 0; // color table address +unsigned char g_tms_pgt_addr = 0; // pattern generation table address +unsigned char g_tms_sat_addr = 0; // sprite attribute table address +unsigned char g_tms_sgt_addr = 0; // sprite generation table address +unsigned char g_tms_foreground_color = 0xF; // white (3 bit) +unsigned char g_tms_background_color = 0; // black (3 bit) + +bool g_tms_interrupt_enabled = false; // whether NMI is on or off + +int g_transparency_enabled = 0; +int g_transparency_latch = 0; + +// BARBADEL: Added +int introHack = 0; +int prevg_vidmode = 0; +void tms9128nl_clear_overlay(); +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +// resets all variables to their initial state +void tms9128nl_reset() +{ + memset(vidmem, 0, sizeof(vidmem)); + lowbyte = 0; + highbyte = 0; + rvidindex = 0; + wvidindex = 0; + toggleflag = 0; + g_vidmode = 0; + viddisp = 1; + memset(vidreg, 0, sizeof(vidreg)); + rowdiv = 40; + g_tms_pnt_addr = 0; + g_tms_ct_addr = 0; + g_tms_pgt_addr = 0; + g_tms_sat_addr = 0; + g_tms_sgt_addr = 0; + g_tms_foreground_color = 0xF; + g_tms_background_color = 0; + g_tms_interrupt_enabled = false; + g_transparency_enabled = 0; + g_transparency_latch = 0; + introHack = 0; + prevg_vidmode = 0; +} + +bool tms9128nl_int_enabled() +{ + return(g_tms_interrupt_enabled); +} + +void tms9128nl_writechar(unsigned char value) +//write a character on the screen, using 40*24 mode emulation +// this is the same as writing to register #0 on a TMS chip +{ + unsigned int row = 0,col = 0; + int base = 0; + + if (viddisp==0) return; //video display is off + //if (g_vidmode!=1) return; //only text mode 1 for now + + // MODE 1 (bitmapped text) + if (g_vidmode == 1) + { + // if the coordinates requested are within the viewable area + if ((wvidindex >= 0) && (wvidindex <= 0x3c0)) + { + base=0; + rowdiv=40; //40*24 + + row = (wvidindex-base-1) / rowdiv; + col = (wvidindex-base-1) % rowdiv; + + if ((col==31) && (rowdiv==32)) return; //problems with col31? or bug in fancyclearscreen routine? + + tms9128nl_drawchar(value, col, row); + } + // else, they're outside the viewable area, so draw nothing + } // end mode 1 + + // MODE 2 (Cliff Hanger graphical logo) + else if (g_vidmode == 2) + { + if ((wvidindex>=0x3c00) && (wvidindex<=0x3f00)) //pattern name table - graphics mode + { + base=0x3c01; + rowdiv=32; //32*24 + + row = (wvidindex-base-1) / rowdiv; + col = (wvidindex-base-1) % rowdiv; + + if ((col==31) && (rowdiv==32)) return; //problems with col31? or bug in fancyclearscreen routine? + + tms9128nl_drawchar(value, col, row); + } + // BARBADEL: Added + else + { + g_tms_foreground_color = (unsigned char) ((value & 0xF0) >> 4); + g_tms_background_color = (unsigned char) (value & 0x0F); + tms9128nl_palette_update(); // MATT + } + } +} //end writechar + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +unsigned char tms9128nl_getvidmem(void) +{ + return vidmem[rvidindex++]; +} + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +void tms9128nl_write_port1(unsigned char value) +//port 54 is the index into video memory. First a low byte is sent, then a highbyte +// this is the same as writing to port #1 for a TMS chip (the same rules apply) +{ + static int tempindex = 0; + +#ifdef TMS_DEBUG + char s[81] = { 0 }; // just a temp string +#endif + + if (toggleflag==0) + { + wvidindex=0; + rvidindex=0; + lowbyte=value; + // printf("lowbyte: %d\n",lowbyte); + } + + // if toggleflag is not zero + else + { + highbyte=value; + + // if bit 7 is set, it means a TMS register is being written to + if (highbyte & 0x80) + { + // AND'ing by 0x7F strips off the high bit, it has nothing to do with TMS_TRANSPARENT_COLOR + int which_reg = highbyte & 0x7F; // the register that is being written to + + vidreg[which_reg] = lowbyte; // set the register in memory in case we need to refer to it later + + // handle register access + switch (which_reg) + { + // register 0 (select screen mode 2 or Black & White) + case 0: + // if only bit 1 is set, it means to go to graphics mode 2 + if (lowbyte & 2) + { + g_vidmode = 2; + if(prevg_vidmode != g_vidmode) // Barbadel: if we're switching video modes, clear the overlay + { +#ifdef TMS_DEBUG + printline("TMS: mode 2"); +#endif + tms9128nl_clear_overlay(); + prevg_vidmode = g_vidmode; + } + } + // if the B&W bit is set, flag an error + if (lowbyte & 1) + { +#ifdef TMS_DEBUG + printline("TMS: B&W bit set, unsupported"); +#endif + } + else + { + #ifdef TMS_DEBUG + printline("TMS : B&W bit cleared"); + #endif + } + break; + + // register 1 (4/16K, blank screen, GINT, mode1, mode3, sprite mode, sprite scale) + case 1: + // if bit 0 is set, MAG + if (lowbyte & 1) + { +#ifdef TMS_DEBUG + printline("TMS: double sprite size not supported"); +#endif + } + + // if bit 1 is set, 16x16 sprites is what we use, else 8x8 + if (lowbyte & 2) + { +#ifdef TMS_DEBUG + printline("TMS: 16x16 sprites requested"); +#endif + } + else + { +#ifdef TMS_DEBUG + //printline("TMS: 8x8 sprites requested"); + // don't print anything since this is what we expect +#endif + } + + // bit 3 set == mode 3 + if (lowbyte & 0x08) + { + g_vidmode=3; + if(prevg_vidmode != g_vidmode) // Barbadel: if we're switching video modes, clear the overlay + { +#ifdef TMS_DEBUG + printline("TMS: mode 3"); +#endif + tms9128nl_clear_overlay(); + prevg_vidmode = g_vidmode; + } + } + // bit 4 set == mode 1 + else if (lowbyte & 0x10) //bit 4 set - text mode 1 + { + g_vidmode=1; + if(prevg_vidmode != g_vidmode) // Barbadel: if we're switching video modes, clear the overlay + { +#ifdef TMS_DEBUG + printline("TMS: mode 1"); +#endif + tms9128nl_clear_overlay(); + prevg_vidmode = g_vidmode; + } + } + // if all vid bits have been cleared, then set g_vidmode to 0 + // we need to check this somewhere, here is as good a place as any I suppose + else if (!(vidreg[0]&0x02)) //no vid bits set + { + g_vidmode=0; + if(prevg_vidmode != g_vidmode) // Barbadel: if we're switching video modes, clear the overlay + { + #ifdef TMS_DEBUG + printline("TMS: g_vidmode 0 special"); + #endif + tms9128nl_clear_overlay(); + prevg_vidmode = g_vidmode; + } + } + // bit 5 set == generate interrupts + if (lowbyte & 0x20) + { + #ifdef TMS_DEBUG + // if they weren't previously enabled + if (!g_tms_interrupt_enabled) + { + printline("TMS: Generate interrupts enabled"); + } + #endif + // don't print anything since this is what we expect + g_tms_interrupt_enabled = 1; + } + else + { + #ifdef TMS_DEBUG + // only notify us if they weren't already disabled + if (g_tms_interrupt_enabled) + { + printline("TMS: Generate interrupts disabled"); + } + #endif + g_tms_interrupt_enabled = 0; + } + + // don't blank screen + if (lowbyte & 0x40) + { + viddisp=1; // enable video display + } + // blank screen, leaving only backdrop + else + { + viddisp=0; // disable video display (blank screen) + + tms9128nl_clear_overlay(); + #ifdef TMS_DEBUG + printline("TMS: VIDEO DISPLAY TO BE BLANKED!"); + #endif + } + + // bit 7 set == select 16K ram, else 4K ram + if (lowbyte & 0x80) + { + #ifdef TMS_DEBUG + // printline("TMS: 16K ram selected"); + #endif + // don't print anything since this is what we expect + } + else + { + #ifdef TMS_DEBUG + printline("TMS: 4k ram selected, unsupported"); + #endif + } + break; + + // register #2 sets address for pattern name table + case 2: + #ifdef TMS_DEBUG + { + unsigned char temp = (unsigned char) (lowbyte & 0xF); // only lowest 4 bits + if (temp != g_tms_pnt_addr) + { + sprintf(s, "TMS: Pattern Name Table Address changed to %x", g_tms_pnt_addr); + printline(s); + } + } + #endif + g_tms_pnt_addr = (unsigned char) (lowbyte & 0xF); // only lowest 4 bits + break; + // register #3 sets address for color table + case 3: + #ifdef TMS_DEBUG + if (lowbyte != g_tms_ct_addr) + { + sprintf(s, "TMS: Color Table Address changed to %x", g_tms_ct_addr); + printline(s); + } + #endif + + g_tms_ct_addr = lowbyte; + break; + + // register #4 sets address for pattern generation table + case 4: + #ifdef TMS_DEBUG + { + unsigned char temp = (unsigned char) (lowbyte & 7); + if (temp != g_tms_pgt_addr) + { + sprintf(s, "TMS: Pattern Generation Table changed to %x", g_tms_pgt_addr); + printline(s); + } + } + #endif + + g_tms_pgt_addr = (unsigned char) (lowbyte & 7); // only lowest 3 bits + break; + + // register #5 sets address for sprite attribute table + case 5: + #ifdef TMS_DEBUG + { + unsigned char temp = (unsigned char) (lowbyte & 0x7F); + if (temp != g_tms_sat_addr) + { + sprintf(s, "TMS: Sprite Attribute Table address changed to %x", g_tms_sat_addr); + printline(s); + } + } + #endif + g_tms_sat_addr = (unsigned char) (lowbyte & 0x7F); // discard high bit + break; + + // register #6 sets address for sprite generation table + case 6: + #ifdef TMS_DEBUG + { + unsigned char temp = (unsigned char) (lowbyte & 0x7); + if (temp != g_tms_sgt_addr) + { + sprintf(s, "TMS: Sprite Generator Table address changed to %x", g_tms_sgt_addr); + printline(s); + } + } + #endif + g_tms_sgt_addr = (unsigned char) (lowbyte & 0x7); // only lowest 3 bits + break; + + // register #7 sets foreground and background colors + case 7: + #ifdef TMS_DEBUG + { + unsigned char t1 = (unsigned char) ((lowbyte & 0xF0) >> 4); + unsigned char t2 = (unsigned char) (lowbyte & 0x0F); + if (t1 != g_tms_foreground_color) + { + sprintf(s, "TMS : Foreground color changed to %x", g_tms_foreground_color); + printline(s); + } + if (t2 != g_tms_background_color) + { + sprintf(s, "TMS : Background color changed to %x", g_tms_background_color); + printline(s); + } + } + #endif + + g_tms_foreground_color = (unsigned char) ((lowbyte & 0xF0) >> 4); + g_tms_background_color = (unsigned char) (lowbyte & 0x0F); + tms9128nl_palette_update(); + break; + + default: + #ifdef TMS_DEBUG + sprintf(s,"TMS: Register %d was written to (unsupported)", which_reg); + printline(s); + #endif + break; + } //end switch + } //end if bit 7 is set (and we're writing to a register) + + // bit 7 is clear so we're not writing to a register + // instead, we are modifying the video memory address + else + { + #ifdef TMS_DEBUG + // NOTE : we don't currently keep track of whether we're in memory read/write mode + // this seems to work fine for now but it may be an issue later + + // if bit 6 is set it means we're in memory write mode + if (highbyte & 0x40) + { + // printline("Memory write mode requested"); + } + // otherwise we're in memory read mode + else + { + printline("Memory read mode requested"); + } + #endif + + highbyte = (unsigned char) (highbyte & 0x3f); //strip top 2 bits + tempindex = (highbyte << 8) | lowbyte; + wvidindex = tempindex; + rvidindex = tempindex; + } //end if high bit not set + } //end if toggleflag is not zero + toggleflag=toggleflag^1; //flip bit 1 +} + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +// writes a byte to port 0 of the TMS chip +void tms9128nl_write_port0(unsigned char Value) +//return a 1 if the screen needs updating +{ + vidmem[wvidindex] = Value; + wvidindex++; // the index always advances when we write + tms9128nl_writechar(Value); // update the screen +} + +void tms9128nl_convert_color(unsigned char color_src, SDL_Color *color) +{ + + char s[81] = { 0 }; + + switch(color_src) + { + case 0: // transparent + color->r = 0; + color->g = 0; + color->b = 0; + break; + case 1: // black + color->r = 0; + color->g = 0; + color->b = 0; + break; + case 2: // medium green; + color->r = 36; + color->g = 219; + color->b = 36; + break; + case 3: // light green + color->r = 109; + color->g = 255; + color->b = 109; + break; + case 4: // dark blue + color->r = 36; + color->g = 36; + color->b = 255; + break; + case 5: // light blue + color->r = 73; + color->g = 109; + color->b = 255; + break; + case 6: // dark red + if (!g_transparency_latch) + { + color->r = 182; + color->g = 36; + color->b = 36; + } + // if we're in transparency mode, the move prompts + else + { + // these colors aren't correct for the TMS chip but they make Cliffy look a bit more + // authentic (the move prompts are more purplish than red) + color->r = 125; + color->g = 0; + color->b = 128; //BARBADEL: 128 makes it more purple than 50 + } + break; + case 7: // light cyan + color->r = 73; + color->g = 219; + color->b = 255; + break; + case 8: // medium red + color->r = 255; + color->g = 36; + color->b = 36; + break; + case 9: // light red + color->r = 255; + color->g = 109; + color->b = 109; + break; + case 10: // dark yellow + color->r = 219; + color->g = 219; + color->b = 36; + break; + case 11: // light yellow + color->r = 219; + color->g = 219; + color->b = 146; + break; + case 12: // dark green + color->r = 36; + color->g = 146; + color->b = 36; + break; + case 13: // magenta + color->r = 219; + color->g = 73; + color->b = 182; + break; + case 14: // grey + color->r = 182; + color->g = 182; + color->b = 182; + break; + case 15: // white + color->r = 255; + color->g = 255; + color->b = 255; + break; + default: + sprintf(s, "UNSUPPORTED COLOR passed into convert color : %d", color_src); + printline(s); + break; + } +} + +// draws a character to the Cliff video display +// 40 columns by 24 rows +// uses Cliffy's video memory to retrieve 8x8 character bitmap +void tms9128nl_drawchar(unsigned char ch, int col, int row) +{ + const int CHAR_WIDTH = 8; + const int CHAR_HEIGHT = 8; + + int bmp_index = (ch * 8) + (g_tms_pgt_addr << 11); // index in vid mem where bmp data is located + int i = 0, j = 0; // temp indices + int x = col * CHAR_WIDTH; + int y = row * CHAR_HEIGHT; + unsigned char line = 0; + unsigned char background_color = TMS_BG_COLOR; + + // if character is 0 and we're in transparency mode, make bitmap transparent + if (g_transparency_latch) + { + static bool latched = false; + + if ((ch == 0) || (ch == 0xFF)) + { + // we need two 0's in a row to make a transparent block + if (!latched) + { + latched = true; + return; + } + else + { + background_color = TMS_TRANSPARENT_COLOR; + } + } + else + { + latched = false; + } + } + + // colors are special in g_vidmode 2, we don't handle them properly yet + if (g_vidmode == 2) + { + // MODIFIED SECTION BY BARBADEL + + if (ch != 255) + { + x += 4; // MATT : even scaled, it is still 1 character off-center. Perhaps it has a 1 character border? + + // major hack : If the row is less than 12 we know it's the Cliff Hanger graphic, hence we hard-code the + // correct values in here. Someone should fix this sometime :) + if (row <= 11) + { + g_tms_foreground_color = 0x5; // Light Blue + g_tms_background_color = 0x1; // Black + tms9128nl_palette_update(); + bmp_index = (ch * 8) + 8*256 * (row > 7); + } + else + { +// MATT : these color hacks don't seem to be necessary anymore +// g_tms_foreground_color = 0x1; // Black +// g_tms_background_color = 0x5; // Light Blue + bmp_index = (ch * 8) + 0x3800; + } + } + else + { + x += 4; + g_tms_foreground_color = 0x0; // Black + g_tms_background_color = 0x5; // Light Blue + tms9128nl_palette_update(); + + if(col != 0) + { +// g_transparent_color = 0xff; + bmp_index = (ch * 8) + 8*256 * (row > 7); + } + else + { +// g_transparent_color = 0x7f; +// background_color = 0; + bmp_index = (ch * 8) + 8*256 * (row > 7); + } + } + } + + // draw each line of character into new surface + for (i = 0; i < CHAR_HEIGHT; i++) + { + line = vidmem[bmp_index + i]; // get a line + + // handle each pixel across + for (j = CHAR_WIDTH - 1; j >= 0; j--) + { + // if rightmost bit is 1, it means draw the pixel + if (line & 1) + { + *((Uint8 *) g_vidbuf + ((y+i+TMS_VERTICAL_OFFSET) * TMS9128NL_OVERLAY_W) + (x+j)) = TMS_FG_COLOR; + } + // else draw the background + else + { + *((Uint8 *) g_vidbuf + ((y+i+TMS_VERTICAL_OFFSET) * TMS9128NL_OVERLAY_W) + (x+j)) = background_color; + } + line = (unsigned char) (line >> 1); + } + } // end for loop + + // In transparency mode, if we draw a solid character, we need to make the character after it non-transparent + // This seems to be how Cliff Hanger behaves. I haven't found it documented anywhere though. + if ((g_transparency_latch) && (ch != 0) && (ch != 0xFF)) + { + int row, col; + Uint8 *ptr = ((Uint8 *) g_vidbuf) + ((y + TMS_VERTICAL_OFFSET) * TMS9128NL_OVERLAY_W) + x + CHAR_WIDTH; + for (row = 0; row < CHAR_HEIGHT; row++) + { + for (col = 0; col < CHAR_WIDTH; col++) + { + // make it non-transparent if it is + if (*ptr == TMS_TRANSPARENT_COLOR) + { + *ptr = TMS_BG_COLOR; + } + ptr++; + } + ptr += (TMS9128NL_OVERLAY_W - CHAR_WIDTH); // move to the next line + } + } + + g_game->set_video_overlay_needs_update(true); +} + +void tms9128nl_outcommand(char *s,int col,int row) +{ +// gp2x doesn't have enough resolution to display this schlop anyway... +#ifndef GP2X + SDL_Rect dest; + + dest.x = (short) ((col*6) + 200); + dest.y = (short) ((row*13) + 100); + dest.w = (unsigned short) (6 * strlen(s)); // width of rectangle area to draw (width of font * length of string) + dest.h = 13; // height of area (height of font) + + // VLDP freaks out if it's not the only thing drawing to the screen + if (!g_ldp->is_vldp()) + { + vid_blank(); + SDLDrawText(s, get_screen_blitter(), FONT_SMALL, dest.x, dest.y); + // TODO : get this working again under the new video scheme + } +#endif +} + +// called everytime the color palette changes +// We don't make this part of the 'palette_update()' function because that function also +// does some stuff with the transparent color, which is only a one-time initialization requirement +void tms9128nl_palette_update() +{ + SDL_Color fore, back; // the foreground and background colors + + tms9128nl_convert_color(g_tms_foreground_color, &fore); + tms9128nl_convert_color(g_tms_background_color, &back); + + palette_set_color(0, back); + palette_set_color(255, fore); + + // if we should do extra calculations for stretching + if (g_vidmode == 2) + { + SDL_Color fore75back25, fore5back5, fore25back75; // mixtures of the foreground and background colors (for stretching) + MIX_COLORS_75_25(fore75back25, fore, back); // 3/4, 1/4 + MIX_COLORS_50(fore5back5, fore, back); // average + MIX_COLORS_75_25(fore25back75, back, fore); // 1/4, 3/4 + palette_set_color(1, fore25back75); + palette_set_color(2, fore5back5); + palette_set_color(3, fore75back25); + } + + palette_finalize(); + g_game->set_video_overlay_needs_update(true); +} + +// calculates the initial color palette (basically our main routine is in palette_update) +void tms9128nl_palette_calculate() +{ + // transparent color set to a light grey color so we can debug more effectively in 'noldp' mode + SDL_Color color; + color.r = color.g = color.b = TMS_TRANSPARENT_COLOR; + palette_set_transparency(0, false); // change default to non-transparent + palette_set_transparency(TMS_TRANSPARENT_COLOR, true); // make transparent color transparent :) + palette_set_color(TMS_TRANSPARENT_COLOR, color); + + tms9128nl_palette_update(); + tms9128nl_reset(); +} + +void tms9128nl_video_repaint() +{ + // if the transparency state has changed + if (g_transparency_enabled != g_transparency_latch) + { + int i = 0; + + Uint8 *ptr = (Uint8 *) g_vidbuf + (TMS9128NL_OVERLAY_W * TMS_VERTICAL_OFFSET); + + // I don't believe we want to do the stretched overlay here + + // if transparency was off and is now on and we're in vidmode 1 (HACK) + if ((g_transparency_enabled) && (g_vidmode == 1)) + { + + for (i = 0; i < TMS9128NL_OVERLAY_W * (TMS9128NL_OVERLAY_H - (TMS_VERTICAL_OFFSET << 1)); i++) + { + // if color is a background color, make it 0x7F (transparency color) + if (*ptr == 0) *ptr = TMS_TRANSPARENT_COLOR; + ptr++; + } + } + else + { + for (i = 0; i < TMS9128NL_OVERLAY_W * (TMS9128NL_OVERLAY_H - (TMS_VERTICAL_OFFSET << 1)); i++) + { + // if color is transparent (0x7F), make it a background color + if (*ptr == TMS_TRANSPARENT_COLOR) *ptr = 0; + ptr++; + } + } + + g_transparency_latch = g_transparency_enabled; + } + + g_transparency_enabled = 0; // apparently this has to be set to true every pulse of the NMI in order + // to maintain the transparency. The Cliff ROM does this. + + // if we're in video mode 2, we have to display our stretched overlay instead of our regular one + if (g_vidmode == 2) + { + tms9128nl_video_repaint_stretched(); + } + + // if we're not in mode 2, display our non-stretched overlay + else + { + memcpy(g_game->get_active_video_overlay()->pixels, g_vidbuf, TMS9128NL_OVERLAY_W * TMS9128NL_OVERLAY_H); + } + + +} + +// creates the stretched overlay, using the contents of the normal overlay as its source +// the stretched overlay is simply a 256x192 window scaled to 320x192 using a hard-coded algorithm (hopefully it's fast) +void tms9128nl_video_repaint_stretched() +{ + int x256 = 0; + int y = 0; + + Uint8 *ptr256 = (Uint8 *) g_vidbuf; // source ... + Uint8 *ptr320 = (Uint8 *) g_game->get_active_video_overlay()->pixels; // destination ... + + // these values correspond to colors in the color palette + unsigned char blend[4][2] = + { + { 0, 0 }, + { 3, 1 }, + { 2, 2 }, + { 1, 3 }, + }; + + // do every row + for (y = 0; y < TMS9128NL_OVERLAY_H; y++) + { + // do each pixel, but divide it up into smallest integer sections so we can use a hard-coded algorithm + // there is a 4:5 correspondance between the 256 and 320 surfaces + for (x256 = 0; x256 < 256; x256 += 4) + { + // PIXEL +0 + *(ptr320) = *(ptr256); + + // PIXEL +1 to PIXEL +3 (blending possibly required) + for (int i = 1; i < 4; i++) + { + // if prev pixel is not the same as cur pixel, blending is required + if (*(ptr256+i-1) != *(ptr256+i)) + { + // if prev pixel is background color, cur pixel must be foreground + if (*(ptr256+i-1) == 0) + { + *(ptr320+i) = blend[i][0]; + } + // else prev pixel is foreground, and therefore cur pixel must be background + else + { + *(ptr320+i) = blend[i][1]; + } + } + else *(ptr320+i) = *(ptr256+i); // else no blending required + } + + // PIXEL +4 + *(ptr320+4) = *(ptr256+3); + + ptr320 += 5; + ptr256 += 4; + } + ptr256 += (320-256); // move to the next line, ptr320 is already at the next line + } +} + +void tms9128nl_clear_overlay() +{ + Uint8 clear_color = TMS_BG_COLOR; + + int i = 0; + + Uint8 *ptr = g_vidbuf; + +// printf("Overlay is being cleared, transparency is %d, latch is %d\n", g_transparency_enabled, g_transparency_latch); + + // if transparency mode is on ... + if (g_transparency_latch) + { + clear_color = TMS_TRANSPARENT_COLOR; + } + + // top area always gets border color and is never transparent + for (i = 0; i < TMS9128NL_OVERLAY_W * TMS_VERTICAL_OFFSET; i++) + { + + *ptr = 0; + ptr++; + } + + // erase viewable area with either the background color or the transparent color + for (i = 0; i < TMS9128NL_OVERLAY_W * (TMS9128NL_OVERLAY_H - (TMS_VERTICAL_OFFSET << 1)); i++) + { + *ptr = clear_color; + ptr++; + } + + // bottom area always gets border color and is never transparent + for (i = 0; i < TMS9128NL_OVERLAY_W * TMS_VERTICAL_OFFSET; i++) + { + *ptr = 0; + } + + g_game->set_video_overlay_needs_update(true); +} + +// kind of a hack for Cliff Hanger, not sure if this is part of the TMS9128NL chip or not +// sets the "transparency value" for one NMI tick (it gets cleared at each NMI tick) +void tms9128nl_set_transparency() +{ + g_transparency_enabled = 1; +} + diff --git a/video/tms9128nl.h b/video/tms9128nl.h new file mode 100644 index 000000000..2ca716d46 --- /dev/null +++ b/video/tms9128nl.h @@ -0,0 +1,69 @@ +/* + * tms9128nl.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef TMS9128NL_H +#define TMS9128NL_H + +#include // to declare SDL_Color + +#define TMS9128NL_OVERLAY_W 320 /* width of overlay */ +#define TMS9128NL_OVERLAY_H 240 /* height of the overlay */ + +#define TMS_VERTICAL_OFFSET 24 /* how many lines down to begin drawing video */ + +#define TMS_BG_COLOR 0 +#define TMS_TRANSPARENT_COLOR 0x7F +#define TMS_FG_COLOR 0xFF + +#define TMS_COLOR_COUNT 256 + +// mixes two colors together 0.75 and 0.25 weights, returning their mixture in 'result' +#define MIX_COLORS_75_25(result,src1,src2) \ + result.r = (Uint8) (((src1.r * 3) + src2.r) >> 2); \ + result.g = (Uint8) (((src1.g * 3) + src2.g) >> 2); \ + result.b = (Uint8) (((src1.b * 3) + src2.b) >> 2) + +// mix two colors evenly (50% blend) +#define MIX_COLORS_50(result,src1,src2) \ + result.r = (Uint8) ((src1.r + src2.r) >> 1); \ + result.g = (Uint8) ((src1.g + src2.g) >> 1); \ + result.b = (Uint8) ((src1.b + src2.b) >> 1) + + +void tms9128nl_reset(); +bool tms9128nl_int_enabled(); +void tms9128nl_writechar(unsigned char); +unsigned char tms9128nl_getvidmem(); +void tms9128nl_write_port1(unsigned char); +void tms9128nl_write_port0(unsigned char Value); +int tms9128nl_setvidmem(unsigned char); +void tms9128nl_convert_color(unsigned char, SDL_Color *); +void tms9128nl_drawchar(unsigned char, int, int); +void tms9128nl_outcommand(char *s,int col,int row); +void tms9128nl_palette_update(); +void tms9128nl_palette_calculate(); +void tms9128nl_video_repaint(); +void tms9128nl_video_repaint_stretched(); +void tms9128nl_set_transparency(); + +#endif diff --git a/video/video.cpp b/video/video.cpp new file mode 100644 index 000000000..b722aeccb --- /dev/null +++ b/video/video.cpp @@ -0,0 +1,1292 @@ +/* + * video.cpp + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// video.cpp +// Part of the DAPHNE emulator +// This code started by Matt Ownby, May 2000 + +#include +#include +#include +#include // for some error messages +#include // rdg2010 +#include "video.h" +#include "palette.h" +#include "SDL_DrawText.h" +#include "../io/conout.h" +#include "../io/error.h" +#include "../io/mpo_fileio.h" +#include "../io/mpo_mem.h" +#include "SDL_Console.h" +#include "../game/game.h" +#include "../ldp-out/ldp.h" +#include "../ldp-out/ldp-vldp-gl.h" +#include "../io/homedir.h" + + +#ifdef USE_OPENGL +#ifdef MAC_OSX +#include +#else +#include +#endif + + +// This is the max width and height that any .BMP will be, so that we can fit it into +// an opengl texture. If you need to display a bigger .BMP, increase this number. +// NOTE : this number must be a power of 2!!! +#define GL_TEX_SIZE 1024 + +// pointer to the buffer that we allocate for bitmap blits +Uint8 *g_pVidTex = NULL; + +#endif + +using namespace std; + +#ifndef GP2X +unsigned int g_vid_width = 640, g_vid_height = 480; // default video width and video height +#ifdef DEBUG +const Uint16 cg_normalwidths[] = { 320, 640, 800, 1024, 1280, 1280, 1600 }; +const Uint16 cg_normalheights[]= { 240, 480, 600, 768, 960, 1024, 1200 }; +#else +const Uint16 cg_normalwidths[] = { 640, 800, 1024, 1280, 1280, 1600 }; +const Uint16 cg_normalheights[]= { 480, 600, 768, 960, 1024, 1200 }; +#endif // DEBUG +#else +unsigned int g_vid_width = 320, g_vid_height = 240; // default for gp2x +const Uint16 cg_normalwidths[] = { 320 }; +const Uint16 cg_normalheights[]= { 240 }; +#endif + +// the dimensions that we draw (may differ from g_vid_width/height if aspect ratio is enforced) +unsigned int g_draw_width = 640, g_draw_height = 480; + +SDL_Surface *g_led_bmps[LED_RANGE] = { 0 }; +SDL_Surface *g_other_bmps[B_EMPTY] = { 0 }; +SDL_Surface *g_screen = NULL; // our primary display +SDL_Surface *g_screen_blitter = NULL; // the surface we blit to (we don't blit directly to g_screen because opengl doesn't like that) +bool g_console_initialized = false; // 1 once console is initialized +bool g_fullscreen = false; // whether we should initialize video in fullscreen mode or not +bool g_fakefullscreen = false; // by RDG2010 -- whether daphne should do fullscreen window +int g_scalefactor = 100; // by RDG2010 -- scales the image to this percentage value (for CRT TVs with overscan problems). +int sboverlay_characterset = 1; + +// whether we will try to force a 4:3 aspect ratio regardless of window size +// (this is probably a good idea as a default option) +bool g_bForceAspectRatio = true; + +bool g_bUseOpenGL = false; // whether user has requested we use OpenGL + +// the # of degrees to rotate counter-clockwise in opengl mode +float g_fRotateDegrees = 0.0; + +#ifdef USE_OPENGL +GLuint g_texture_id = 0; // for any blits we have to do in opengl ... +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// initializes the window in which we will draw our BMP's +// returns true if successful, false if failure +bool init_display() +{ + + bool result = false; // whether video initialization is successful or not + bool abnormalscreensize = true; // assume abnormal + const SDL_VideoInfo *vidinfo = NULL; + Uint8 suggested_bpp = 0; + Uint32 sdl_flags = 0; // the default for this depends on whether we are using HW accelerated YUV overlays or not + + char *hw_env = getenv("SDL_VIDEO_YUV_HWACCEL"); + + // if HW acceleration has been disabled, we need to use a SW surface due to some oddities with crashing and fullscreen + if (hw_env && (hw_env[0] == '0')) + { + sdl_flags = SDL_SWSURFACE; + } + + // else if HW acceleration hasn't been explicitely disabled ... + else + { + + sdl_flags = SDL_HWSURFACE; + // Win32 notes (may not apply to linux) : + // After digging around in the SDL source code, I've discovered a few things ... + // When using fullscreen mode, you should always use SDL_HWSURFACE because otherwise + // you can't use YUV hardware overlays due to SDL creating an extra surface without + // your consent (which seems retarded to me hehe). + // SDL_SWSURFACE + hw accelerated YUV overlays will work in windowed mode, but might + // as well just use SDL_HWSURFACE for everything. + } + + char s[250] = { 0 }; + Uint32 x = 0; // temporary index + + // if we were able to initialize the video properly + if ( SDL_InitSubSystem(SDL_INIT_VIDEO) >=0 ) + { + + vidinfo = SDL_GetVideoInfo(); + suggested_bpp = vidinfo->vfmt->BitsPerPixel; + + // if we were in 8-bit mode, try to get at least 16-bit color + // because we definitely use more than 256 colors in daphne + if (suggested_bpp < 16) + { + suggested_bpp = 32; + } + + // By RDG2010 + // Have cursor disabled always. + // Useful for ALG SINGE games + // If there is a game that needs to show the cursor icon of the OS + // then modify. + SDL_ShowCursor(SDL_DISABLE); // hide mouse in fullscreen mode + + if (g_fullscreen) + { + //SDL_ShowCursor(SDL_DISABLE); // hide mouse in fullscreen mode + sdl_flags |= SDL_FULLSCREEN; + } + + // go through each standard resolution size to see if we are using a standard resolution + for (x=0; x < (sizeof(cg_normalwidths) / sizeof(Uint16)); x++) + { + // if we find a match, we know we're using a standard res + if ((g_vid_width == cg_normalwidths[x]) && (g_vid_height == cg_normalheights[x])) + { + abnormalscreensize = false; + } + } + + // if we're using a non-standard resolution + if (abnormalscreensize) + { + printline("WARNING : You have specified an abnormal screen resolution! Normal screen resolutions are:"); + // print each standard resolution + for (x=0; x < (sizeof(cg_normalwidths) / sizeof(Uint16)); x++) + { + sprintf(s,"%d x %d", cg_normalwidths[x], cg_normalheights[x]); + printline(s); + } + newline(); + } + + /* by RDG2010 + * Adding preliminary lightgun support. + * For now that means a fake fullscreen. + * A borderless, no title bar window the same size as the desktop. + * This is done in three steps: + * 1. Get desktop resolution. + * 2. Make SDL window borderless. + * 3. Move window to top-left corner of the screen. + * + * Tested OK on both Windows and Ubuntu Linux. + * TODO: Provide a better solution. + * + */ + + if (get_fakefullscreen()) + { + + // Step 1. Get desktop resolution. + // Get the current resolution of the system's desktop. + const SDL_VideoInfo* info = SDL_GetVideoInfo(); // For SDL 1.3 use SDL_GetDesktopDisplayMode() instead. + int desktopWidth = info->current_w; + int desktopHeight = info->current_h; + // Update variables here, before initializing any surfaces. + g_vid_width = desktopWidth ; g_vid_height = desktopHeight; + } + // RDG2010 + + g_draw_width = g_vid_width; + g_draw_height = g_vid_height; + + // if we're supposed to enforce the aspect ratio ... + if (g_bForceAspectRatio) + { + double dCurAspectRatio = (double) g_vid_width / g_vid_height; + const double dTARGET_ASPECT_RATIO = 4.0/3.0; + + // if current aspect ratio is less than 1.3333 + if (dCurAspectRatio < dTARGET_ASPECT_RATIO) + { + g_draw_height = (g_draw_width * 3) / 4; + } + // else if current aspect ratio is greater than 1.3333 + else if (dCurAspectRatio > dTARGET_ASPECT_RATIO) + { + g_draw_width = (g_draw_height * 4) / 3; + } + // else the aspect ratio is already correct, so don't change anything + } + + // if we're supposed to scale the image... + if (g_scalefactor < 100) + { + g_draw_width = g_draw_width * g_scalefactor / 100; + g_draw_height = g_draw_height * g_scalefactor / 100; + } + +#ifndef GP2X + if (!g_bUseOpenGL) + { +#ifdef WIN32 + if (g_game->verify_required_file2("singe32.bmp","pics",0xC17A933D)) + { + // Add icon to the SDL Window -- RDG + + Uint32 colorkey; + SDL_Surface *image; + image = SDL_LoadBMP("pics/singe32.bmp"); + colorkey = SDL_MapRGB(image->format, 255, 0, 255); + SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey); + SDL_WM_SetIcon(image,NULL); // MUST BE CALLED BEFORE set video mode, or else it won't show on the title bar. + + } + +#endif + // by RDG2010 + // Step 2. Create a borderless SDL window. + // If doing fullscreen window, make the window bordeless (no title bar). + // This is achieved by adding the SDL_NOFRAME flag. + + if (get_fakefullscreen()) sdl_flags = sdl_flags | SDL_NOFRAME; + + g_screen = SDL_SetVideoMode(g_vid_width, g_vid_height, suggested_bpp, sdl_flags); + SDL_WM_SetCaption("SINGE: Somewhat Interactive Nostalgic Game Engine =]", "Singe"); + + } + else + { +#ifdef USE_OPENGL + init_opengl(); + glGenTextures(1, &g_texture_id); // generate texture buffer for use in this file + g_pVidTex = MPO_MALLOC(GL_TEX_SIZE * GL_TEX_SIZE * 4); // 32-bit bits per pixel, width and height the same +#endif + } +#else + SDL_ShowCursor(SDL_DISABLE); // always hide mouse for gp2x + g_screen = SDL_SetVideoMode(320, 240, 0, SDL_HWSURFACE); +#endif + + /* by RDG2010 + * Step 3. Move window to the top-left corner of the screen. + * + * The task of positioning the window is OS dependant. + * When using a window the same size of the desktop, X11 will + * automatically position it to the top-left corner of the screen. + * In the case of Windows, it has to be done manually. + * + */ + +#ifdef WIN32 + if (get_fakefullscreen()) + { + + // Access to SDL's OS specific structure. + SDL_SysWMinfo windowInfo; + SDL_VERSION(&windowInfo.version); + + if(SDL_GetWMInfo(&windowInfo)) + { + // Retrieve the Windows handle to the SDL window. + HWND handle = windowInfo.window; + // Position Window to top-left corner of the screen. + if(!SetWindowPos(handle, NULL, 0, 0, 0, 0, SWP_NOREPOSITION|SWP_NOZORDER|SWP_NOSIZE)) + { + printline("Error occurred with 'SetWindowPos'. Fullscreen window failed."); + result = 0; + } + + } + else + { + // Error occurred with 'SDL_GetWMInfo' + printline("Error occurred with 'SDL_GetWMInfo'. Fullscreen window failed."); + result = 0; + + } // endif + + } // endif + +#endif + + + // create a 32-bit surface + g_screen_blitter = SDL_CreateRGBSurface(SDL_SWSURFACE, + g_vid_width, + g_vid_height, + 32, + 0xff, 0xFF00, 0xFF0000, 0xFF000000); + + if (g_screen && g_screen_blitter) + { + SDL_SetAlpha(g_screen_blitter,SDL_SRCALPHA,0); //rdg + sprintf(s, "Set %dx%d at %d bpp with flags: %x", g_screen->w, g_screen->h, g_screen->format->BitsPerPixel, g_screen->flags); + printline(s); + + // initialize SDL console in the background + if (ConsoleInit("pics/ConsoleFont.bmp", g_screen_blitter, 100)==0) + { + AddCommand(g_cpu_break, "break"); + g_console_initialized = true; + result = true; + } + else + { + printerror("Error initializing SDL console =("); + } + + // sometimes the screen initializes to white, so this attempts to prevent that + vid_blank(); + vid_flip(); + vid_blank(); + vid_flip(); + } + } + + if (result == 0) + { + sprintf(s, "Could not initialize video display: %s", SDL_GetError()); + printerror(s); + } + + return(result); + +} + +#ifdef USE_OPENGL +bool init_opengl() +{ + bool bResult = false; + + Uint32 sdl_flags = SDL_SWSURFACE | SDL_OPENGL; + + // fullscreen is broken + if (get_fullscreen()) sdl_flags |= SDL_FULLSCREEN; + + SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + + // by RDG2010 + // Step 2. Create a borderless SDL window (on the OpenGL side). + // If doing fullscreen window, make the window bordeless (no title bar). + // This is achieved by adding the SDL_NOFRAME flag. + // Tested OK on both Windows and Ubuntu Linux. + + if (get_fakefullscreen()) sdl_flags = sdl_flags | SDL_NOFRAME; + + g_screen = SDL_SetVideoMode(g_vid_width, g_vid_height, 0, sdl_flags); + + // if SDL_SetVideoMode worked ... + if (g_screen) + { + //SDL_WM_SetCaption("DAPHNE: Now in experimental OpenGL mode :)", "daphne"); + SDL_WM_SetCaption("SINGE: Somewhat Interactive Nostalgic Game Engine =]", "Singe"); + + //glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); // since we are doing scaling, we need this ... + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); // this should give us some optimization for free + glDisable(GL_LIGHTING); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* Set the clear color. */ + glClearColor( 0, 0.0, 0, 1 ); + + /* Setup our viewport. */ + glViewport( 0, 0, g_screen->w, g_screen->h ); + + // ENABLE 2D MODE (ORTHO) + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + + // The idea is to have the center of the image be at 0,0 to make rotation, scaling, etc + // easier. + glOrtho( + -g_screen->w / 2, // left + g_screen->w / 2, // right + -g_screen->h / 2, // bottom + g_screen->h / 2, // top + -10, 10); + + glMatrixMode (GL_MODELVIEW); + + glEnable(GL_TEXTURE_2D); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + // handle optional rotation + // if we're to one side or the other, scale the image so it will fit + if ((g_fRotateDegrees == 90.0) || (g_fRotateDegrees == 270.0)) + { + // NOTE : this can either shrink or enlarge depending on whether the width or height is bigger + GLfloat fFactor = (GLfloat) g_vid_height / g_vid_width; + glScalef(fFactor, fFactor, 1.0); + } + + // only rotate if we have a need to + if (g_fRotateDegrees != 0) + { + glRotatef(g_fRotateDegrees, 0, 0, 1.0); + } + + bResult = true; + } + // else SetVideoMode failed ... + + return bResult; +} +#endif // USE_OPENGL + +// shuts down video display +void shutdown_display() +{ + printline("Shutting down video display..."); + + if (g_console_initialized) + { + ConsoleShutdown(); + g_console_initialized = false; + } + +#ifdef USE_OPENGL + // free texture buffer from memory + MPO_FREE(g_pVidTex); +#endif + + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + +void vid_flip() +{ + // if we're not using OpenGL, then just use the regular SDL Flip ... + if (!g_bUseOpenGL) + { + SDL_Flip(g_screen); + } + else + { + SDL_GL_SwapBuffers(); + } +} + +void vid_blank() +{ + if (!g_bUseOpenGL) + { + SDL_FillRect(g_screen, NULL, 0); + } + else + { +#ifdef USE_OPENGL + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#endif + } +} + +#ifdef USE_OPENGL +// converts an SDL surface to an opengl texture +void vid_srf2tex(SDL_Surface *srf, GLuint uTexID) +{ + Uint8 *ptrPixelRow = (Uint8 *) srf->pixels; + Uint32 *RGBARow = (Uint32 *) g_pVidTex; + Uint32 *g_puRGBAPalette = get_rgba_palette(); + for (unsigned int uRow = 0; (uRow < (unsigned) srf->h) && (uRow < GL_TEX_SIZE); ++uRow) + { + Uint8 *ptrPixel = ptrPixelRow; + Uint32 *RGBA = RGBARow; + + for (unsigned int uCol = 0; (uCol < (unsigned) srf->w) && (uCol < GL_TEX_SIZE); ++uCol) + { + Uint8 R, G, B; + + // if this is an 8-bit surface + if (srf->format->BitsPerPixel == 8) + { + // retrieve precalculated RGBA value + *RGBA = g_puRGBAPalette[*ptrPixel]; + } + // else it doesn't use a color palette + else + { + Uint32 uVal = *((Uint32*) ptrPixel); + R = ((uVal & srf->format->Rmask) >> srf->format->Rshift) << srf->format->Rloss; + G = ((uVal & srf->format->Gmask) >> srf->format->Gshift) << srf->format->Gloss; + B = ((uVal & srf->format->Bmask) >> srf->format->Bshift) << srf->format->Bloss; + // this may not work for big endian, but we won't know until we try + *RGBA = R | (G << 8) | (B << 16) | 0xFF000000; + } + + // move to the next pixel ... + ptrPixel += srf->format->BytesPerPixel; + ++RGBA; + } // end this line + + // move to the next row + ptrPixelRow += srf->pitch; + RGBARow += GL_TEX_SIZE; // move down one row in the texture memory + } + + glBindTexture(GL_TEXTURE_2D, uTexID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + // apply the texture + glTexImage2D(GL_TEXTURE_2D, + 0, // level is 0 + GL_RGBA, GL_TEX_SIZE, GL_TEX_SIZE, + 0, // border is 0 + GL_RGBA, GL_UNSIGNED_BYTE, g_pVidTex); + +} +#endif + +void vid_blit(SDL_Surface *srf, int x, int y) +{ +// if (g_ldp->is_blitting_allowed()) rdg + int result = 0; + { + if (!g_bUseOpenGL) + { + SDL_Rect dest; + dest.x = (short) x; + dest.y = (short) y; + dest.w = (unsigned short) srf->w; + dest.h = (unsigned short) srf->h; + result = SDL_BlitSurface(srf, NULL, g_screen, &dest); + } + + // else, OpenGL mode for blitting ... + else + { +#ifdef USE_OPENGL + + // convert surface to a texture + vid_srf2tex(srf, g_texture_id); + + // draw the textured rectangle + GLfloat fWidth = (GLfloat) srf->w / GL_TEX_SIZE; + GLfloat fHeight = (GLfloat) srf->h / GL_TEX_SIZE; + + // convert y from top-to-bottom to bottom-to-top (SDL -> openGL) + y = g_vid_height - y; + + // adjust coordinates so they match up with glOrtho projection + x -= (g_vid_width >> 1); + y -= (g_vid_height >> 1); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3i(x, y, 0); // top left + glTexCoord2f(0, fHeight); glVertex3i(x, y - srf->h, 0); // bottom left + glTexCoord2f(fWidth, fHeight); glVertex3i(x + srf->w, y - srf->h, 0); // bottom right + glTexCoord2f(fWidth, 0); glVertex3i(x + srf->w, y, 0); // top right + glEnd(); + +#endif // USE_OPENGL + } + } + // else blitting isn't allowed, so just ignore +} + +// redraws the proper display (Scoreboard, etc) on the screen, after first clearing the screen +// call this every time you want the display to return to normal +void display_repaint() +{ + vid_blank(); + vid_flip(); + g_game->video_force_blit(); +} + +// loads all the .bmp's used by DAPHNE +// returns true if they were all successfully loaded, or a false if they weren't +bool load_bmps() +{ + + bool result = true; // assume success unless we hear otherwise + int index = 0; + char filename[81]; +/* + for (; index < LED_RANGE; index++) + { + sprintf(filename, "pics/led%d.bmp", index); + + g_led_bmps[index] = load_one_bmp(filename); + + // If the bit map did not successfully load + if (g_led_bmps[index] == 0) + { + result = false; + } + } + + g_other_bmps[B_DL_PLAYER1] = load_one_bmp("pics/player1.bmp"); + g_other_bmps[B_DL_PLAYER2] = load_one_bmp("pics/player2.bmp"); + g_other_bmps[B_DL_LIVES] = load_one_bmp("pics/lives.bmp"); + g_other_bmps[B_DL_CREDITS] = load_one_bmp("pics/credits.bmp"); +*/ + g_other_bmps[B_DAPHNE_SAVEME] = load_one_bmp("pics/saveme.bmp"); + g_other_bmps[B_GAMENOWOOK] = load_one_bmp("pics/gamenowook.bmp"); +/* + if (sboverlay_characterset != 2) + g_other_bmps[B_OVERLAY_LEDS] = load_one_bmp("pics/overlayleds1.bmp"); + else + g_other_bmps[B_OVERLAY_LEDS] = load_one_bmp("pics/overlayleds2.bmp"); + + g_other_bmps[B_OVERLAY_LDP1450] = load_one_bmp("pics/ldp1450font.bmp"); +*/ + // check to make sure they all loaded + //for (index = 0; index < B_EMPTY; index++) + for (index = 0; index < 2; index++) + { + if (g_other_bmps[index] == NULL) + { + result = false; + } + } + + return(result); +} + + +SDL_Surface *load_one_bmp(const char *filename) +{ + SDL_Surface *result = SDL_LoadBMP(filename); + + if (!result) + { + string err = "Could not load bitmap : "; + err = err + filename; + printerror(err.c_str()); + } + + return(result); +} + +// Draw's one of our LED's to the screen +// value contains the bitmap to draw (0-9 is valid) +// x and y contain the coordinates on the screen +// This function is called from scoreboard.cpp +// 1 is returned on success, 0 on failure +bool draw_led(int value, int x, int y) +{ + vid_blit(g_led_bmps[value], x, y); + return true; +} + +// Draw overlay digits to the screen +void draw_overlay_leds(unsigned int values[], int num_digits, int start_x, int y, SDL_Surface *overlay) +{ + SDL_Rect src, dest; + + dest.x = start_x; + dest.y = y; + dest.w = OVERLAY_LED_WIDTH; + dest.h = OVERLAY_LED_HEIGHT; + + src.y = 0; + src.w = OVERLAY_LED_WIDTH; + src.h = OVERLAY_LED_HEIGHT; + + /* Draw the digit(s) */ + for(int i = 0; i < num_digits; i++) + { + src.x = values[i] * OVERLAY_LED_WIDTH; + SDL_BlitSurface(g_other_bmps[B_OVERLAY_LEDS], &src, overlay, &dest); + dest.x += OVERLAY_LED_WIDTH; + } + + dest.x = start_x; + dest.w = num_digits * OVERLAY_LED_WIDTH; + SDL_UpdateRects(overlay, 1, &dest); +} + +// Draw LDP1450 overlay characters to the screen (added by Brad O.) +void draw_singleline_LDP1450(char *LDP1450_String, int start_x, int y, SDL_Surface *overlay) +{ + SDL_Rect src, dest; + + int i = 0; + int value = 0; + int LDP1450_strlen; +// char s[81]=""; + + dest.x = start_x; + dest.y = y; + dest.w = OVERLAY_LDP1450_WIDTH; + dest.h = OVERLAY_LDP1450_HEIGHT; + + src.y = 0; + src.w = OVERLAY_LDP1450_WIDTH; + src.h = OVERLAY_LDP1450_WIDTH; + + LDP1450_strlen = strlen(LDP1450_String); + + if (!LDP1450_strlen) // if a blank line is sent, we must blank out the entire line + { + strcpy(LDP1450_String," "); + LDP1450_strlen = strlen(LDP1450_String); + } + else + { + if (LDP1450_strlen <= 11) // pad end of string with spaces (in case previous line was not cleared) + { + for (i=LDP1450_strlen; i<=11; i++) + LDP1450_String[i] = 32; + LDP1450_strlen = strlen(LDP1450_String); + } + } + + for (i=0; i= 0x26 && value <= 0x39) // numbers and symbols + value -= 0x25; + else if (value >= 0x41 && value <= 0x5a) // alpha + value -= 0x2a; + else if (value == 0x13) // special LDP-1450 character (inversed space) + value = 0x32; + else + value = 0x31; // if not a number, symbol, or alpha, recognize as a space + + src.x = value * OVERLAY_LDP1450_WIDTH; + SDL_BlitSurface(g_other_bmps[B_OVERLAY_LDP1450], &src, overlay, &dest); + + dest.x += OVERLAY_LDP1450_CHARACTER_SPACING; + } + dest.x = start_x; + dest.w = LDP1450_strlen * OVERLAY_LDP1450_CHARACTER_SPACING; + + // MPO : calling UpdateRects probably isn't necessary and may be harmful + //SDL_UpdateRects(overlay, 1, &dest); +} + +// used to draw non LED stuff like scoreboard text +// 'which' corresponds to enumerated values +bool draw_othergfx(int which, int x, int y, bool bSendToScreenBlitter) +{ + // NOTE : this is drawn to g_screen_blitter, not to g_screen, + // to be more friendly to our opengl implementation! + SDL_Surface *srf = g_other_bmps[which]; + SDL_Rect dest; + dest.x = (short) x; + dest.y = (short) y; + dest.w = (unsigned short) srf->w; + dest.h = (unsigned short) srf->h; + + // if we should blit this to the screen blitter for later use ... + if (bSendToScreenBlitter) + { + SDL_BlitSurface(srf, NULL, g_screen_blitter, &dest); + } + // else blit it now + else + { + vid_blit(g_other_bmps[which], x, y); + } + return true; +} + +// de-allocates all of the .bmps that we have allocated +void free_bmps() +{ + + int nuke_index = 0; + + // get rid of all the LED's + for (; nuke_index < LED_RANGE; nuke_index++) + { + free_one_bmp(g_led_bmps[nuke_index]); + } + for (nuke_index = 0; nuke_index < B_EMPTY; nuke_index++) + { + // check to make sure it exists before we try to free + if (g_other_bmps[nuke_index]) + { + free_one_bmp(g_other_bmps[nuke_index]); + } + } +} + +void free_one_bmp(SDL_Surface *candidate) +{ + + SDL_FreeSurface(candidate); + +} + +////////////////////////////////////////////////////////////////////////////////////////// + +SDL_Surface *get_screen() +{ + return g_screen; +} + +SDL_Surface *get_screen_blitter() +{ + return g_screen_blitter; +} + +int get_console_initialized() +{ + return g_console_initialized; +} + +bool get_fullscreen() +{ + return g_fullscreen; +} + +// sets our g_fullscreen bool (determines whether will be in fullscreen mode or not) +void set_fullscreen(bool value) +{ + g_fullscreen = value; +} + +// by RDG2010 +bool get_fakefullscreen() +{ + return g_fakefullscreen; +} + +void set_fakefullscreen(bool value) +{ + g_fakefullscreen = value; +} + +int get_scalefactor() +{ + return g_scalefactor; +} +void set_scalefactor(int value) +{ + if (value > 100 || value < 50) // Validating in case user inputs crazy values. + { + printline("Invalid scale value. Ignoring -scalefactor parameter."); + g_scalefactor = 100; + + } else { g_scalefactor = value; } +} + +void set_rotate_degrees(float fDegrees) +{ + g_fRotateDegrees = fDegrees; +} + +void set_sboverlay_characterset(int value) +{ + sboverlay_characterset = value; +} + +// returns video width +Uint16 get_video_width() +{ + return g_vid_width; +} + +// sets g_vid_width +void set_video_width(Uint16 width) +{ + // Let the user specify whatever width s/he wants (and suffer the consequences) + // We need to support arbitrary resolution to accomodate stuff like screen rotation + g_vid_width = width; +} + +// returns video height +Uint16 get_video_height() +{ + return g_vid_height; +} + +// sets g_vid_height +void set_video_height(Uint16 height) +{ + // Let the user specify whatever height s/he wants (and suffer the consequences) + // We need to support arbitrary resolution to accomodate stuff like screen rotation + g_vid_height = height; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +// converts the SDL_Overlay to a BMP file +// ASSUMES OVERLAY IS ALREADY LOCKED!!! +void take_screenshot(SDL_Overlay *yuvimage) +{ + SDL_Color cur_color = { 0 }; + bool bSaveYUV = false; + +#ifdef DEBUG + // in debug mode, save the YUV stuff too + bSaveYUV = true; +#endif // DEBUG + + SDL_Surface *rgbimage = SDL_CreateRGBSurface(SDL_SWSURFACE, yuvimage->w, yuvimage->h, 32, 0xFF, 0xFF00, 0xFF0000, 0); + if (rgbimage) + { + Uint32 *cur_pixel = (Uint32 *) rgbimage->pixels; + + // if we're in YV12 format (old) + if (yuvimage->format == SDL_YV12_OVERLAY) + { + Uint8 *Y = yuvimage->pixels[0]; + Uint8 *V = yuvimage->pixels[1]; + Uint8 *U = yuvimage->pixels[2]; + int y_extra = yuvimage->pitches[0] - yuvimage->w; + int v_extra = yuvimage->pitches[1] - (yuvimage->w / 2); + int u_extra = yuvimage->pitches[2] - (yuvimage->w / 2); + + // advance by 2 since the U and V channels are half-sized + for (int row = 0; row < yuvimage->h; row += 2) + { + // advance by 2 since the U and V channels are half-sized + for (int col = 0; col < yuvimage->w; col += 2) + { + // get a 2x2 block of pixels and store them due to YUV structure + // upper left + yuv2rgb(&cur_color, *Y, *U, *V); + cur_pixel[0] = SDL_MapRGB(rgbimage->format, cur_color.r, cur_color.g, cur_color.b); + + // upper right + yuv2rgb(&cur_color, *(Y+1), *U, *V); + cur_pixel[1] = SDL_MapRGB(rgbimage->format, cur_color.r, cur_color.g, cur_color.b); + + // lower left + yuv2rgb(&cur_color, *(Y + yuvimage->pitches[0]), *U, *V); + cur_pixel[0 + rgbimage->w] = SDL_MapRGB(rgbimage->format, cur_color.r, cur_color.g, cur_color.b); + + // lower right + yuv2rgb(&cur_color, *(Y + yuvimage->pitches[0] + 1), *U, *V); + cur_pixel[1 + rgbimage->w] = SDL_MapRGB(rgbimage->format, cur_color.r, cur_color.g, cur_color.b); + + cur_pixel += 2; // move two pixels over + Y += 2; // move two Y values over + U++; // but just 1 U and V + V++; + } + Y += y_extra; + V += v_extra; + U += u_extra; + cur_pixel += rgbimage->w; // move down one row (FIXME: I think this should use pitch) + // WARNING: the above assumes that the pitch is the width * 4 + + Y += yuvimage->pitches[0]; // move down one line + } + } + else if (yuvimage->format == SDL_YUY2_OVERLAY) + { + mpo_io *io = NULL; + if (bSaveYUV) + { + io = mpo_open("surface.YUY2", MPO_OPEN_CREATE); + } + + Uint8 *line_ptr = yuvimage->pixels[0]; + for (int row = 0; row < yuvimage->h; row ++) + { + // if we're saving to a file, then write the YUY2 line + if (bSaveYUV) + { + mpo_write(line_ptr, yuvimage->w * 2, NULL, io); + } + + Uint8 *pixel_ptr = line_ptr; + // advance by 2 because we're doing 2 pixels at a time + for (int col = 0; col < yuvimage->w; col += 2) + { + // left + yuv2rgb(&cur_color, *(pixel_ptr), *(pixel_ptr+1), *(pixel_ptr+3)); + cur_pixel[0] = SDL_MapRGB(rgbimage->format, cur_color.r, cur_color.g, cur_color.b); + + // right + yuv2rgb(&cur_color, *(pixel_ptr+2), *(pixel_ptr+1), *(pixel_ptr+3)); + cur_pixel[1] = SDL_MapRGB(rgbimage->format, (cur_color.r & 0xFE), (cur_color.g & 0xFE), (cur_color.b & 0xFE)); + + cur_pixel += 2; // move 2 pixels over + pixel_ptr += 4; // move 4 bytes over + } + line_ptr += yuvimage->pitches[0]; + cur_pixel += (rgbimage->pitch - (rgbimage->w*4)) / 4; // this look complicated, but the pitch should be the width * 4 so it's just a precaution + // NOTE : if the pitch is not a multiple of 4, then we've got problems.. + } + + if (io) + { + mpo_close(io); + } + } + else + { + printline ("ERROR : unknown YUV format!"); + } + + // now the RGB image has been created, time to save + save_screenshot(rgbimage); + SDL_FreeSurface(rgbimage); // de-allocate surface, as we no longer need it + + } // end if RGB image + else + { + printline("ERROR: Could not create RGB image to take screenshot with"); + } + + // if we're in YV12 mode and we should save the YUV stuff, then do so + if (bSaveYUV && (yuvimage->format == SDL_YV12_OVERLAY)) + { + // NOW save the Y, U and V channels in separate files + // Most people won't need or want these files, but I have use of them for testing + Uint8 *Y = yuvimage->pixels[0]; + Uint8 *V = yuvimage->pixels[1]; + Uint8 *U = yuvimage->pixels[2]; + + struct mpo_io *io = mpo_open("surface.Y", MPO_OPEN_CREATE); + if (io) + { + for (int row = 0; row < yuvimage->h; row++) + { + mpo_write(Y, yuvimage->w, NULL, io); + Y += yuvimage->pitches[0]; + } + mpo_close(io); + } + + io = mpo_open("surface.V", MPO_OPEN_CREATE); + if (io) + { + for (int row = 0; row < (yuvimage->h / 2); row++) + { + mpo_write(V, yuvimage->w / 2, NULL, io); + V += yuvimage->pitches[1]; + } + mpo_close(io); + } + + io = mpo_open("surface.U", MPO_OPEN_CREATE); + if (io) + { + for (int row = 0; row < (yuvimage->h / 2); row++) + { + mpo_write(U, yuvimage->w / 2, NULL, io); + U += yuvimage->pitches[2]; + } + mpo_close(io); + } + } +} + +#ifdef USE_OPENGL +void take_screenshot_GL() +{ + SDL_Surface *rgbimage = SDL_CreateRGBSurface(SDL_SWSURFACE, + g_vid_width, g_vid_height, 32, 0xFF, 0xFF00, 0xFF0000, 0); + + if (rgbimage) + { + unsigned char *bufDst = (unsigned char *) rgbimage->pixels; + unsigned int uLineLength = g_vid_width << 2; + + unsigned char *bufTmp = new unsigned char [uLineLength * g_vid_height]; + if (bufTmp) + { + // grab current screen + glReadPixels(0, 0, g_vid_width, g_vid_height, GL_RGBA, GL_UNSIGNED_BYTE, bufTmp); + + // OpenGL goes bottom to top, and the SDL Surface goes top to bottom, + // so we have to flip the image. + for (unsigned int uLine = 0; uLine < g_vid_height; ++uLine) + { + unsigned char *u8Dst = bufDst + (uLine * uLineLength); + unsigned char *u8Src = bufTmp + ((g_vid_height - uLine - 1) * uLineLength); + + memcpy(u8Dst, u8Src, (g_vid_width << 2)); + } + + // now the RGB image has been created, time to save + save_screenshot(rgbimage); + + delete [] bufTmp; + } + else printline("ERROR: take_screenshot_GL memory allocation failed"); + + SDL_FreeSurface(rgbimage); // de-allocate surface, as we no longer need it + + } // end if RGB image + else + { + printline("ERROR: Could not create RGB image to take screenshot with"); + } +} +#endif // USE_OPENGL + +// saves an SDL surface to a .BMP file in the screenshots directory +void save_screenshot(SDL_Surface *shot) +{ + int screenshot_num = 0; + char filename[81] = { 0 }; + string fullpath; + + // search for a filename that does not exist + for (;;) + { + screenshot_num++; + sprintf(filename, "screen%d.bmp", screenshot_num); + fullpath = g_homedir.get_screenshot_dir() + filename; + + // if file does not exist, we'll save a screenshot to that filename + if (!mpo_file_exists(fullpath.c_str())) + { + break; + } + } + + if (SDL_SaveBMP(shot, fullpath.c_str()) == 0) + { + outstr("NOTE: Wrote screenshot to file "); + printline(filename); + } + else + { + outstr("ERROR: Could not write screenshot to file "); + printline(filename); + } +} + +// converts YUV to RGB +// Use this only when you don't care about speed =] +// NOTE : it is important for y, u, and v to be signed +void yuv2rgb(SDL_Color *result, int y, int u, int v) +{ + // NOTE : Visual C++ 7.0 apparently has a bug + // in its floating point optimizations because this function + // will return incorrect results when compiled as a Release + // Possible workaround: use integer math instead of float? or don't use VC++ 7? hehe + + int b = (int) (1.164*(y - 16) + 2.018*(u - 128)); + int g = (int) (1.164*(y - 16) - 0.813*(v - 128) - 0.391*(u - 128)); + int r = (int) (1.164*(y - 16) + 1.596*(v - 128)); + + // clamp values (not sure if this is necessary, but we aren't worried about speed) + if (b > 255) b = 255; + if (b < 0) b = 0; + if (g > 255) g = 255; + if (g < 0) g = 0; + if (r > 255) r = 255; + if (r < 0) r = 0; + + result->r = (unsigned char) r; + result->g = (unsigned char) g; + result->b = (unsigned char) b; +} + +void draw_string(const char* t, int col, int row, SDL_Surface* overlay) +{ + SDL_Rect dest; + + dest.x = (short) ((col*6)); + dest.y = (short) ((row*13)); + dest.w = (unsigned short) (6 * strlen(t)); // width of rectangle area to draw (width of font * length of string) + dest.h = 13; // height of area (height of font) + + SDL_FillRect(overlay, &dest, 0); // erase anything at our destination before we print new text + SDLDrawText(t, overlay, FONT_SMALL, dest.x, dest.y); + SDL_UpdateRects(overlay, 1, &dest); +} + +// toggles fullscreen mode +void vid_toggle_fullscreen() +{ + // Commented out because it creates major problems with YUV overlays and causing segfaults.. + // The real way to toggle fullscreen is to kill overlay, kill surface, make surface, make overlay. + /* + g_screen = SDL_SetVideoMode(g_screen->w, + g_screen->h, + g_screen->format->BitsPerPixel, + g_screen->flags ^ SDL_FULLSCREEN); + */ +} + +// NOTE : put into a separate function to make autotesting easier +void set_yuv_hwaccel(bool enabled) +{ + const char *val = "0"; + if (enabled) val = "1"; +#ifdef WIN32 + SetEnvironmentVariable("SDL_VIDEO_YUV_HWACCEL", val); + string sEnv = "SDL_VIDEO_YUV_HWACCEL="; + sEnv += val; + putenv(sEnv.c_str()); +#else + setenv("SDL_VIDEO_YUV_HWACCEL", val, 1); +#endif +} + +bool get_yuv_hwaccel() +{ + bool result = true; // it is enabled by default +#ifdef WIN32 + char buf[30]; + ZeroMemory(buf, sizeof(buf)); + DWORD res = GetEnvironmentVariable("SDL_VIDEO_YUV_HWACCEL", buf, sizeof(buf)); + if (buf[0] == '0') result = false; +#else + char *hw_env = getenv("SDL_VIDEO_YUV_HWACCEL"); + + // if HW acceleration has been disabled + if (hw_env && (hw_env[0] == '0')) result = false; +#endif + return result; +} + +void set_force_aspect_ratio(bool bEnabled) +{ + g_bForceAspectRatio = bEnabled; +} + +bool get_force_aspect_ratio() +{ + return g_bForceAspectRatio; +} + +#ifdef USE_OPENGL +void set_use_opengl(bool enabled) +{ + g_bUseOpenGL = enabled; +} + +bool get_use_opengl() +{ + return g_bUseOpenGL; +} + +#endif // USE_OPENGL + diff --git a/video/video.h b/video/video.h new file mode 100644 index 000000000..51e939d3b --- /dev/null +++ b/video/video.h @@ -0,0 +1,119 @@ +/* + * video.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of DAPHNE, a laserdisc arcade game emulator + * + * DAPHNE 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. + * + * DAPHNE 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 + */ + +// by Matt Ownby +// Part of the DAPHNE emulator + +#ifndef BITMAP_H +#define BITMAP_H + +#include + +#define LED_RANGE 17 //16 is normal, the 17th is for the 'A' in SAE + +#define OVERLAY_LED_WIDTH 8 +#define OVERLAY_LED_HEIGHT 13 + +#define OVERLAY_LDP1450_WIDTH 16 //width of each LDP1450 overlay character +#define OVERLAY_LDP1450_HEIGHT 16 //height of each LDP1450 overlay character +#define OVERLAY_LDP1450_CHARACTER_SPACING 15 //spacing between LDP1450 overlay characters +#define OVERLAY_LDP1450_LINE_SPACING 16 //spacing between LDP1450 overlay lines + +enum { B_DAPHNE_SAVEME, B_GAMENOWOOK, B_DL_PLAYER1, B_DL_PLAYER2, B_DL_LIVES, B_DL_CREDITS, B_OVERLAY_LEDS, B_OVERLAY_LDP1450, B_EMPTY }; // bitmaps +enum { FONT_SMALL, FONT_BIG }; // font enumeration, dependent on which order font .bmp's are loaded in + +// dimensions of small font +#define FONT_SMALL_W 6 +#define FONT_SMALL_H 13 + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool init_display(); + +#ifdef USE_OPENGL +bool init_opengl(); +void take_screenshot_GL(); +#endif // USE_OPENGL + +void shutdown_display(); + +// flips the video buffers (if in double buffering mode) +void vid_flip(); + +// blanks the back video buffer (makes it black) +void vid_blank(); + +// blits an SDL Surface to the back buffer +void vid_blit(SDL_Surface *srf, int x, int y); + +void display_repaint(); +bool load_bmps(); +bool draw_led(int, int, int); +void draw_overlay_leds(unsigned int led_values[], int num_values, int x, int y, SDL_Surface *overlay); +void draw_singleline_LDP1450(char *LDP1450_String, int start_x, int y, SDL_Surface *overlay); +bool draw_othergfx(int which, int x, int y, bool bSendToScreenBlitter = true); +void free_bmps(); +SDL_Surface *load_one_bmp(const char *); +void free_one_bmp(SDL_Surface *); +void draw_rectangle(short x, short y, unsigned short w, unsigned short h, unsigned char red, unsigned char green, unsigned char blue); +SDL_Surface *get_screen(); +SDL_Surface *get_screen_blitter(); +int get_console_initialized(); +bool get_fullscreen(); +void set_fullscreen(bool value); +bool get_fakefullscreen(); // by RDG2010 +void set_fakefullscreen(bool value); // by RDG2010 +int get_scalefactor(); // by RDG2010 +void set_scalefactor(int value); // by RDG2010 +void set_rotate_degrees(float fDegrees); +void set_sboverlay_characterset(int value); +Uint16 get_video_width(); +void set_video_width(Uint16); +Uint16 get_video_height(); +void set_video_height(Uint16); +void take_screenshot(SDL_Overlay *yuvimage); +void save_screenshot(SDL_Surface *shot); +void yuv2rgb(SDL_Color *result, int y, int u, int v); +void draw_string(const char*, int, int, SDL_Surface*); +void vid_toggle_fullscreen(); + +// used to enable/disable the HWACCEL environment variable +// (the YUV overlay must be created after this has been called for it to take effect) +// if 'enabled' is true, the YUV hw accel is enabled. +void set_yuv_hwaccel(bool enabled); + +// returns true if acceleration is enabled or false if not +bool get_yuv_hwaccel(); + +void set_force_aspect_ratio(bool bEnabled); + +bool get_force_aspect_ratio(); + +#ifdef USE_OPENGL +// sets the value of g_bUseOpenGL +void set_use_opengl(bool enabled); + +// returns value of g_bUseOpenGL +bool get_use_opengl(); +#endif // USE_OPENGL + +#endif diff --git a/vldp2/940/interface_920.c b/vldp2/940/interface_920.c new file mode 100644 index 000000000..2d46e4b45 --- /dev/null +++ b/vldp2/940/interface_920.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include "interface_940.h" + +// this is our shared vars structure +struct libmpeg2_shared_vars_s g_SharedVars; + +struct libmpeg2_shared_vars_s *g_pShared = NULL; + +#ifndef GP2X +#include +pthread_t g_thread940; +#endif + +// check for incoming messages from cpu2 +void mp2_920_think() +{ + // if CPU2 has an incoming frame for us ... + if (g_pShared->uAckFrameCount != g_pShared->uReqFrameCount) + { + if ((g_pShared->uReqFrameCount % 30) == 0) + { + printf("TODO : received incoming frame %u\n", g_pShared->uReqFrameCount); + } + + // acknowledge that we received the frame + g_pShared->uReqFrameCount = g_pShared->uAckFrameCount; + } + + // if we have a log message coming in ... + if (g_pShared->uAckLogCount != g_pShared->uReqLogCount) + { + // TODO : store this somewhere else + printf("CPU2 LOG: %s\n", g_pShared->logStr); + + // tell cpu2 that we received the log message + g_pShared->uReqLogCount = g_pShared->uAckLogCount; + } + + assert(g_pShared->uCorruptTest == 55); // make sure buffer hasn't overflowed +} + +// sleep function that also thinks to ensure that we don't get into a "deadlock" situation with the other cpu +void mp2_920_sleep_ms(unsigned int uMs) +{ + mp2_920_think(); + usleep(1000 * uMs); +} + +void mp2_920_send_cmd(int cmd) +{ + g_pShared->uReqCmd = cmd; + + // increase counter to let cpu2 know we have a new command ... + g_pShared->uReqCount++; + + // wait for cpu2 to accept our command + while (g_pShared->uAckCount != g_pShared->uReqCount) + { + mp2_920_sleep_ms(1); + } +} + +void mp2_920_decode_mpeg(unsigned char *pBufStart, unsigned int uBufLength) +{ + if (uBufLength > INBUFSIZE) + { + fprintf(stderr, "decode_mpeg uBufLength is too big\n"); + return; + } + + // if we need to wait for cpu2 to finish with a buffer before we pass more schlop into it + while ((g_pShared->uReqBufCount - g_pShared->uAckBufCount) > 1) + { + printf("Waiting for cpu2 to finish with the buffer...\n"); // debug + mp2_920_sleep_ms(1); + } + + // use an unused buffer + g_pShared->uReqInBuf++; + g_pShared->uReqInBuf = g_pShared->uReqInBuf % INBUFCOUNT; // wraparound + g_pShared->uReqBufCount++; + + // copy mpeg chunk into buffer for cpu2 + memcpy(g_pShared->inBuf[g_pShared->uReqInBuf], pBufStart, uBufLength); + + // tell cpu2 how big this buffer is + g_pShared->uInBufSize[g_pShared->uReqInBuf] = uBufLength; + + mp2_920_send_cmd(C940_LIBMPEG2_DECODE); // do it! +} + +void mp2_920_reset_mpeg() +{ + mp2_920_send_cmd(C940_LIBMPEG2_RESET); // do it! +} + +#ifndef GP2X +extern void *mp2_940_start(void *ignored); +#endif // GP2X + +int mp2_920_init() +{ + int iSuccess = 0; + +#ifdef GP2X + // TODO : set g_pShared to a memory location +#else + // for thread testing + g_pShared = &g_SharedVars; +#endif // GP2X + + // clear entire structure to 0 + memset(g_pShared, 0, sizeof(struct libmpeg2_shared_vars_s)); + printf("shared variables have been cleared\n"); + g_pShared->uCorruptTest = 55; // make sure that the buffer is not overflowed + +#ifdef GP2X + // TODO : cpu initialization stuff ... +#else + // start 2nd "cpu" (using threads for debugging) + if (pthread_create(&g_thread940, NULL, mp2_940_start, 0) == 0) + { + iSuccess = 1; + } + else + { + fprintf(stderr, "Thread creation failed\n"); + } +#endif // GP2X + + return iSuccess; +} + +void mp2_920_shutdown() +{ + mp2_920_send_cmd(C940_QUIT); // send quit message +} + diff --git a/vldp2/940/interface_920.h b/vldp2/940/interface_920.h new file mode 100644 index 000000000..bb2f18c4b --- /dev/null +++ b/vldp2/940/interface_920.h @@ -0,0 +1,8 @@ + +void mp2_920_decode_mpeg(unsigned char *pBufStart, unsigned int uBufLength); + +void mp2_920_reset_mpeg(); + +int mp2_920_init(); + +void mp2_920_shutdown(); diff --git a/vldp2/940/interface_940.c b/vldp2/940/interface_940.c new file mode 100644 index 000000000..4d4035421 --- /dev/null +++ b/vldp2/940/interface_940.c @@ -0,0 +1,271 @@ +/* + * vldp_940_interface.c + * + * Copyright (C) 2007 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// contains the "thread" that will eventually run on another cpu (940) + +#ifdef WIN32 +#include "../vc++/inttypes.h" +#else +#include +#endif + +#include "mpeg2.h" +#include "video_out.h" +#include "interface_940.h" + +//////////////////////////////////////////////// + +#ifndef NULL +#define NULL 0 +#endif // NULL + +static mpeg2dec_t *g_mpeg_data = 0; // structure for libmpeg2's state +static vo_instance_t *s_video_output = 0; + +static struct libmpeg2_shared_vars_s *g_pShared = 0; + +//////////////////////////////////////////////// + +void mpo_strncpy(char *dst, const char *src, unsigned int uLimit) +{ + unsigned int u = 0; + + for (;;) + { + dst[u] = src[u]; + + // if we've reached the null terminator, then break + if (src[u] == 0) + { + break; + } + + u++; + + // if we've reached our buffer limit + if (u >= uLimit) + { + // terminate string, then bail + dst[u-1] = 0; + break; + } + } +} + +void do_error(const char *s) +{ + mpo_strncpy(g_pShared->logStr, s, sizeof(g_pShared->logStr)); + g_pShared->uAckLogCount++; + + // wait until cpu1 has received this log message, because we don't want log messages to get lost + while (g_pShared->uReqLogCount != g_pShared->uAckLogCount); +} + +///////////////// + +// decode_mpeg2 function taken from mpeg2dec.c and optimized a bit +static void decode_mpeg2 (uint8_t * current, uint8_t * end) +{ + const mpeg2_info_t * info; + int state; + vo_setup_result_t setup_result; + + mpeg2_buffer (g_mpeg_data, current, end); + + info = mpeg2_info (g_mpeg_data); + // loop until we return (state is -1) + for (;;) + { + state = mpeg2_parse (g_mpeg_data); + switch (state) + { + case -1: + return; + case STATE_SEQUENCE: + /* might set nb fbuf, convert format, stride */ + /* might set fbufs */ + if (s_video_output->setup (s_video_output, info->sequence->width, + info->sequence->height, &setup_result)) + { + do_error("display setup failed"); + } + + if (setup_result.convert) + mpeg2_convert (g_mpeg_data, setup_result.convert, NULL); + + // if this driver offers a setup_fbuf callback ... +// else if (s_video_output->setup_fbuf) +// we KNOW we offer a setup_fbuf function, so get rid of this conditional + { + uint8_t * buf[3]; + void * id; + + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + } + break; + case STATE_PICTURE: + /* might skip */ + /* might set fbuf */ + + // all possible stuff we could've done here was removed because the null driver + // doesn't do any of it + + break; + case STATE_PICTURE_2ND: + /* should not do anything */ + break; + case STATE_SLICE: + case STATE_END: + /* draw current picture */ + /* might free frame buffer */ + // if the init hasn't been called yet, this may fail so we have to put the conditional + if (info->display_fbuf) + { + s_video_output->draw (s_video_output, info->display_fbuf->buf, + info->display_fbuf->id); + } + + break; + } // end switch + } // end endless for loop +} + +///////////////// + +// returns C940_NO_COMMAND is no command is waiting +int mp2_940_peek_command() +{ + int iResult = C940_NO_COMMAND; + + // if a new command is waiting + if (g_pShared->uAckCount != g_pShared->uReqCount) + { + iResult = g_pShared->uReqCmd; + } + + return iResult; +} + +// tell cpu1 that cpu2 has received the command +void mp2_940_ack_command() +{ + g_pShared->uAckCount = g_pShared->uReqCount; +} + +void mp2_940_do_decode() +{ + // copy variables we need before we ack + unsigned int uWhichBuf = g_pShared->uReqInBuf; + unsigned int uBufSize = g_pShared->uInBufSize[uWhichBuf]; + unsigned char *pBufStart = g_pShared->inBuf[uWhichBuf]; + unsigned char *pBufEnd = pBufStart + uBufSize; + + if (uBufSize == 0) + { + do_error("mp2_940_do_decode: uBufSize is 0! This can't be right..."); + } + + // tell CPU1 that we will start decoding the proper buffer + mp2_940_ack_command(); + + decode_mpeg2(pBufStart, pBufEnd); + + // tell cpu1 that we're done with this buffer + g_pShared->uAckBufCount = g_pShared->uReqBufCount; +} + +void mp2_940_do_reset() +{ + mpeg2_partial_init(g_mpeg_data); + mp2_940_ack_command(); +} + +// when building on x86/linux to test this stuff ... +extern struct libmpeg2_shared_vars_s g_SharedVars; + +void mp2_940_setup_g_pShared() +{ +#ifdef GP2X + // TODO : g_pShared should point to a static memory location +#else + g_pShared = &g_SharedVars; +#endif // GP2X +} + +// this is the main function that starts on the 940 +void *mp2_940_start(void *ignored) +{ + int done = 0; + + mp2_940_setup_g_pShared(); + + s_video_output = (vo_instance_t *) vo940_open(); // open 'null' driver (we just pass decoded frames to parent thread) + if (s_video_output) + { + g_mpeg_data = mpeg2_init(); + } + else + { + do_error("VLDP : Error opening LIBVO!"); + done = 1; + } + + do_error("CPU2 Running!"); // not really an error :) + + // wait for commands from CPU1 + while (!done) + { + int iCmd = mp2_940_peek_command(); + switch (iCmd) + { + default: // no command + break; + case C940_QUIT: + done = 1; + mp2_940_ack_command(); + break; + case C940_LIBMPEG2_DECODE: + mp2_940_do_decode(); + break; + case C940_LIBMPEG2_RESET: + mp2_940_do_reset(); + break; + } + } // end while we have not received a quit command + + do_error("CPU2 shutting down ..."); + + mpeg2_close(g_mpeg_data); // shutdown libmpeg2 + + if (s_video_output->close) + { + s_video_output->close(s_video_output); // shutdown video driver + } + + return 0; +} + diff --git a/vldp2/940/interface_940.h b/vldp2/940/interface_940.h new file mode 100644 index 000000000..963338cfc --- /dev/null +++ b/vldp2/940/interface_940.h @@ -0,0 +1,105 @@ +#ifndef VLDP_940_INTERFACE_H +#define VLDP_940_INTERFACE_H + +// the size of the input buffers +#define INBUFSIZE 4096 +#define INBUFCOUNT 2 + +// libmpeg2 needs 3 output buffers! +#define OUTBUFCOUNT 3 + +// The biggest buffer we expect to ever use (Y surface, 720x480 resolution, 8 bits per pixel) +// Increase this if you need more space. +#define OUTBUFSIZE (720*480) + +// the maximum size of the null-terminated log string returned by CPU2 +#define LOG_STRING_SIZE 320 + +#ifndef NULL +#define NULL 0 +#endif // NULL + +// commands from CPU1 to CPU2 +enum +{ + // no command is waiting + C940_NO_COMMAND = 0, + + // tells program to shutdown (only really used when we're testing this code with threads) + C940_QUIT, + + // decodes from inBuf1 + C940_LIBMPEG2_DECODE, + + // resets libmpeg2 to start decoding a new mpeg stream + C940_LIBMPEG2_RESET +}; + +// status of CPU2 for CPU1 +enum +{ + S940_BUSY = 200, + S940_READY, + S940_ERR +}; + +struct libmpeg2_shared_vars_s +{ + // VARIABLES READ/WRITE BY CPU1, READ-ONLY BY CPU2 + + // input buffers + unsigned char inBuf[INBUFCOUNT][INBUFSIZE]; + + // the amount of bytes used in the input buffer (doesn't have to take up full size) + unsigned int uInBufSize[INBUFCOUNT]; + + // which input buffer CPU2 should use + unsigned int uReqInBuf; + + // requested command + unsigned int uReqCmd; + + // request counter (so cpu2 knows when cpu1 has sent a command) + unsigned int uReqCount; + + // counter to tell whether cpu2 is keeping in sync with us so we don't fill the buffers too quickly + unsigned int uReqBufCount; + + // cpu1's frame counter (so cpu2 knows when cpu1 has received the frame) + unsigned int uReqFrameCount; + + // cpu1's log counter (so cpu2 knows when cpu1 has received log message) + unsigned int uReqLogCount; + + // VARIABLES READ/WRITE BY CPU2, READ-ONLY BY CPU1 + + // acknowledgement counter (so cpu1 knows when cpu2 has received the command) + unsigned int uAckCount; + + // to tell cpu1 that we've finished processing the inbuf + unsigned int uAckBufCount; + + // the output resolution of the frame + unsigned int uOutX; + unsigned int uOutY; + + // which output buffer is 'live' + unsigned int uAckOutBuf; + + // # of frames we've displayed (so CPU1 knows when a new frame is available) + unsigned int uAckFrameCount; + + // log counter, so CPU1 knows when a new log string from CPU2 is available + unsigned int uAckLogCount; + + // null-terminated log string + char logStr[LOG_STRING_SIZE]; + + // where the YUV frame will be stored + unsigned char outBuf[OUTBUFCOUNT][3][OUTBUFSIZE]; + + unsigned int uCorruptTest; +}; + +#endif // VLDP_940_INTERFACE_H + diff --git a/vldp2/940/main920.c b/vldp2/940/main920.c new file mode 100644 index 000000000..e5ababa06 --- /dev/null +++ b/vldp2/940/main920.c @@ -0,0 +1,45 @@ +#include +#include // for memcpy +#include "interface_920.h" + +int main(int argc, char **argv) +{ + if (argc == 2) + { + FILE *F = fopen(argv[1], "rb"); + if (F) + { + unsigned char buf[4096]; + mp2_920_init(); + + for (;;) + { + size_t uBytesRead = fread(buf, 1, sizeof(buf), F); + + mp2_920_decode_mpeg(buf, uBytesRead); + + // we're done! + if (uBytesRead < sizeof(buf)) + { + break; + } + } + fclose(F); + + mp2_920_shutdown(); + } + else + { + printf("File %s could not be opened\n", argv[1]); + } + } + else + { + printf("usage: %s \n", argv[0]); + } + + printf("Main returning\n"); + + return 0; +} + diff --git a/vldp2/940/video_out_940.c b/vldp2/940/video_out_940.c new file mode 100644 index 000000000..f067d7c8a --- /dev/null +++ b/vldp2/940/video_out_940.c @@ -0,0 +1,97 @@ +/* + * video_out_sdl.c + * + * Copyright (C) 2000-2002 Ryan C. Gordon and + * Dominik Schnitzer + * + * SDL info, source, and binaries can be found at http://www.libsdl.org/ + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +//#include "config.h" + + +#include + +#include "video_out.h" +#include "interface_940.h" + +extern struct libmpeg2_shared_vars_s *g_pShared; + +// we expect this function to get called 3 times +static void vo940_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + static unsigned int uWhichBuf = 0; + + buf[0] = g_pShared->outBuf[uWhichBuf][0]; + buf[1] = g_pShared->outBuf[uWhichBuf][1]; + buf[2] = g_pShared->outBuf[uWhichBuf][2]; + + // id will refer to the buffer index + *id = (void *) uWhichBuf; + + uWhichBuf++; + + // wraparound (this should never happen, because this function should only be called 3 times) + uWhichBuf = uWhichBuf % OUTBUFCOUNT; +} + +static void vo940_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + // indicate which buffer has the new frame + g_pShared->uAckOutBuf = (unsigned int) id; + + // tell cpu1 that we have a new frame + g_pShared->uAckFrameCount = (g_pShared->uAckFrameCount + 1); + + // wait for CPU1 to get the new frame + while (g_pShared->uReqFrameCount != g_pShared->uAckFrameCount) + { + } +} + +static int vo940_setup (vo_instance_t * _instance, int width, int height, + vo_setup_result_t * result) +{ + g_pShared->uOutX = width; + g_pShared->uOutY = height; + result->convert = NULL; + return 0; +} + +// don't want to use malloc, because the 2nd cpu doesn't have this function +vo_instance_t g_vo940_instance; + +vo_instance_t * vo940_open (void) +{ + vo_instance_t *instance = &g_vo940_instance; + + instance->setup = vo940_setup; + instance->setup_fbuf = vo940_setup_fbuf; + instance->set_fbuf = NULL; + instance->start_fbuf = NULL; + instance->discard = NULL; + instance->draw = vo940_draw_frame; + instance->close = NULL; + + return (vo_instance_t *) instance; +} + diff --git a/vldp2/AUTHORS b/vldp2/AUTHORS new file mode 100644 index 000000000..465cddc2d --- /dev/null +++ b/vldp2/AUTHORS @@ -0,0 +1,31 @@ +Aaron Holtzman started the project and +made the initial working implementation. + +Michel Lespinasse did major changes for speed and +mpeg conformance and is the current maintainer. Most of the current +code was (re)written by him. + +Other contributors include: + Bruno Barreyra - build fixes + Gildas Bazin - mingw32 port + Alexander W. Chin - progressive_seq fix + Stephen Crowley - build fixes + Didier Gautheron - bug fixes + Ryan C. Gordon - SDL support + Peter Gubanov - MMX IDCT scheduling + Håkan Hjort - Solaris fixes, mlib code + Gerd Knorr - Xv support + David I. Lehn - motion_comp mmx code + Olie Lho - MMX yuv2rgb routine + Rick Niles - build fixes + Real Ouellet - g200 fixes + Bajusz Peter - motion comp fixes + Franck Sicard - x11 fixes + Brion Vibber - x11 fixes + Martin Vogt - reentrancy fixes + Fredrik Vraalsen - general hackage and stuff + +(let me know if I forgot anyone) + +Thanks to David Schleef for creating me an account on his ppc g4 +machine and making it possible for me to work on the altivec code. diff --git a/vldp2/COPYING b/vldp2/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/vldp2/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/vldp2/ChangeLog b/vldp2/ChangeLog new file mode 100644 index 000000000..6c553ce37 --- /dev/null +++ b/vldp2/ChangeLog @@ -0,0 +1,81 @@ +mpeg2dec-0.3.1 Fri Dec 13 22:15:36 PST 2002 +-integrated CPU detection code +-alpha IDCT/MC optimizations +-C IDCT optimizations +-fixed all known memory leaks +-workarounds for HPPA/IA64/sparc build issues + +mpeg2dec-0.3.0 Wed Nov 27 23:23:23 PST 2002 +-first release using the new libmpeg2 API +-improved error handling - does not seek to the next sequence header anymore +-more minor optimizations (about 7% faster than 0.2.1) +-support for streams higher than 2800 pixels +-added SIMD optimizations to the VC++ port + +mpeg2dec-0.2.1 Sun Mar 17 23:24:04 PST 2002 +-altivec optimizations - provides 2.5x speedup for g4 processors +-fixed MC code - should not crash on bad streams anymore +-much higher tolerance to corrupted streams +-support for high definition streams +-support for VC++ compiler +-various mpeg flags exported to libvo + +mpeg2dec-0.2.0 Thu Feb 15 20:12:34 PST 2001 +-support for field pictures +-new 3Dnow/SSE accelerations for motion compensation and color conversion +-full libmpeg2 and libvo reentrancy +-various portability enhancements - from big iron to embedded to windows +-major libvo rewrite - new API more adapted to synchro and speed enhancements +-pgmpipe output for piping with other programs +-make install actually installs +-various cleanups - including removal of the infamous HACK_MODE + +mpeg2dec-0.1.7 Thu Nov 2 21:38:33 PST 2000 +-fix the solaris mlib code back bup +-added Xv support +-major cruft removal +-cleanup on motion_comp +-remove mb_buffer goofiness +-new yuv2rgb code +-SDL display code added +-faster motion_comp_c code +-moved codec, display code into separate libraries +-test suite +-lots of conformance fixes +-rewrite of the parsing code +-MMX/SSE runtime detection and support +-new configuration code + +mpeg2dec-0.1.6 Wed Mar 22 09:45:44 PST 2000 +-enhanced g200 +-solaris fixes +-inlined, rewritten bitstream code (much faster now) +-moved colorspace conversion code into yuv2rgb.c + +mpeg2dec-0.1.5 Mon Dec 13 23:08:43 EST 1999 +-numerous bugfixes to mga_vid and x11 displays. +-fix clipping in motion_comp +-fix interlaced macroblocks in frame pictures +-add preliminary MMX support + +mpeg2dec-0.1.4 Fri Dec 10 00:28:43 EST 1999 +-New bitstream interface +-fixed screwy first macroblock +-fixed mga_vid build problems +-fixed pale x11 output + +mpeg2dec-0.1.3 Mon Dec 6 19:18:57 EST 1999 +-fixed Invalid macroblock type bug. +-fixed Makefile for mga_vid + +mpeg2dec-0.1.2 Mon Dec 6 19:18:57 EST 1999 +-fixed AC coefficient bug. Output looks pretty + now. +-inv_quantize code moved into parse. + +mpeg2dec-0.1.1 Sun Dec 5 19:18:57 EST 1999 +-added X11 display interface +-fixed minor bug mga_vid init bug + +mpeg2dec-0.1.0 Sun Dec 5 01:18:57 EST 1999 +-First release diff --git a/vldp2/HOW_TO_COMPILE_UNIX.txt b/vldp2/HOW_TO_COMPILE_UNIX.txt new file mode 100644 index 000000000..5f1c18b52 --- /dev/null +++ b/vldp2/HOW_TO_COMPILE_UNIX.txt @@ -0,0 +1,21 @@ +How to compile libvldp2.so +by Matt Ownby (Mar 20th, 2003) +------------------------------ + +This source code is based on libmpeg2 (http://libmpeg2.sf.net). + +Libmpeg2 has a nice ./configure script, which I took advantage of, but I made +my own Makefiles for the final build because I really have a hard time using +automake/autoconf. + +So to compile under linux, you'd do: + + ./configure + make -f Makefile.linux + +Compiling under Mac OSX is similar: + + ./configure + make -f Makefile.osx + +That's all it takes. diff --git a/vldp2/HOW_TO_COMPILE_WIN32.txt b/vldp2/HOW_TO_COMPILE_WIN32.txt new file mode 100644 index 000000000..9c2a1825e --- /dev/null +++ b/vldp2/HOW_TO_COMPILE_WIN32.txt @@ -0,0 +1,2 @@ +Vldp2 is now compiled from the main daphne project from within Visual Studio. + diff --git a/vldp2/INSTALL b/vldp2/INSTALL new file mode 100644 index 000000000..30a07fecf --- /dev/null +++ b/vldp2/INSTALL @@ -0,0 +1,58 @@ +Unix build instructions +----------------------- + +./configure +make +make install + +If you install from CVS you'll have to run ./bootstrap first + + +Building for win32 +------------------ + +There are at least three ways to do it: + +- natively on Windows using Microsoft VC++ and the vc++ project + included in this distribution. + +- natively on Windows using MSYS + MINGW (www.mingw.org) (MSYS is a + minimal build environnement to compile unixish projects under + windows. It provides all the common unix tools like sh, gmake...) + +- or on Linux, using the mingw32 cross-compiler + + +Building using MSYS + MINGW on windows +-------------------------------------- + +First you will need to download and install the latest MSYS (version +1.0.7 as of now) and MINGW. The installation is really easy. Begin +with the MSYS auto-installer and once this is done, extract MINGW into +c:\msys\1.0\mingw. You also have to remember to remove the make +utility included with MINGW as it conflicts with the one from MSYS +(just rename or remove c:\msys\1.0\mingw\bin\make.exe). + +http://prdownloads.sourceforge.net/mingw/MSYS-1.0.7-i686-2002.04.24-1.exe +http://prdownloads.sourceforge.net/mingw/MinGW-1.1.tar.gz + +Then you can build the package using: +# ./configure +# make + + +Building using the mingw32 cross-compiler +----------------------------------------- + +You need to install mingw32 first. For Debian GNU/Linux users, there +is a mingw32 package. Otherwise you might get it from the mingw site +at http://www.mingw.org/download.shtml. + +The videolan project also keeps precompiled mingw32 binaries at +http://www.videolan.org/vlc/windows.html . If you install these, +you'll have to set your PATH accordingly to include +/usr/local/cross-tools/bin too. + +The build should then proceed using something like: +# CC=i586-mingw32msvc-gcc ./configure --host=i586-mingw32msvc +# make diff --git a/vldp2/Makefile.am b/vldp2/Makefile.am new file mode 100644 index 000000000..262d2915c --- /dev/null +++ b/vldp2/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = autotools include libmpeg2 libvo doc src vc++ test + +EXTRA_DIST = bootstrap diff --git a/vldp2/Makefile.freebsd b/vldp2/Makefile.freebsd new file mode 100644 index 000000000..6e8ede7fc --- /dev/null +++ b/vldp2/Makefile.freebsd @@ -0,0 +1,39 @@ +# Makefile for VLDP2 +# Written by Matt Ownby + +# TODO: Add dependencies + +CC = gcc +#DFLAGS = -g -DVLDP_DEBUG + +# Benchmarking version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops + +CFLAGS = ${DFLAGS} `sdl11-config --cflags` -I./include +LIBS = `sdl11-config --libs` + +OBJS = vldp/vldp.o vldp/vldp_internal.o vldp/mpegscan.o \ + libmpeg2/cpu_accel.o libmpeg2/alloc.o libmpeg2/cpu_state.o \ + libmpeg2/decode.o libmpeg2/header.o libmpeg2/motion_comp.o \ + libmpeg2/idct.o libmpeg2/idct_mmx.o libmpeg2/motion_comp_mmx.o \ + libmpeg2/slice.o \ + libvo/video_out.o libvo/video_out_null.o + +LIBNAME = libvldp2.so + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: vldp2 + +vldp2: ${OBJS} + ${CC} -shared -o ${LIBNAME} ${OBJS} ${LIBS} + cp ${LIBNAME} ../../. + +clean: + rm ${LIBNAME} ${OBJS} diff --git a/vldp2/Makefile.in b/vldp2/Makefile.in new file mode 100644 index 000000000..f786bcd2d --- /dev/null +++ b/vldp2/Makefile.in @@ -0,0 +1,521 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = autotools include libmpeg2 libvo doc src vc++ test + +EXTRA_DIST = bootstrap +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ + Makefile.in NEWS TODO acinclude.m4 aclocal.m4 configure \ + configure.in +DIST_SUBDIRS = $(SUBDIRS) +all: all-recursive + +.SUFFIXES: + +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) + +$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = . +distdir = $(PACKAGE)-$(VERSION) + +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } + +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkinstalldirs) $(distdir)/libmpeg2 + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist dist-all: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + $(am__remove_distdir) + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ + && rm -f $(distdir).tar.gz \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' +distuninstallcheck: + cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf autom4te.cache +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ + clean-generic clean-libtool clean-recursive ctags \ + ctags-recursive dist dist-all dist-gzip distcheck distclean \ + distclean-generic distclean-libtool distclean-recursive \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am dvi-recursive info info-am info-recursive install \ + install-am install-data install-data-am install-data-recursive \ + install-exec install-exec-am install-exec-recursive \ + install-info install-info-am install-info-recursive install-man \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-libtool mostlyclean-recursive pdf pdf-am \ + pdf-recursive ps ps-am ps-recursive tags tags-recursive \ + uninstall uninstall-am uninstall-info-am \ + uninstall-info-recursive uninstall-recursive + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/Makefile.lin940 b/vldp2/Makefile.lin940 new file mode 100644 index 000000000..8b0f30bbf --- /dev/null +++ b/vldp2/Makefile.lin940 @@ -0,0 +1,40 @@ +# Makefile for VLDP2 +# Written by Matt Ownby + +# TODO: Add dependencies + +CC = gcc +#DFLAGS = -pg +DFLAGS = -g -DVLDP_DEBUG + +# Benchmarking version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops + +CFLAGS = ${DFLAGS} `sdl-config --cflags` -I./include -Wall +LIBS = `sdl-config --libs` + +OBJS = libmpeg2/cpu_accel.o libmpeg2/alloc.o libmpeg2/cpu_state.o \ + libmpeg2/decode.o libmpeg2/header.o libmpeg2/motion_comp.o \ + libmpeg2/idct.o libmpeg2/idct_mmx.o libmpeg2/motion_comp_mmx.o \ + libmpeg2/slice.o \ + libvo/video_out.o \ + 940/interface_940.o 940/video_out_940.o 940/interface_920.o \ + 940/main920.o + +EXENAME = test920 + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: vldp2 + +vldp2: ${OBJS} + ${CC} -o ${EXENAME} ${OBJS} ${LIBS} + +clean: + rm ${EXENAME} ${OBJS} diff --git a/vldp2/Makefile.linux b/vldp2/Makefile.linux new file mode 100644 index 000000000..529c264c1 --- /dev/null +++ b/vldp2/Makefile.linux @@ -0,0 +1,41 @@ +# Makefile for VLDP2 +# Written by Matt Ownby + +# TODO: Add dependencies + +CC = gcc +#DFLAGS = -pg +#DFLAGS = -g -DVLDP_DEBUG + +# Benchmarking version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +CFLAGS = ${DFLAGS} `sdl-config --cflags` -I./include +LIBS = `sdl-config --libs` + +OBJS = vldp/vldp.o vldp/vldp_internal.o vldp/mpegscan.o \ + libmpeg2/cpu_accel.o libmpeg2/alloc.o libmpeg2/cpu_state.o \ + libmpeg2/decode.o libmpeg2/header.o libmpeg2/motion_comp.o \ + libmpeg2/idct.o libmpeg2/idct_mmx.o libmpeg2/motion_comp_mmx.o \ + libmpeg2/slice.o \ + libvo/video_out.o libvo/video_out_null.o + +LIBNAME = libvldp2.so + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: vldp2 + +vldp2: ${OBJS} + ${CC} -shared -o ${LIBNAME} ${OBJS} ${LIBS} + cp ${LIBNAME} ../../. + +clean: + rm ${LIBNAME} ${OBJS} diff --git a/vldp2/Makefile.linux_x64 b/vldp2/Makefile.linux_x64 new file mode 100644 index 000000000..66238d288 --- /dev/null +++ b/vldp2/Makefile.linux_x64 @@ -0,0 +1,43 @@ +# Makefile for VLDP2 +# Written by Matt Ownby + +# IMPORTANT: vldp2 needs to be configured with "--disable-accel-detect" + +# TODO: Add dependencies + +CC = gcc +#DFLAGS = -pg +#DFLAGS = -g -DVLDP_DEBUG + +# Benchmarking version +#DFLAGS = -O3 -march=i686 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +DFLAGS = -O3 -funroll-loops -fPIC \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DFILE_OFFSET_BITS=64 + +CFLAGS = ${DFLAGS} `sdl-config --cflags` -I./include +LIBS = `sdl-config --libs` + +OBJS = vldp/vldp.o vldp/vldp_internal.o vldp/mpegscan.o \ + libmpeg2/cpu_accel.o libmpeg2/alloc.o libmpeg2/cpu_state.o \ + libmpeg2/decode.o libmpeg2/header.o libmpeg2/motion_comp.o \ + libmpeg2/idct.o libmpeg2/idct_mmx.o libmpeg2/motion_comp_mmx.o \ + libmpeg2/slice.o \ + libvo/video_out.o libvo/video_out_null.o + +LIBNAME = libvldp2.so + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: vldp2 + +vldp2: ${OBJS} + ${CC} -shared -o ${LIBNAME} ${OBJS} ${LIBS} + cp ${LIBNAME} ../../. + +clean: + rm ${LIBNAME} ${OBJS} diff --git a/vldp2/Makefile.osx b/vldp2/Makefile.osx new file mode 100644 index 000000000..f8155e498 --- /dev/null +++ b/vldp2/Makefile.osx @@ -0,0 +1,43 @@ +# Makefile for VLDP2 +# Written by Matt Ownby + +# TODO: Add dependencies + +CC = gcc +#DFLAGS = -g + +# Benchmarking version +#DFLAGS = -O3 -fomit-frame-pointer -funroll-loops -DVLDP_BENCHMARK + +# Standard version +DFLAGS = -O3 -fomit-frame-pointer -funroll-loops + +CFLAGS = ${DFLAGS} `sdl-config --cflags` -I./include +SLIBS = /usr/local/lib +#LIBS = $(SLIBS)/libSDL.a +LIBS = + +# compiling in this altivec stuff won't hurt and might help ... +OBJS = vldp/vldp.o vldp/vldp_internal.o vldp/mpegscan.o \ + libmpeg2/cpu_accel.o libmpeg2/alloc.o libmpeg2/cpu_state.o \ + libmpeg2/decode.o libmpeg2/header.o libmpeg2/motion_comp.o \ + libmpeg2/idct.o \ + libmpeg2/slice.o \ + libmpeg2/idct_altivec.o libmpeg2/motion_comp_altivec.o \ + libvo/video_out.o libvo/video_out_null.o + +LIBNAME = libvldp2.so + +.SUFFIXES: .c + +.c.o: + ${CC} ${CFLAGS} -c $< -o $@ + +all: vldp2 + +vldp2: ${OBJS} + ${CC} -o ${LIBNAME} ${OBJS} -bundle -bundle_loader ../../daphne + cp ${LIBNAME} ../../. + +clean: + rm ${LIBNAME} ${OBJS} diff --git a/vldp2/NEWS b/vldp2/NEWS new file mode 100644 index 000000000..b14c395a6 --- /dev/null +++ b/vldp2/NEWS @@ -0,0 +1,86 @@ +mpeg2dec-0.3.1 Fri Dec 13 22:15:36 PST 2002 + +This is mainly a maintainance release. On the API side, libmpeg2 now +includes some CPU detection code - so it will by default automatically +use whatever features are available on the CPU it runs on. There is a +function to override this, mainly for testing purposes. + +There has been a few speed improvements too - there is now some alpha +specific code that makes the library more than twice faster on these +machines, and the C IDCT has also been improved which translates to +about 6% speed improvement for people who use this code. + +Finally, a few bugs have been fixed, most notably some memory leaks +and sparc/HPPA/IA64 build issues. + + +mpeg2dec-0.3.0 Wed Nov 27 23:23:23 PST 2002 + +The main goal of this release is to preview the new libmpeg2 API. The +old API was not flexible enough for most users, as a result various +projects (xine, mplayer etc...) ended up rewriting their own versions +of decode.c. The goal with this new API is that it will be flexible +enough for people to actually use it instead of rolling their own :) + +In many respects, this code is less mature than the 0.2.x codebase +was. There will probably be a few changes in future versions regarding +color conversion and CPU detection, to cite a few. The goal is to get +a release out and then add the missing features in future 0.3.x +releases. + +In addition to the new API, there are a few new features already too. +For example, we now have improved the error handling, which should +help applications who do seeking for example. Also a few minor speed +improvements (about 7%) and SIMD optimizations now enabled in the VC++ +port too. + + +mpeg2dec-0.2.1 Sun Mar 17 23:24:04 PST 2002 + +Two major new features: First, a much higher tolerance to corrupted +streams. Instead of just segfaulting, we should now be able to keep +going after errors. There is no test suite for this feature yet though. + +Second, the altivec optimizations provide a huge speedup (more than +2.5x) on ppc g4 machines. + +High definition video streams are now supported. + +There is also native support for compiling using VC++. + +And, the libvo interface has been slightly extended so people can more +easily make use of the various mpeg flags. + + +mpeg2dec-0.2.0 Thu Feb 15 20:12:34 PST 2001 + +The most important new feature is the support for field +pictures. mpeg2dec is now able to display any conformant +"main profile @ main level" mpeg-2 stream. This means any +stream you should actually encounter in practice :) + +We also added some more accelerations for motion compensation and +color conversion - 3Dnow and SSE. Non-x86 accelerations would be +welcome - patches anyone ? + +libmpeg2 and libvo are now fully reentrant. This will enable other +projects to reuse the mpeg2dec codebase without patches. For the same +reason we added support for "make install" + +Libvo has been switched to a new API. The immediate advantage is that +it allowed us to get rid of the "HACK_MODE" setting - you really dont +want to know. In the future this will also help a lot with the +implementation of synchro. + +Portability enhancements - including support for win32 DLLs. This was +done to get into the hearts of a few more developpers :) + + +mpeg2dec-0.1.7 Thu Nov 2 21:38:33 PST 2000 + +First release since march ! Lots of new features : improved +performance, mpeg-1 and mpeg-2 support, integrated demuxer, standards +compliance. + +The major missing feature is mpeg-2 field pictures, this is planned +for mpeg2dec-0.2.0 diff --git a/vldp2/README b/vldp2/README new file mode 100644 index 000000000..085816319 --- /dev/null +++ b/vldp2/README @@ -0,0 +1,198 @@ + + +ABOUT LIBMPEG2 + +libmpeg2 is a free library for decoding mpeg-2 and mpeg-1 video +streams. It is released under the terms of the GPL license. + +The main goals in libmpeg2 development are: + + * Conformance - libmpeg2 is able to decode all mpeg streams that + conform to certain restrictions: "constrained parameters" for + mpeg-1, and "main profile" for mpeg-2. In practice, this is + what most people are using. For streams that follow these + restrictions, we believe libmpeg2 is 100% conformant to the + mpeg standards - and we have a pretty extensive test suite to + check this. + + * Speed - there has been huge efforts there, and we believe + libmpeg2 is the fastest library around for what it + does. Please tell us if you find a faster one ! With typical + video streams as found on DVD's, and doing only decoding with + no display, you should be able to get about 110 fps on a + PIII/666, or 150 fps on an Athlon/950. This is less than 20 + cycles per output pixel. In a real player program, the display + routines will probably take as much time as the actual + decoding ! + + * Portability - most of the code is written in C, and when we + use platform-specific optimizations (typically assembly + routines, currently used for the motion compensation and the + inverse cosine transform stages) we always have a generic C + routine to fall back on. This should be portable to all + architectures - at least we have heard reports from people + running this code on x86, ppc, sparc, arm and + sh4. Assembly-optimized implementations are available on x86 + (MMX) and ppc (altivec) architectures. Ultrasparc (VIS) is + probably the next on the list - we'll see. + + * Reuseability - we do not want libmpeg2 to include any + project-specific code, but it should still include enough + features to be used by very diverse projects. We are only + starting to get there - the best way to help here is to give + us some feedback ! + +The project homepage is at http://libmpeg2.sourceforge.net/ + + +MPEG2DEC + +mpeg2dec is a test program for libmpeg2. It decodes mpeg-1 and mpeg-2 +video streams, and also includes a demultiplexer for mpeg-1 and mpeg-2 +program streams. It is purposely kept simple : it does not include +features like reading files from a DVD, CSS, fullscreen output, +navigation, etc... The main purpose of mpeg2dec is to have a simple +test bed for libmpeg2. + +The libmpeg2 source code is always distributed in the mpeg2dec +package, to make it easier for people to test it. + +The basic usage is to just type "mpeg2dec file" where file is a +demultiplexed mpeg video file. + +The "-s" option must be used for multiplexed (audio and video) mpeg +files using the "program stream" format. These files are usualy found +on the internet or on unencrypted DVDs. + +The "-t" option must be used for multiplexed (audio and video) mpeg +files using the "transport stream" format. These files are usualy +found in digital TV applications. + +The "-o" option is used to select a given output module - for example +to redirect the output to a file. This is also used for performance +testing and conformance testing. + +The "-c" option is used to disable all optimizations. + + +OTHER PROJECTS USING LIBMPEG2 + +libmpeg2 is being used by various other projects, including: + + * xine (http://xine.sourceforge.net/) - started as a simple + mpeg-2 audio and video decoder, but it since became a + full-featured DVD and video media player. + + * MPlayer (http://www.MPlayerHQ.hu) - another good player, it is + also very robust against damaged streams. + + * movietime (http://movietime.sourceforge.net/) - still quite + young, but it looks very promising ! + + * mpeg2decX (http://homepage1.nifty.com/~toku/software_en.html) - + a graphical interface for mpeg2dec for macintosh osX. + + * drip (http://drip.sourceforge.net/) - a DVD to DIVX transcoder. + + * OMS (http://www.linuxvideo.org/oms/) + + * XMPS (http://xmps.sourceforge.net/) + + * GStreamer (http://www.gstreamer.net/) - a framework for + streaming media; it has an mpeg2 decoding plugin based on + libmpeg2. + + * mpeglib (http://mpeglib.sourceforge.net/) - a video decoding + library that usess libmpeg2 when decoding mpeg streams. + + * daphne (http://daphne.rulecity.com/) - a laserdisc arcade game + simulator. + + * GOPchop (http://outflux.net/unix/software/GOPchop/) - a + GOP-accurate editor for MPEG2 streams. + +If you use libmpeg2 in another project, let us know ! + +VideoLAN (http://www.videolan.org/) does not directly use libmpeg2, +but this is still a cool project :) + + +TASKS + +There are several places where we could easily use some help: + + * Documentation: libmpeg2 still has no documentation. Every + project using it has had to figure things out by looking at + the header files, at the mpeg2dec sample application, and by + asking questions. Writing down a nice documentation would make + the code more easily reuseable. + + * Testing: If you find any stream that does not decode right + with libmpeg2, let us know ! The best thing would be to mail + to the libmpeg2-devel mailing list. Also, it would be nice to + build a stress test so we can make sure libmpeg2 never crashes + on bad streams. + + * Coding: There is a small TODO list in the mpeg2dec package, + you can have a look there ! Most items are pretty terse + though. + + * Porting: If you're porting to a new architecture, you might + want to experiment with the compile flags defined in + configure.in . When you figure out whats fastest on your + platform, send us a patch ! + + * Assembly optimizations: We only have x86 and altivec + optimizations yet, it would be worthwhile writing routines for + other architectures, especially those that have SIMD + instruction set extensions ! Also the yuv2rgb x86 routines + could probably be optimized a lot. + + +CVS SNAPSHOTS + +A daily snapshot is created using "make distcheck" every night and +uploaded to http://libmpeg2.sourceforge.net/files/mpeg2dec-snapshot.tar.gz . +It is easier to use than the CVS repository, because you do not need +to have the right versions of automake, autoconf and libtool +installed. It might be convenient when working on a libmpeg2 port for +example. + + +CVS REPOSITORY + +The latest libmpeg2 and mpeg2dec source code can always be found by +anonymous CVS: + +# export CVSROOT=:pserver:anonymous@cvs.libmpeg2.sourceforge.net:/cvsroot/libmpeg2 +# cvs login (Just press Return when prompted for a password) +# cvs checkout mpeg2dec + +You can also browse the latest changes online at +http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libmpeg2/mpeg2dec/ + +The other CVS modules are mpeg2dec-streams for the test suite, and +mpeg2dec-livid for the CVS history of the project while it was still +hosted on the linuxvideo.org servers. + + +MAILING LISTS + +See the subscription information at http://libmpeg2.sourceforge.net/lists.html + +libmpeg2-devel + +This is the main mailing list for technical discussion about +libmpeg2. Anyone wanting to work on libmpeg2, or maybe just stay +informed about the development process, should probably subscribe to +this list. + +libmpeg2-checkins + +All libmpeg2 checkins are announced there. This is a good way to keep +track of what goes into CVS. + +libmpeg2-announce + +This is a very low traffic mailing list, only for announcements of new +versions of libmpeg2. Only project administrators can post there. diff --git a/vldp2/TODO b/vldp2/TODO new file mode 100644 index 000000000..fb6606684 --- /dev/null +++ b/vldp2/TODO @@ -0,0 +1,37 @@ +* fix altivec IDCT (memset block to 0), optimize mmx idct memset too. + +* things we dont implement yet + * more verbose error reporting + * decoding of 4:2:2 streams + * export MC information (for XvMC or for error resilience) + * export quantizer information (for postprocessing filters) + * export header/picture/slice user data + * dont crash on bad streams, make sure we can resync after a while + * possible chunk buffer overflow while reading bits + * dont just fprintf and exit + * synchronization stuff + * IDCT precision with sparse matrixes + * sparc IDCT/MC optimizations; get rid of mlib code + * support for still pictures (decode before receiving next startcode !) + +* structural optimizations + * integrate idct_add and idct_copy into the main idct routine + * do yuv per sub-slice (probably big speed boost) + * try different memory arrangements for pictures (yuyv, stride, ...) + * once we have sync, call draw_frame before decoding I or P not after + +* local optimizations + * use restrict (__restrict__) pointers: int * restrict p; + * reschedule altivec IDCT and MC routines for 7450 chips + * try feig IDCT instead of MSSG c IDCT ? + * review the use of static inline functions + * improve MMX motion comp inner routines + * optimize IDCT for very sparse input matrixes ? + * optimize startcode search loop ? + * bit parsing / DCT parsing optimizations + +* clean up + * clean up header file usage + * clean up yuv2rgb for interlaced pictures (handling of uv) + * clean up picture_t structure (some variables should be local ?) + * clean up slice_init diff --git a/vldp2/acinclude.m4 b/vldp2/acinclude.m4 new file mode 100644 index 000000000..171d57c5b --- /dev/null +++ b/vldp2/acinclude.m4 @@ -0,0 +1,151 @@ +dnl AC_C_RESTRICT +dnl Do nothing if the compiler accepts the restrict keyword. +dnl Otherwise define restrict to __restrict__ or __restrict if one of +dnl those work, otherwise define restrict to be empty. +AC_DEFUN([AC_C_RESTRICT], + [AC_MSG_CHECKING([for restrict]) + ac_cv_c_restrict=no + for ac_kw in restrict __restrict__ __restrict; do + AC_TRY_COMPILE([],[char * $ac_kw p;],[ac_cv_c_restrict=$ac_kw; break]) + done + AC_MSG_RESULT([$ac_cv_c_restrict]) + case $ac_cv_c_restrict in + restrict) ;; + no) AC_DEFINE([restrict],, + [Define as `__restrict' if that's what the C compiler calls + it, or to nothing if it is not supported.]) ;; + *) AC_DEFINE_UNQUOTED([restrict],$ac_cv_c_restrict) ;; + esac]) + +dnl AC_C_BUILTIN_EXPECT +dnl Check whether compiler understands __builtin_expect. +AC_DEFUN([AC_C_BUILTIN_EXPECT], + [AC_CACHE_CHECK([for __builtin_expect],[ac_cv_builtin_expect], + [cat > conftest.c <&AC_FD_CC]); then + ac_cv_builtin_expect=yes + else + ac_cv_builtin_expect=no + fi + rm -f conftest*]) + if test x"$ac_cv_builtin_expect" = x"yes"; then + AC_DEFINE(HAVE_BUILTIN_EXPECT,, + [Define if you have the `__builtin_expect' function.]) + fi]) + +dnl AC_C_ALWAYS_INLINE +dnl Define inline to something appropriate, including the new always_inline +dnl attribute from gcc 3.1 +AC_DEFUN([AC_C_ALWAYS_INLINE], + [AC_C_INLINE + if test x"$GCC" = x"yes" -a x"$ac_cv_c_inline" = x"inline"; then + AC_MSG_CHECKING([for always_inline]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Werror" + AC_TRY_COMPILE([],[__attribute__ ((__always_inline__)) void f (void);], + [ac_cv_always_inline=yes],[ac_cv_always_inline=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_always_inline]) + if test x"$ac_cv_always_inline" = x"yes"; then + AC_DEFINE_UNQUOTED([inline],[__attribute__ ((__always_inline__))]) + fi + fi]) + +dnl AC_C_ATTRIBUTE_ALIGNED +dnl define ATTRIBUTE_ALIGNED_MAX to the maximum alignment if this is supported +AC_DEFUN([AC_C_ATTRIBUTE_ALIGNED], + [AC_CACHE_CHECK([__attribute__ ((aligned ())) support], + [ac_cv_c_attribute_aligned], + [ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + AC_TRY_COMPILE([], + [static char c __attribute__ ((aligned($ac_cv_c_attr_align_try))) = 0; return c;], + [ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try]) + done]) + if test x"$ac_cv_c_attribute_aligned" != x"0"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], + [$ac_cv_c_attribute_aligned],[maximum supported data alignment]) + fi]) + +dnl AC_TRY_CFLAGS (CFLAGS, [ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check if $CC supports a given set of cflags +AC_DEFUN([AC_TRY_CFLAGS], + [AC_MSG_CHECKING([if $CC supports $1 flags]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$1" + AC_TRY_COMPILE([],[],[ac_cv_try_cflags_ok=yes],[ac_cv_try_cflags_ok=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_try_cflags_ok]) + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + ifelse([$2],[],[:],[$2]) + else + ifelse([$3],[],[:],[$3]) + fi]) + +dnl AC_LIBTOOL_NON_PIC ([ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check for nonbuggy libtool -prefer-non-pic +AC_DEFUN([AC_LIBTOOL_NON_PIC], + [AC_MSG_CHECKING([if libtool supports -prefer-non-pic flag]) + mkdir ac_test_libtool; cd ac_test_libtool; ac_cv_libtool_non_pic=no + echo "int g (int i); int f (int i) {return g (i);}" >f.c + echo "int (* hook) (int) = 0; int g (int i) {if (hook) i = hook (i); return i + 1;}" >g.c + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c f.c >/dev/null 2>&1 && \ + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c g.c >/dev/null 2>&1 && \ + ../libtool --mode=link $CC $CFLAGS -prefer-non-pic -o libfoo.la \ + -rpath / f.lo g.lo >/dev/null 2>&1 && + ac_cv_libtool_non_pic=yes + cd ..; rm -fr ac_test_libtool; AC_MSG_RESULT([$ac_cv_libtool_non_pic]) + if test x"$ac_cv_libtool_non_pic" = x"yes"; then + ifelse([$1],[],[:],[$1]) + else + ifelse([$2],[],[:],[$2]) + fi]) + +dnl AC_CHECK_GENERATE_INTTYPES_H (INCLUDE-DIRECTORY) +dnl generate a default inttypes.h if the header file does not exist already +AC_DEFUN([AC_CHECK_GENERATE_INTTYPES], + [rm -f $1/inttypes.h + AC_CHECK_HEADER([inttypes.h],[], + [AC_CHECK_SIZEOF([char]) + AC_CHECK_SIZEOF([short]) + AC_CHECK_SIZEOF([int]) + if test x"$ac_cv_sizeof_char" != x"1" -o \ + x"$ac_cv_sizeof_short" != x"2" -o \ + x"$ac_cv_sizeof_int" != x"4"; then + AC_MSG_ERROR([can not build a default inttypes.h]) + fi + cat >$1/inttypes.h << EOF +/* default inttypes.h for people who do not have it on their system */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H +#if (!defined __int8_t_defined) && (!defined __BIT_TYPES_DEFINED__) +#define __int8_t_defined +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +#ifdef ARCH_X86 +typedef signed long long int64_t; +#endif +#endif +#if (!defined _LINUX_TYPES_H) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifdef ARCH_X86 +typedef unsigned long long uint64_t; +#endif +#endif +#endif +EOF + ])]) diff --git a/vldp2/aclocal.m4 b/vldp2/aclocal.m4 new file mode 100644 index 000000000..ea817af27 --- /dev/null +++ b/vldp2/aclocal.m4 @@ -0,0 +1,4586 @@ +# generated automatically by aclocal 1.7.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl AC_C_RESTRICT +dnl Do nothing if the compiler accepts the restrict keyword. +dnl Otherwise define restrict to __restrict__ or __restrict if one of +dnl those work, otherwise define restrict to be empty. +AC_DEFUN([AC_C_RESTRICT], + [AC_MSG_CHECKING([for restrict]) + ac_cv_c_restrict=no + for ac_kw in restrict __restrict__ __restrict; do + AC_TRY_COMPILE([],[char * $ac_kw p;],[ac_cv_c_restrict=$ac_kw; break]) + done + AC_MSG_RESULT([$ac_cv_c_restrict]) + case $ac_cv_c_restrict in + restrict) ;; + no) AC_DEFINE([restrict],, + [Define as `__restrict' if that's what the C compiler calls + it, or to nothing if it is not supported.]) ;; + *) AC_DEFINE_UNQUOTED([restrict],$ac_cv_c_restrict) ;; + esac]) + +dnl AC_C_BUILTIN_EXPECT +dnl Check whether compiler understands __builtin_expect. +AC_DEFUN([AC_C_BUILTIN_EXPECT], + [AC_CACHE_CHECK([for __builtin_expect],[ac_cv_builtin_expect], + [cat > conftest.c <&AC_FD_CC]); then + ac_cv_builtin_expect=yes + else + ac_cv_builtin_expect=no + fi + rm -f conftest*]) + if test x"$ac_cv_builtin_expect" = x"yes"; then + AC_DEFINE(HAVE_BUILTIN_EXPECT,, + [Define if you have the `__builtin_expect' function.]) + fi]) + +dnl AC_C_ALWAYS_INLINE +dnl Define inline to something appropriate, including the new always_inline +dnl attribute from gcc 3.1 +AC_DEFUN([AC_C_ALWAYS_INLINE], + [AC_C_INLINE + if test x"$GCC" = x"yes" -a x"$ac_cv_c_inline" = x"inline"; then + AC_MSG_CHECKING([for always_inline]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Werror" + AC_TRY_COMPILE([],[__attribute__ ((__always_inline__)) void f (void);], + [ac_cv_always_inline=yes],[ac_cv_always_inline=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_always_inline]) + if test x"$ac_cv_always_inline" = x"yes"; then + AC_DEFINE_UNQUOTED([inline],[__attribute__ ((__always_inline__))]) + fi + fi]) + +dnl AC_C_ATTRIBUTE_ALIGNED +dnl define ATTRIBUTE_ALIGNED_MAX to the maximum alignment if this is supported +AC_DEFUN([AC_C_ATTRIBUTE_ALIGNED], + [AC_CACHE_CHECK([__attribute__ ((aligned ())) support], + [ac_cv_c_attribute_aligned], + [ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + AC_TRY_COMPILE([], + [static char c __attribute__ ((aligned($ac_cv_c_attr_align_try))) = 0; return c;], + [ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try]) + done]) + if test x"$ac_cv_c_attribute_aligned" != x"0"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], + [$ac_cv_c_attribute_aligned],[maximum supported data alignment]) + fi]) + +dnl AC_TRY_CFLAGS (CFLAGS, [ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check if $CC supports a given set of cflags +AC_DEFUN([AC_TRY_CFLAGS], + [AC_MSG_CHECKING([if $CC supports $1 flags]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$1" + AC_TRY_COMPILE([],[],[ac_cv_try_cflags_ok=yes],[ac_cv_try_cflags_ok=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_try_cflags_ok]) + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + ifelse([$2],[],[:],[$2]) + else + ifelse([$3],[],[:],[$3]) + fi]) + +dnl AC_LIBTOOL_NON_PIC ([ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check for nonbuggy libtool -prefer-non-pic +AC_DEFUN([AC_LIBTOOL_NON_PIC], + [AC_MSG_CHECKING([if libtool supports -prefer-non-pic flag]) + mkdir ac_test_libtool; cd ac_test_libtool; ac_cv_libtool_non_pic=no + echo "int g (int i); int f (int i) {return g (i);}" >f.c + echo "int (* hook) (int) = 0; int g (int i) {if (hook) i = hook (i); return i + 1;}" >g.c + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c f.c >/dev/null 2>&1 && \ + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c g.c >/dev/null 2>&1 && \ + ../libtool --mode=link $CC $CFLAGS -prefer-non-pic -o libfoo.la \ + -rpath / f.lo g.lo >/dev/null 2>&1 && + ac_cv_libtool_non_pic=yes + cd ..; rm -fr ac_test_libtool; AC_MSG_RESULT([$ac_cv_libtool_non_pic]) + if test x"$ac_cv_libtool_non_pic" = x"yes"; then + ifelse([$1],[],[:],[$1]) + else + ifelse([$2],[],[:],[$2]) + fi]) + +dnl AC_CHECK_GENERATE_INTTYPES_H (INCLUDE-DIRECTORY) +dnl generate a default inttypes.h if the header file does not exist already +AC_DEFUN([AC_CHECK_GENERATE_INTTYPES], + [rm -f $1/inttypes.h + AC_CHECK_HEADER([inttypes.h],[], + [AC_CHECK_SIZEOF([char]) + AC_CHECK_SIZEOF([short]) + AC_CHECK_SIZEOF([int]) + if test x"$ac_cv_sizeof_char" != x"1" -o \ + x"$ac_cv_sizeof_short" != x"2" -o \ + x"$ac_cv_sizeof_int" != x"4"; then + AC_MSG_ERROR([can not build a default inttypes.h]) + fi + cat >$1/inttypes.h << EOF +/* default inttypes.h for people who do not have it on their system */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H +#if (!defined __int8_t_defined) && (!defined __BIT_TYPES_DEFINED__) +#define __int8_t_defined +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +#ifdef ARCH_X86 +typedef signed long long int64_t; +#endif +#endif +#if (!defined _LINUX_TYPES_H) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifdef ARCH_X86 +typedef unsigned long long uint64_t; +#endif +#endif +#endif +EOF + ])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. + +# 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, 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. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +AC_PREREQ([2.54]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl + AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[_am_stamp_count=`expr ${_am_stamp_count-0} + 1` +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright 2002 Free Software Foundation, Inc. + +# 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, 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 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.7.1])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 Free Software Foundation, Inc. + +# 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, 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. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# 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, 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. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + +# 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, 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. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 Free Software Foundation, Inc. + +# 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, 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 Free Software Foundation, Inc. + +# 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, 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. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 Free Software Foundation, Inc. + +# 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, 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. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# serial 4 -*- Autoconf -*- + +# Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + +# 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, 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. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c -o conftest.o conftest.c >/dev/null 2>&1 && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[rm -f .deps 2>/dev/null +mkdir .deps 2>/dev/null +if test -d .deps; then + DEPDIR=.deps +else + # MS-DOS does not allow filenames that begin with a dot. + DEPDIR=_deps +fi +rmdir .deps 2>/dev/null +AC_SUBST([DEPDIR]) +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# 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, 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. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002 Free Software Foundation, Inc. + +# 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, 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. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +doit: + @echo done +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST(am__include) +AC_SUBST(am__quote) +AC_MSG_RESULT($_am_result) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +# 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, 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. + +# serial 5 + +AC_PREREQ(2.52) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) +fi])]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. + +# 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, 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. + +# serial 2 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL + +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([LT_AC_PROG_SED])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# AC_LIBTOOL_HEADER_ASSERT +# ------------------------ +AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], +[AC_CACHE_CHECK([whether $CC supports assert without backlinking], + [lt_cv_func_assert_works], + [case $host in + *-*-solaris*) + if test "$GCC" = yes && test "$with_gnu_ld" != yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) lt_cv_func_assert_works=no ;; + *) lt_cv_func_assert_works=yes ;; + esac + fi + ;; + esac]) + +if test "x$lt_cv_func_assert_works" = xyes; then + AC_CHECK_HEADERS(assert.h) +fi +])# AC_LIBTOOL_HEADER_ASSERT + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[[ABCDGISTW]]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$nonopt $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +AC_MSG_RESULT([$hardcode_action]) + +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="${SED} -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | [[A-Za-z]]:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[[78]]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and LTDLINCL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break; + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" +]) +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +AC_MSG_RESULT([$SED]) +]) + diff --git a/vldp2/autotools/Makefile.am b/vldp2/autotools/Makefile.am new file mode 100644 index 000000000..e69de29bb diff --git a/vldp2/autotools/Makefile.in b/vldp2/autotools/Makefile.in new file mode 100644 index 000000000..2dbd1c14b --- /dev/null +++ b/vldp2/autotools/Makefile.in @@ -0,0 +1,280 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +subdir = autotools +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = Makefile.am Makefile.in config.guess config.sub depcomp \ + install-sh ltmain.sh missing mkinstalldirs +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu autotools/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/autotools/config.guess b/vldp2/autotools/config.guess new file mode 100644 index 000000000..f1657bbc4 --- /dev/null +++ b/vldp2/autotools/config.guess @@ -0,0 +1,1363 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-09-03' + +# This file 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# This shell variable is my proudest work .. or something. --bje + +set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; +(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) + || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; +dummy=$tmpdir/dummy ; +files="$dummy.c $dummy.o $dummy.rel $dummy" ; +trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $files ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; +unset files' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + rm -f $dummy.s $dummy && rmdir $tmpdir + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy && rmdir $tmpdir + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c && rmdir $tmpdir + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 +rm -f $dummy.c $dummy && rmdir $tmpdir + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/vldp2/autotools/config.sub b/vldp2/autotools/config.sub new file mode 100644 index 000000000..1dea9b79d --- /dev/null +++ b/vldp2/autotools/config.sub @@ -0,0 +1,1470 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-09-05' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39 | mipstx39el \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/vldp2/autotools/depcomp b/vldp2/autotools/depcomp new file mode 100644 index 000000000..807b991f4 --- /dev/null +++ b/vldp2/autotools/depcomp @@ -0,0 +1,423 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 Free Software Foundation, Inc. + +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +if test -z "$depfile"; then + base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` + dir=`echo "$object" | sed 's,/.*$,/,'` + if test "$dir" = "$object"; then + dir= + fi + # FIXME: should be _deps on DOS. + depfile="$dir.deps/$base" +fi + +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. We will use -o /dev/null later, + # however we can't do the remplacement now because + # `-o $object' might simply not be used + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/vldp2/autotools/install-sh b/vldp2/autotools/install-sh new file mode 100644 index 000000000..11870f1b0 --- /dev/null +++ b/vldp2/autotools/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/vldp2/autotools/ltmain.sh b/vldp2/autotools/ltmain.sh new file mode 100644 index 000000000..46a945047 --- /dev/null +++ b/vldp2/autotools/ltmain.sh @@ -0,0 +1,5100 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\/]*) + add_dir="-L$inst_prefix_dir$libdir $add_dir" + ;; + esac + fi + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs. + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done + eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test $need_relink = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 ${SED} + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place in case we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/vldp2/autotools/missing b/vldp2/autotools/missing new file mode 100644 index 000000000..6a37006e8 --- /dev/null +++ b/vldp2/autotools/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/vldp2/autotools/mkinstalldirs b/vldp2/autotools/mkinstalldirs new file mode 100644 index 000000000..d2d5f21b6 --- /dev/null +++ b/vldp2/autotools/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/vldp2/bootstrap b/vldp2/bootstrap new file mode 100644 index 000000000..ccd14dd36 --- /dev/null +++ b/vldp2/bootstrap @@ -0,0 +1,11 @@ +#! /bin/sh +set -x + +aclocal -I autotools +libtoolize --force --copy +autoheader +#add --include-deps if you want to bootstrap with any other compiler than gcc +#automake --add-missing --copy --include-deps +automake --add-missing --copy +autoconf +rm -f config.cache diff --git a/vldp2/configure b/vldp2/configure new file mode 100644 index 000000000..357d5f5ed --- /dev/null +++ b/vldp2/configure @@ -0,0 +1,12827 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.54. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="src/mpeg2dec.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LN_S ECHO RANLIB ac_ct_RANLIB LIBTOOL INCLUDES LIBMPEG2_CFLAGS LIBMPEG2_LIBS LIBVO_CFLAGS LIBVO_LIBS X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS SDLCONFIG LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +X features: + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors + --enable-debug debug mode configuration + --enable-shared=PKGS build shared libraries default=no + --enable-static=PKGS build static libraries default=yes + --enable-fast-install=PKGS optimize for fast installation default=yes + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-accel-detect make a version without accel detection code + --disable-mlib make a version not using mediaLib + --enable-directx=DIR use Win32 DirectX headers in DIR + --disable-sdl make a version not using SDL + --enable-warnings treat warnings as errors + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-pic try to use only PIC/non-PIC objects default=use both + --with-x use the X Window System + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.54. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell meta-characters. +ac_configure_args= +ac_sep= +for ac_arg +do + case $ac_arg in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n ) continue ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +ac_aux_dir= +for ac_dir in autotools $srcdir/autotools; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in autotools $srcdir/autotools" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in autotools $srcdir/autotools" >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + ac_config_files="$ac_config_files Makefile autotools/Makefile include/Makefile test/Makefile doc/Makefile src/Makefile libmpeg2/Makefile libvo/Makefile vc++/Makefile libmpeg2/libmpeg2.pc" + +am__api_version="1.7" +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="${MAKE}"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + # test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=mpeg2dec + VERSION=0.3.1 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. + + + + ac_config_headers="$ac_config_headers include/config.h" + +echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +check \`config.log' for details." >&5 +echo "$as_me: error: C compiler cannot create executables +check \`config.log' for details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +rm -f .deps 2>/dev/null +mkdir .deps 2>/dev/null +if test -d .deps; then + DEPDIR=.deps +else + # MS-DOS does not allow filenames that begin with a dot. + DEPDIR=_deps +fi +rmdir .deps 2>/dev/null + + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +doit: + @echo done +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c -o conftest.o conftest.c >/dev/null 2>&1 && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +if test $ac_cv_c_compiler_gnu = yes; then + echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + +if test x"$CC" = x"checkergcc"; then + enable_sdl=no +elif test x"$GCC" = x"yes"; then + + + OPT_CFLAGS="$CFLAGS -Wall" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi + + + OPT_CFLAGS=`echo "$CFLAGS"|sed "s/-O[0-9]*//g"` + + OPT_CFLAGS="$OPT_CFLAGS -O3" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi + + # Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + +fi; + if test x"$enable_debug" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define DEBUG +_ACEOF + + else + OPT_CFLAGS="$CFLAGS -fomit-frame-pointer" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi + fi + + case "$host" in + i?86-* | k?-* | x86_64-*) + +cat >>confdefs.h <<\_ACEOF +#define ARCH_X86 +_ACEOF + + case "$host" in + i386-*) OPT_CFLAGS="$CFLAGS -mcpu=i386";; + i486-*) OPT_CFLAGS="$CFLAGS -mcpu=i486";; + i586-*) OPT_CFLAGS="$CFLAGS -mcpu=pentium";; + i686-*) OPT_CFLAGS="$CFLAGS -mcpu=pentiumpro";; + k6-*) OPT_CFLAGS="$CFLAGS -mcpu=k6";; + esac + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi;; + ppc-* | powerpc-*) + OPT_CFLAGS="$CFLAGS -Wa,-m7400" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS; +cat >>confdefs.h <<\_ACEOF +#define ARCH_PPC +_ACEOF + + else + : + fi;; + sparc-* | sparc64-*) + OPT_CFLAGS="$CFLAGS -mcpu=ultrasparc -mvis -Wa,-Av9b" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi;; + alpha*) + OPT_CFLAGS="$CFLAGS -Wa,-mev6" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS; + +cat >>confdefs.h <<\_ACEOF +#define ARCH_ALPHA +_ACEOF + + else + : + fi;; + esac +elif test x"$CC" = x"tcc" -a x"`$CC -version 2>&1 | grep TenDRA`" != x""; then + TENDRA=yes + CFLAGS="-Xp -Yansi -f`pwd`/include/tendra.h -DELIDE_CODE" + enable_mlib=no + no_x=yes + enable_sdl=no +elif test x"$CC" = x"icc" -a x"`$CC -V 2>&1 | grep Intel`" != x""; then + CFLAGS="-g -O3 -unroll -ip" +else + case "$host" in + sparc-sun-solaris*) + OPT_CFLAGS="$CFLAGS -xCC -fast -xO5" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi;; + esac +fi + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=no +fi; + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi; +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi; +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by GCC" >&5 +echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6 + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break; + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" + +fi + +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + + + + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output" >&5 +echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +solaris* | sysv5*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 4880 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +lt_cv_cc_needs_belf=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$as_me:$LINENO: result: $objdir" >&5 +echo "${ECHO_T}$objdir" >&6 + + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_pic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi + +fi + +if test -z "$lt_cv_prog_cc_pic"; then + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +else + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6 + + # Check to make sure the pic_flag actually works. + echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6 + if test "${lt_cv_prog_cc_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 + lt_cv_prog_cc_pic_works=no + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + +fi + + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6 +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5 +echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;} + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then : + else + { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 +echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} + lt_cv_prog_cc_can_build_shared=no + fi +fi + +echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_prog_cc_static_works=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi + + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6 + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:5394: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +fi + +compiler_c_o=$lt_cv_compiler_c_o +echo "$as_me:$LINENO: result: $compiler_c_o" >&5 +echo "${ECHO_T}$compiler_c_o" >&6 + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6 + if test "${lt_cv_compiler_o_lo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + +fi + + compiler_o_lo=$lt_cv_compiler_o_lo + echo "$as_me:$LINENO: result: $compiler_o_lo" >&5 +echo "${ECHO_T}$compiler_o_lo" >&6 +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$compiler_rtti_exceptions" >&6 + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \$# in + 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \$2 \$3 \$4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$nonopt $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [12].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can + # not hardcode correct soname into executable. Probably we can + # add versioning support to collect2, so additional links can + # be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +f = shl_load; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +f = dlopen; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + if test "${lt_cv_archive_cmds_need_lc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + $rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi +fi + + echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5 +echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6 + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + global_symbol_to_c_name_address \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="${SED} -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + +INCLUDES='-I$(top_srcdir)/include -I$(top_builddir)/include' + + + + +for ac_header in sys/time.h sys/timeb.h io.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +rm -f include/inttypes.h + if test "${ac_cv_header_inttypes_h+set}" = set; then + echo "$as_me:$LINENO: checking for inttypes.h" >&5 +echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6 +if test "${ac_cv_header_inttypes_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_inttypes_h" >&5 +echo "${ECHO_T}$ac_cv_header_inttypes_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking inttypes.h usability" >&5 +echo $ECHO_N "checking inttypes.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking inttypes.h presence" >&5 +echo $ECHO_N "checking inttypes.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: inttypes.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: inttypes.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: inttypes.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: inttypes.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: inttypes.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: inttypes.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: inttypes.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for inttypes.h" >&5 +echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6 +if test "${ac_cv_header_inttypes_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_inttypes_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_inttypes_h" >&5 +echo "${ECHO_T}$ac_cv_header_inttypes_h" >&6 + +fi +if test $ac_cv_header_inttypes_h = yes; then + : +else + echo "$as_me:$LINENO: checking for char" >&5 +echo $ECHO_N "checking for char... $ECHO_C" >&6 +if test "${ac_cv_type_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((char *) 0) + return 0; +if (sizeof (char)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_char=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_char=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5 +echo "${ECHO_T}$ac_cv_type_char" >&6 + +echo "$as_me:$LINENO: checking size of char" >&5 +echo $ECHO_N "checking size of char... $ECHO_C" >&6 +if test "${ac_cv_sizeof_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_char" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (char))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (char))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (char))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (char))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (char))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_char=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (char), 77" >&5 +echo "$as_me: error: cannot compute sizeof (char), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (char)); } +unsigned long ulongval () { return (long) (sizeof (char)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (char))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (char)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (char)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_char=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (char), 77" >&5 +echo "$as_me: error: cannot compute sizeof (char), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_char=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5 +echo "${ECHO_T}$ac_cv_sizeof_char" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + + echo "$as_me:$LINENO: checking for short" >&5 +echo $ECHO_N "checking for short... $ECHO_C" >&6 +if test "${ac_cv_type_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((short *) 0) + return 0; +if (sizeof (short)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_short=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_short=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 +echo "${ECHO_T}$ac_cv_type_short" >&6 + +echo "$as_me:$LINENO: checking size of short" >&5 +echo $ECHO_N "checking size of short... $ECHO_C" >&6 +if test "${ac_cv_sizeof_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_short" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_short=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77" >&5 +echo "$as_me: error: cannot compute sizeof (short), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (short)); } +unsigned long ulongval () { return (long) (sizeof (short)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (short))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (short)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (short)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_short=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77" >&5 +echo "$as_me: error: cannot compute sizeof (short), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_short=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 +echo "${ECHO_T}$ac_cv_sizeof_short" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6 +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((int *) 0) + return 0; +if (sizeof (int)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_int=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6 + +echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6 +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_int" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77" >&5 +echo "$as_me: error: cannot compute sizeof (int), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (int)); } +unsigned long ulongval () { return (long) (sizeof (int)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (int))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77" >&5 +echo "$as_me: error: cannot compute sizeof (int), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_int=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + if test x"$ac_cv_sizeof_char" != x"1" -o \ + x"$ac_cv_sizeof_short" != x"2" -o \ + x"$ac_cv_sizeof_int" != x"4"; then + { { echo "$as_me:$LINENO: error: can not build a default inttypes.h" >&5 +echo "$as_me: error: can not build a default inttypes.h" >&2;} + { (exit 1); exit 1; }; } + fi + cat >include/inttypes.h << EOF +/* default inttypes.h for people who do not have it on their system */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H +#if (!defined __int8_t_defined) && (!defined __BIT_TYPES_DEFINED__) +#define __int8_t_defined +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +#ifdef ARCH_X86 +typedef signed long long int64_t; +#endif +#endif +#if (!defined _LINUX_TYPES_H) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifdef ARCH_X86 +typedef unsigned long long uint64_t; +#endif +#endif +#endif +EOF + +fi + + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6 +case $ac_cv_c_inline in + inline | yes) ;; + no) +cat >>confdefs.h <<\_ACEOF +#define inline +_ACEOF + ;; + *) cat >>confdefs.h <<_ACEOF +#define inline $ac_cv_c_inline +_ACEOF + ;; +esac + + if test x"$GCC" = x"yes" -a x"$ac_cv_c_inline" = x"inline"; then + echo "$as_me:$LINENO: checking for always_inline" >&5 +echo $ECHO_N "checking for always_inline... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Werror" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +__attribute__ ((__always_inline__)) void f (void); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_always_inline=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_always_inline=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_always_inline" >&5 +echo "${ECHO_T}$ac_cv_always_inline" >&6 + if test x"$ac_cv_always_inline" = x"yes"; then + cat >>confdefs.h <<_ACEOF +#define inline __attribute__ ((__always_inline__)) +_ACEOF + + fi + fi +echo "$as_me:$LINENO: checking for restrict" >&5 +echo $ECHO_N "checking for restrict... $ECHO_C" >&6 + ac_cv_c_restrict=no + for ac_kw in restrict __restrict__ __restrict; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +char * $ac_kw p; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_restrict=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done + echo "$as_me:$LINENO: result: $ac_cv_c_restrict" >&5 +echo "${ECHO_T}$ac_cv_c_restrict" >&6 + case $ac_cv_c_restrict in + restrict) ;; + no) +cat >>confdefs.h <<\_ACEOF +#define restrict +_ACEOF + ;; + *) cat >>confdefs.h <<_ACEOF +#define restrict $ac_cv_c_restrict +_ACEOF + ;; + esac +echo "$as_me:$LINENO: checking for __builtin_expect" >&5 +echo $ECHO_N "checking for __builtin_expect... $ECHO_C" >&6 +if test "${ac_cv_builtin_expect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_builtin_expect=yes + else + ac_cv_builtin_expect=no + fi + rm -f conftest* +fi +echo "$as_me:$LINENO: result: $ac_cv_builtin_expect" >&5 +echo "${ECHO_T}$ac_cv_builtin_expect" >&6 + if test x"$ac_cv_builtin_expect" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BUILTIN_EXPECT +_ACEOF + + fi +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_bigendian=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + + + + +for ac_func in memalign gettimeofday ftime +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_signal=int +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + + + + +echo "$as_me:$LINENO: checking if libtool supports -prefer-non-pic flag" >&5 +echo $ECHO_N "checking if libtool supports -prefer-non-pic flag... $ECHO_C" >&6 + mkdir ac_test_libtool; cd ac_test_libtool; ac_cv_libtool_non_pic=no + echo "int g (int i); int f (int i) {return g (i);}" >f.c + echo "int (* hook) (int) = 0; int g (int i) {if (hook) i = hook (i); return i + 1;}" >g.c + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c f.c >/dev/null 2>&1 && \ + ../libtool --mode=compile $CC $CFLAGS -prefer-non-pic \ + -c g.c >/dev/null 2>&1 && \ + ../libtool --mode=link $CC $CFLAGS -prefer-non-pic -o libfoo.la \ + -rpath / f.lo g.lo >/dev/null 2>&1 && + ac_cv_libtool_non_pic=yes + cd ..; rm -fr ac_test_libtool; echo "$as_me:$LINENO: result: $ac_cv_libtool_non_pic" >&5 +echo "${ECHO_T}$ac_cv_libtool_non_pic" >&6 + if test x"$ac_cv_libtool_non_pic" = x"yes"; then + LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -prefer-non-pic" + else + : + fi + +# Check whether --enable-accel-detect or --disable-accel-detect was given. +if test "${enable_accel_detect+set}" = set; then + enableval="$enable_accel_detect" + +fi; +if test x"$enable_accel_detect" != x"no"; then + +cat >>confdefs.h <<\_ACEOF +#define ACCEL_DETECT +_ACEOF + +fi + +# Check whether --enable-mlib or --disable-mlib was given. +if test "${enable_mlib+set}" = set; then + enableval="$enable_mlib" + +fi; +if test x"$enable_mlib" != x"no"; then + cflags_save="$CFLAGS" + CFLAGS="$CFLAGS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib" + echo "$as_me:$LINENO: checking for mlib_VideoColorYUV2RGB420 in -lmlib" >&5 +echo $ECHO_N "checking for mlib_VideoColorYUV2RGB420 in -lmlib... $ECHO_C" >&6 +if test "${ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmlib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char mlib_VideoColorYUV2RGB420 (); +int +main () +{ +mlib_VideoColorYUV2RGB420 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420" >&5 +echo "${ECHO_T}$ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420" >&6 +if test $ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420 = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LIBMPEG2_MLIB +_ACEOF + + LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -I/opt/SUNWmlib/include" + LIBMPEG2_LIBS="$LIBMPEG2_LIBS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib -lmlib" +fi + + CFLAGS="$cflags_save" +fi + + + + +echo "$as_me:$LINENO: checking for X" >&5 +echo $ECHO_N "checking for X... $ECHO_C" >&6 + + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + +fi; +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else + if test "${ac_cv_have_x+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -fr conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat >Imakefile <<'_ACEOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +_ACEOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -fr conftest.dir +fi + +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include + +/usr/include/X11 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 + +/usr/local/X11/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include + +/usr/local/include/X11 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 + +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Intrinsic.h. + # First, try using that file with no special directory specified. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Intrinsic.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi +rm -f conftest.err conftest.$ac_ext +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lXt $LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +int +main () +{ +XtMalloc (0) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +LIBS=$ac_save_LIBS +for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r $ac_dir/libXt.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi # $ac_x_libraries = no + +if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$as_me:$LINENO: result: $have_x" >&5 +echo "${ECHO_T}$have_x" >&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 +echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + +cat >>confdefs.h <<\_ACEOF +#define X_DISPLAY_MISSING 1 +_ACEOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case `(uname -sr) 2>/dev/null` in + "SunOS 5"*) + echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5 +echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6 + ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_R_nospace=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_R_nospace=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + if test $ac_R_nospace = yes; then + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_R_space=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_R_space=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + if test $ac_R_space = yes; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + X_LIBS="$X_LIBS -R $x_libraries" + else + echo "$as_me:$LINENO: result: neither works" >&5 +echo "${ECHO_T}neither works" >&6 + fi + fi + LIBS=$ac_xsave_LIBS + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn Johnson says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And Karl Berry says + # the Alpha needs dnet_stub (dnet does not exist). + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XOpenDisplay (); +int +main () +{ +XOpenDisplay (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6 +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dnet_ntoa (); +int +main () +{ +dnet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dnet_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dnet_dnet_ntoa=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6 +if test $ac_cv_lib_dnet_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6 +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet_stub $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dnet_ntoa (); +int +main () +{ +dnet_ntoa (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dnet_stub_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dnet_stub_dnet_ntoa=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6 +if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +fi + + fi +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_xsave_LIBS" + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to T.E. Dickey. + # The functions gethostbyname, getservbyname, and inet_addr are + # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. + echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +f = gethostbyname; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_gethostbyname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 + + if test $ac_cv_func_gethostbyname = no; then + echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +fi + + if test $ac_cv_lib_nsl_gethostbyname = no; then + echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 +echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6 +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bsd_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_bsd_gethostbyname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6 +if test $ac_cv_lib_bsd_gethostbyname = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" +fi + + fi + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says Simon Leinen: it contains gethostby* + # variants that don't use the name server (or something). -lsocket + # must be given before -lnsl if both are needed. We assume that + # if connect needs -lnsl, so does gethostbyname. + echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6 +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +f = connect; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_connect=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6 + + if test $ac_cv_func_connect = no; then + echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 +echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +int +main () +{ +connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_connect=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_socket_connect=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6 +if test $ac_cv_lib_socket_connect = yes; then + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +fi + + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + echo "$as_me:$LINENO: checking for remove" >&5 +echo $ECHO_N "checking for remove... $ECHO_C" >&6 +if test "${ac_cv_func_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char remove (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_remove) || defined (__stub___remove) +choke me +#else +f = remove; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_remove=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_remove=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 +echo "${ECHO_T}$ac_cv_func_remove" >&6 + + if test $ac_cv_func_remove = no; then + echo "$as_me:$LINENO: checking for remove in -lposix" >&5 +echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6 +if test "${ac_cv_lib_posix_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lposix $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove (); +int +main () +{ +remove (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_posix_remove=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_posix_remove=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 +echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6 +if test $ac_cv_lib_posix_remove = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + echo "$as_me:$LINENO: checking for shmat" >&5 +echo $ECHO_N "checking for shmat... $ECHO_C" >&6 +if test "${ac_cv_func_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shmat (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shmat) || defined (__stub___shmat) +choke me +#else +f = shmat; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shmat=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_shmat=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 +echo "${ECHO_T}$ac_cv_func_shmat" >&6 + + if test $ac_cv_func_shmat = no; then + echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 +echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6 +if test "${ac_cv_lib_ipc_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lipc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat (); +int +main () +{ +shmat (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ipc_shmat=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_ipc_shmat=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 +echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6 +if test $ac_cv_lib_ipc_shmat = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS=$LDFLAGS + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # John Interrante, Karl Berry + echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 +echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6 +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char IceConnectionNumber (); +int +main () +{ +IceConnectionNumber (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ICE_IceConnectionNumber=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_ICE_IceConnectionNumber=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6 +if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +fi + + LDFLAGS=$ac_save_LDFLAGS + +fi + +if test x"$no_x" != x"yes"; then + echo "$as_me:$LINENO: checking for XShmCreateImage in -lXext" >&5 +echo $ECHO_N "checking for XShmCreateImage in -lXext... $ECHO_C" >&6 +if test "${ac_cv_lib_Xext_XShmCreateImage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXext $X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XShmCreateImage (); +int +main () +{ +XShmCreateImage (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_Xext_XShmCreateImage=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_Xext_XShmCreateImage=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_Xext_XShmCreateImage" >&5 +echo "${ECHO_T}$ac_cv_lib_Xext_XShmCreateImage" >&6 +if test $ac_cv_lib_Xext_XShmCreateImage = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_X11 +_ACEOF + + LIBVO_CFLAGS="$LIBVO_CFLAGS $X_CFLAGS" + LIBVO_LIBS="$LIBVO_LIBS $X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext" + echo "$as_me:$LINENO: checking for XvShmCreateImage in -lXv" >&5 +echo $ECHO_N "checking for XvShmCreateImage in -lXv... $ECHO_C" >&6 +if test "${ac_cv_lib_Xv_XvShmCreateImage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXv $X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XvShmCreateImage (); +int +main () +{ +XvShmCreateImage (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_Xv_XvShmCreateImage=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_Xv_XvShmCreateImage=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_Xv_XvShmCreateImage" >&5 +echo "${ECHO_T}$ac_cv_lib_Xv_XvShmCreateImage" >&6 +if test $ac_cv_lib_Xv_XvShmCreateImage = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_XV +_ACEOF + + LIBVO_LIBS="$LIBVO_LIBS -lXv" +fi + +fi + +fi + +# Check whether --enable-directx or --disable-directx was given. +if test "${enable_directx+set}" = set; then + enableval="$enable_directx" + +fi; +case $enable_directx in + ""|yes) +for ac_header in ddraw.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_DX +_ACEOF + + LIBVO_LIBS="$LIBVO_LIBS -lgdi32" +fi + +done +;; + no) ;; + *) if test -f "$enable_directx/ddraw.h"; then + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_DX +_ACEOF + + LIBVO_CFLAGS="$LIBVO_CFLAGS -I$enable_directx" + LIBVO_LIBS="$LIBVO_LIBS -lgdi32" + else + { { echo "$as_me:$LINENO: error: Cannot find $enable_directx/ddraw.h" >&5 +echo "$as_me: error: Cannot find $enable_directx/ddraw.h" >&2;} + { (exit 1); exit 1; }; } + fi;; +esac + +# Check whether --enable-mlib or --disable-mlib was given. +if test "${enable_mlib+set}" = set; then + enableval="$enable_mlib" + +fi; +if test x"$enable_mlib" != x"no"; then + cflags_save="$CFLAGS" + CFLAGS="$CFLAGS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib" + echo "$as_me:$LINENO: checking for mlib_VideoColorYUV2RGB420 in -lmlib" >&5 +echo $ECHO_N "checking for mlib_VideoColorYUV2RGB420 in -lmlib... $ECHO_C" >&6 +if test "${ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmlib $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char mlib_VideoColorYUV2RGB420 (); +int +main () +{ +mlib_VideoColorYUV2RGB420 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420" >&5 +echo "${ECHO_T}$ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420" >&6 +if test $ac_cv_lib_mlib_mlib_VideoColorYUV2RGB420 = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_MLIB +_ACEOF + + LIBVO_CFLAGS="$LIBVO_CFLAGS -I/opt/SUNWmlib/include" + LIBVO_LIBS="$LIBVO_LIBS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib -lmlib" +fi + + CFLAGS="$cflags_save" +fi + +# Check whether --enable-sdl or --disable-sdl was given. +if test "${enable_sdl+set}" = set; then + enableval="$enable_sdl" + +fi; +if test x"$enable_sdl" != x"no"; then + # Extract the first word of "sdl-config", so it can be a program name with args. +set dummy sdl-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_SDLCONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$SDLCONFIG"; then + ac_cv_prog_SDLCONFIG="$SDLCONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SDLCONFIG="yes" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +SDLCONFIG=$ac_cv_prog_SDLCONFIG +if test -n "$SDLCONFIG"; then + echo "$as_me:$LINENO: result: $SDLCONFIG" >&5 +echo "${ECHO_T}$SDLCONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + if test x"$SDLCONFIG" = x"yes"; then + +cat >>confdefs.h <<\_ACEOF +#define LIBVO_SDL +_ACEOF + + LIBVO_CFLAGS="$LIBVO_CFLAGS `sdl-config --cflags`" + LIBVO_LIBS="$LIBVO_LIBS `sdl-config --libs`" + fi +fi + + +# Check whether --enable-warnings or --disable-warnings was given. +if test "${enable_warnings+set}" = set; then + enableval="$enable_warnings" + +fi; +if test x"$enable_warnings" = x"yes" -a x"$GCC" = x"yes"; then + OPT_CFLAGS="$CFLAGS -Werror" + echo "$as_me:$LINENO: checking if $CC supports $OPT_CFLAGS flags" >&5 +echo $ECHO_N "checking if $CC supports $OPT_CFLAGS flags... $ECHO_C" >&6 + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$OPT_CFLAGS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_try_cflags_ok=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_try_cflags_ok=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$SAVE_CFLAGS" + echo "$as_me:$LINENO: result: $ac_cv_try_cflags_ok" >&5 +echo "${ECHO_T}$ac_cv_try_cflags_ok" >&6 + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + CFLAGS=$OPT_CFLAGS + else + : + fi +elif test x"$TENDRA" = x"yes"; then + CFLAGS="$CFLAGS -DTenDRA_check" +fi + +echo "$as_me:$LINENO: checking __attribute__ ((aligned ())) support" >&5 +echo $ECHO_N "checking __attribute__ ((aligned ())) support... $ECHO_C" >&6 +if test "${ac_cv_c_attribute_aligned+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +static char c __attribute__ ((aligned($ac_cv_c_attr_align_try))) = 0; return c; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +fi +echo "$as_me:$LINENO: result: $ac_cv_c_attribute_aligned" >&5 +echo "${ECHO_T}$ac_cv_c_attribute_aligned" >&6 + if test x"$ac_cv_c_attribute_aligned" != x"0"; then + +cat >>confdefs.h <<_ACEOF +#define ATTRIBUTE_ALIGNED_MAX $ac_cv_c_attribute_aligned +_ACEOF + + fi + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.54. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.54, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" + exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "autotools/Makefile" ) CONFIG_FILES="$CONFIG_FILES autotools/Makefile" ;; + "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "libmpeg2/Makefile" ) CONFIG_FILES="$CONFIG_FILES libmpeg2/Makefile" ;; + "libvo/Makefile" ) CONFIG_FILES="$CONFIG_FILES libvo/Makefile" ;; + "vc++/Makefile" ) CONFIG_FILES="$CONFIG_FILES vc++/Makefile" ;; + "libmpeg2/libmpeg2.pc" ) CONFIG_FILES="$CONFIG_FILES libmpeg2/libmpeg2.pc" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@AMTAR@,$AMTAR,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@INCLUDES@,$INCLUDES,;t t +s,@LIBMPEG2_CFLAGS@,$LIBMPEG2_CFLAGS,;t t +s,@LIBMPEG2_LIBS@,$LIBMPEG2_LIBS,;t t +s,@LIBVO_CFLAGS@,$LIBVO_CFLAGS,;t t +s,@LIBVO_LIBS@,$LIBVO_LIBS,;t t +s,@X_CFLAGS@,$X_CFLAGS,;t t +s,@X_PRE_LIBS@,$X_PRE_LIBS,;t t +s,@X_LIBS@,$X_LIBS,;t t +s,@X_EXTRA_LIBS@,$X_EXTRA_LIBS,;t t +s,@SDLCONFIG@,$SDLCONFIG,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +_am_stamp_count=`expr ${_am_stamp_count-0} + 1` +echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'`/stamp-h$_am_stamp_count +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/vldp2/configure.in b/vldp2/configure.in new file mode 100644 index 000000000..841671262 --- /dev/null +++ b/vldp2/configure.in @@ -0,0 +1,132 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.54) +AC_INIT +AC_CONFIG_SRCDIR([src/mpeg2dec.c]) +AC_CONFIG_AUX_DIR(autotools) +AC_CONFIG_FILES([Makefile autotools/Makefile include/Makefile test/Makefile + doc/Makefile src/Makefile libmpeg2/Makefile libvo/Makefile vc++/Makefile + libmpeg2/libmpeg2.pc]) +AM_INIT_AUTOMAKE([mpeg2dec],[0.3.1]) +AC_CONFIG_HEADERS([include/config.h]) +AM_MAINTAINER_MODE +AC_CANONICAL_HOST + +dnl Checks for compiler +AC_PROG_CC +AC_PROG_GCC_TRADITIONAL + +dnl CC-specific flags +if test x"$CC" = x"checkergcc"; then + enable_sdl=no +elif test x"$GCC" = x"yes"; then + + dnl GCC-specific flags + + dnl -Wall + dnl -Werror moved to the end to not disturb the configure script + OPT_CFLAGS="$CFLAGS -Wall" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]) + + dnl -O3 + changequote(<<,>>) + OPT_CFLAGS=`echo "$CFLAGS"|sed "s/-O[0-9]*//g"` + changequote([,]) + OPT_CFLAGS="$OPT_CFLAGS -O3" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]) + + AC_ARG_ENABLE([debug], + [ --enable-debug debug mode configuration]) + if test x"$enable_debug" = x"yes"; then + AC_DEFINE([DEBUG],,[debug mode configuration]) + else + dnl -fomit-frame-pointer + OPT_CFLAGS="$CFLAGS -fomit-frame-pointer" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]) + fi + + dnl arch-specific flags + case "$host" in + i?86-* | k?-* | x86_64-*) + AC_DEFINE([ARCH_X86],,[x86 architecture]) + case "$host" in + i386-*) OPT_CFLAGS="$CFLAGS -mcpu=i386";; + i486-*) OPT_CFLAGS="$CFLAGS -mcpu=i486";; + i586-*) OPT_CFLAGS="$CFLAGS -mcpu=pentium";; + i686-*) OPT_CFLAGS="$CFLAGS -mcpu=pentiumpro";; + k6-*) OPT_CFLAGS="$CFLAGS -mcpu=k6";; + esac + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);; + ppc-* | powerpc-*) + OPT_CFLAGS="$CFLAGS -Wa,-m7400" + AC_TRY_CFLAGS([$OPT_CFLAGS], + [CFLAGS=$OPT_CFLAGS; AC_DEFINE([ARCH_PPC],,[ppc architecture])]);; + sparc-* | sparc64-*) + OPT_CFLAGS="$CFLAGS -mcpu=ultrasparc -mvis -Wa,-Av9b" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);; + alpha*) + OPT_CFLAGS="$CFLAGS -Wa,-mev6" + AC_TRY_CFLAGS([$OPT_CFLAGS], + [CFLAGS=$OPT_CFLAGS; + AC_DEFINE([ARCH_ALPHA],,[alpha architecture])]);; + esac +elif test x"$CC" = x"tcc" -a x"`$CC -version 2>&1 | grep TenDRA`" != x""; then + dnl TenDRA portability checking compiler + TENDRA=yes + CFLAGS="-Xp -Yansi -f`pwd`/include/tendra.h -DELIDE_CODE" + enable_mlib=no + no_x=yes + enable_sdl=no +elif test x"$CC" = x"icc" -a x"`$CC -V 2>&1 | grep Intel`" != x""; then + dnl Intel C++ compiler + CFLAGS="-g -O3 -unroll -ip" +else + dnl non-gcc flags - we probably need exact configuration triplets here. + case "$host" in + sparc-sun-solaris*) + OPT_CFLAGS="$CFLAGS -xCC -fast -xO5" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]);; + esac +fi + +dnl Checks for libtool - this must be done after we set cflags +AC_DISABLE_SHARED +AC_LIBTOOL_WIN32_DLL +AC_PROG_LIBTOOL + +dnl Checks for libraries. + +dnl Checks for header files. +INCLUDES='-I$(top_srcdir)/include -I$(top_builddir)/include' +AC_SUBST([INCLUDES]) +AC_CHECK_HEADERS([sys/time.h sys/timeb.h io.h]) +AC_CHECK_GENERATE_INTTYPES([include]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_ALWAYS_INLINE +AC_C_RESTRICT +AC_C_BUILTIN_EXPECT +AC_TYPE_SIZE_T +AC_C_BIGENDIAN + +dnl Checks for library functions. +AC_CHECK_FUNCS([memalign gettimeofday ftime]) +AC_TYPE_SIGNAL + +builtin([include],[libmpeg2/configure.incl]) +builtin([include],[libvo/configure.incl]) + +AC_ARG_ENABLE([warnings], + [ --enable-warnings treat warnings as errors]) +if test x"$enable_warnings" = x"yes" -a x"$GCC" = x"yes"; then + dnl compiler warnings + OPT_CFLAGS="$CFLAGS -Werror" + AC_TRY_CFLAGS([$OPT_CFLAGS],[CFLAGS=$OPT_CFLAGS]) +elif test x"$TENDRA" = x"yes"; then + dnl TenDRA portability checking compiler + CFLAGS="$CFLAGS -DTenDRA_check" +fi + +AC_C_ATTRIBUTE_ALIGNED + +AC_OUTPUT diff --git a/vldp2/doc/Makefile.am b/vldp2/doc/Makefile.am new file mode 100644 index 000000000..a03ea9a00 --- /dev/null +++ b/vldp2/doc/Makefile.am @@ -0,0 +1,8 @@ +noinst_PROGRAMS = sample1 sample2 +sample1_SOURCES = sample1.c +sample1_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la +sample2_SOURCES = sample2.c +sample2_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a @LIBVO_LIBS@ + +EXTRA_DIST = libmpeg2.txt libvo.txt diff --git a/vldp2/doc/Makefile.in b/vldp2/doc/Makefile.in new file mode 100644 index 000000000..a8ddf020a --- /dev/null +++ b/vldp2/doc/Makefile.in @@ -0,0 +1,426 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +noinst_PROGRAMS = sample1 sample2 +sample1_SOURCES = sample1.c +sample1_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la +sample2_SOURCES = sample2.c +sample2_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a @LIBVO_LIBS@ + + +EXTRA_DIST = libmpeg2.txt libvo.txt +subdir = doc +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +noinst_PROGRAMS = sample1$(EXEEXT) sample2$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) + +am_sample1_OBJECTS = sample1.$(OBJEXT) +sample1_OBJECTS = $(am_sample1_OBJECTS) +sample1_DEPENDENCIES = $(top_builddir)/libmpeg2/libmpeg2.la +sample1_LDFLAGS = +am_sample2_OBJECTS = sample2.$(OBJEXT) +sample2_OBJECTS = $(am_sample2_OBJECTS) +sample2_DEPENDENCIES = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a +sample2_LDFLAGS = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/sample1.Po ./$(DEPDIR)/sample2.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(sample1_SOURCES) $(sample2_SOURCES) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(sample1_SOURCES) $(sample2_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +sample1$(EXEEXT): $(sample1_OBJECTS) $(sample1_DEPENDENCIES) + @rm -f sample1$(EXEEXT) + $(LINK) $(sample1_LDFLAGS) $(sample1_OBJECTS) $(sample1_LDADD) $(LIBS) +sample2$(EXEEXT): $(sample2_OBJECTS) $(sample2_DEPENDENCIES) + @rm -f sample2$(EXEEXT) + $(LINK) $(sample2_LDFLAGS) $(sample2_OBJECTS) $(sample2_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample2.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/doc/libmpeg2.txt b/vldp2/doc/libmpeg2.txt new file mode 100644 index 000000000..61260b55b --- /dev/null +++ b/vldp2/doc/libmpeg2.txt @@ -0,0 +1,12 @@ + +I - simplest example + +explanation of sequence_t, picture_t fields + +II - w/ color conversion + +III - pts + +IV - app that preallocates buffers + +V - app that does its own buffer management diff --git a/vldp2/doc/libvo.txt b/vldp2/doc/libvo.txt new file mode 100644 index 000000000..563a574d8 --- /dev/null +++ b/vldp2/doc/libvo.txt @@ -0,0 +1,87 @@ +Introduction to the libvo API + + +I - choosing an output module + +typedef struct vo_driver_s { + char * name; + vo_open_t * open; +} vo_driver_t; + +vo_driver_t * vo_drivers (void); + +going thru the driver array, we find the driver entry with the name we +want, and use the associated setup field in the next steps. If we do +not specify a given name, the first entry in the array is always the +most reasonable default. + + +II - initializing the output module + +vo_instance_t * vo_open (vo_open_t * open); + +this function returns a libvo instance ; this instance can then be +passed to libmpeg2 + + +III - setting up a video mode + +int vo_setup (vo_instance_t * this, int width, int height); + +This function initializes the libvo instance with the desired +resolution. On success it returns 0. + + +IV - displaying frames + +struct vo_frame_s { + uint8_t * base[3]; /* pointer to 3 planes */ + void (* copy) (vo_frame_t * frame, uint8_t **); + ... +}; + +vo_frame_t * vo_get_frame (vo_instance_t * this, int flags); + +This function is used to get a frame buffer before we start decoding a +frame. The flags are : VO_TOP_FIELD, VO_BOTTOM_FIELD, VO_BOTH_FIELDS - +indicate which field(s) will be decoded first, and VO_PREDICTION_FLAG +- used if the frame will be used by the decoder to predict future +frames, and must thus be conserved in memory for a longer time. + +The frames will not be queried in the display order ; however we can +make a few assumptions : all frames with the VO_PREDICTION_FLAG will +be queried in display order, and all frames without the +VO_PREDICTION_FLAG will be queried in display order too. The +prediction frames must be kept in memory for a longer time ; however +it is never necessary to keep more than two prediction frames at any +point in time. + +The base pointers in the frame points to allocated arrays that the +decoder will use as buffers for the decompressed picture. The queried +frame is not displayed yet, so we can work in these buffers without +worrying about display artefacts. + +The copy function, if not set to NULL, is to be called each time we're +done decompressing 16 lines (from either one or both fields, as +indicated in the vo_get_frame flags). After that the decoder is free +to overwrite the picture buffers if this is not a prediction +frame. The intent of the copy function is to enhance the cache +behaviour by letting the libvo process the yuv data just after it is +decompressed - while it is still fresh in the cache. + +void vo_field (vo_frame_t * frame, int flags); + +If we had started decoding only one of the fields, this is used to +indicate when we start decoding the second field. + +void vo_draw (vo_frame_t * frame); + +This is called when we're done working on this frame and we want it +actually displayed. + + +V - closing the output instance + +void vo_close (vo_instance_t * this); + +Close the output instance and free the associated memory diff --git a/vldp2/doc/sample1.c b/vldp2/doc/sample1.c new file mode 100644 index 000000000..40bcb4dfc --- /dev/null +++ b/vldp2/doc/sample1.c @@ -0,0 +1,102 @@ +/* + * sample1.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include +#include +#include + +#include "mpeg2.h" + +static void save_pgm (int width, int height, uint8_t * const * buf, int num) +{ + char filename[100]; + FILE * pgmfile; + int i; + + sprintf (filename, "%d.pgm", num); + pgmfile = fopen (filename, "wb"); + if (!pgmfile) + return; + fprintf (pgmfile, "P5\n%d %d\n255\n", width, height * 3 / 2); + fwrite (buf[0], width, height, pgmfile); + width >>= 1; + height >>= 1; + for (i = 0; i < height; i++) { + fwrite (buf[1] + i * width, width, 1, pgmfile); + fwrite (buf[2] + i * width, width, 1, pgmfile); + } + fclose (pgmfile); +} + +static void sample1 (FILE * file) +{ +#define BUFFER_SIZE 4096 + uint8_t buffer[BUFFER_SIZE]; + mpeg2dec_t * mpeg2dec; + const mpeg2_info_t * info; + int state; + int size; + int framenum = 0; + + mpeg2dec = mpeg2_init (); + if (mpeg2dec == NULL) + exit (1); + info = mpeg2_info (mpeg2dec); + + size = BUFFER_SIZE; + do { + state = mpeg2_parse (mpeg2dec); + switch (state) { + case -1: + size = fread (buffer, 1, BUFFER_SIZE, file); + mpeg2_buffer (mpeg2dec, buffer, buffer + size); + break; + case STATE_SLICE: + case STATE_END: + if (info->display_fbuf) + save_pgm (info->sequence->width, info->sequence->height, + info->display_fbuf->buf, framenum++); + break; + } + } while (size); + + mpeg2_close (mpeg2dec); +} + +int main (int argc, char ** argv) +{ + FILE * file; + + if (argc > 1) { + file = fopen (argv[1], "rb"); + if (!file) { + fprintf (stderr, "Could not open file %s\n", argv[1]); + exit (1); + } + } else + file = stdin; + + sample1 (file); + + return 0; +} diff --git a/vldp2/doc/sample2.c b/vldp2/doc/sample2.c new file mode 100644 index 000000000..7bbaec361 --- /dev/null +++ b/vldp2/doc/sample2.c @@ -0,0 +1,99 @@ +/* + * sample2.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include +#include +#include + +#include "mpeg2.h" +#include "convert.h" + +static void save_ppm (int width, int height, uint8_t * buf, int num) +{ + char filename[100]; + FILE * ppmfile; + + sprintf (filename, "%d.ppm", num); + ppmfile = fopen (filename, "wb"); + if (!ppmfile) + return; + fprintf (ppmfile, "P6\n%d %d\n255\n", width, height); + fwrite (buf, 3 * width, height, ppmfile); + fclose (ppmfile); +} + +static void sample2 (FILE * file) +{ +#define BUFFER_SIZE 4096 + uint8_t buffer[BUFFER_SIZE]; + mpeg2dec_t * mpeg2dec; + const mpeg2_info_t * info; + int state; + int size; + int framenum = 0; + + mpeg2dec = mpeg2_init (); + if (mpeg2dec == NULL) + exit (1); + info = mpeg2_info (mpeg2dec); + + size = BUFFER_SIZE; + do { + state = mpeg2_parse (mpeg2dec); + switch (state) { + case -1: + size = fread (buffer, 1, BUFFER_SIZE, file); + mpeg2_buffer (mpeg2dec, buffer, buffer + size); + break; + case STATE_SEQUENCE: + mpeg2_convert (mpeg2dec, convert_rgb24, NULL); + break; + case STATE_SLICE: + case STATE_END: + if (info->display_fbuf) + save_ppm (info->sequence->width, info->sequence->height, + info->display_fbuf->buf[0], framenum++); + break; + } + } while (size); + + mpeg2_close (mpeg2dec); +} + +int main (int argc, char ** argv) +{ + FILE * file; + + if (argc > 1) { + file = fopen (argv[1], "rb"); + if (!file) { + fprintf (stderr, "Could not open file %s\n", argv[1]); + exit (1); + } + } else + file = stdin; + + sample2 (file); + + return 0; +} diff --git a/vldp2/include/Makefile.am b/vldp2/include/Makefile.am new file mode 100644 index 000000000..56c98512d --- /dev/null +++ b/vldp2/include/Makefile.am @@ -0,0 +1,3 @@ +pkginclude_HEADERS = mpeg2.h convert.h + +EXTRA_DIST = video_out.h mmx.h alpha_asm.h attributes.h tendra.h diff --git a/vldp2/include/Makefile.in b/vldp2/include/Makefile.in new file mode 100644 index 000000000..345c31028 --- /dev/null +++ b/vldp2/include/Makefile.in @@ -0,0 +1,371 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +pkginclude_HEADERS = mpeg2.h convert.h + +EXTRA_DIST = video_out.h mmx.h alpha_asm.h attributes.h tendra.h +subdir = include +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +HEADERS = $(pkginclude_HEADERS) + +DIST_COMMON = $(pkginclude_HEADERS) Makefile.am Makefile.in config.h.in +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status include/config.h + +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + touch $(srcdir)/config.h.in + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(pkgincludedir) + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f"; \ + $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(pkgincludedir)/$$f"; \ + rm -f $(DESTDIR)$(pkgincludedir)/$$f; \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) config.h + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(pkgincludedir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-hdr distclean-libtool \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-pkgincludeHEADERS + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-pkgincludeHEADERS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am uninstall-pkgincludeHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/include/alpha_asm.h b/vldp2/include/alpha_asm.h new file mode 100644 index 000000000..6864ccc2e --- /dev/null +++ b/vldp2/include/alpha_asm.h @@ -0,0 +1,184 @@ +/* + * Alpha assembly macros + * Copyright (c) 2002 Falk Hueffner + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ALPHA_ASM_H +#define ALPHA_ASM_H + +#include + +#if defined __GNUC__ +# define GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define GNUC_PREREQ(maj, min) 0 +#endif + +#define AMASK_BWX (1 << 0) +#define AMASK_FIX (1 << 1) +#define AMASK_CIX (1 << 2) +#define AMASK_MVI (1 << 8) + +#ifdef __alpha_bwx__ +# define HAVE_BWX() 1 +#else +# define HAVE_BWX() (amask(AMASK_BWX) == 0) +#endif +#ifdef __alpha_fix__ +# define HAVE_FIX() 1 +#else +# define HAVE_FIX() (amask(AMASK_FIX) == 0) +#endif +#ifdef __alpha_max__ +# define HAVE_MVI() 1 +#else +# define HAVE_MVI() (amask(AMASK_MVI) == 0) +#endif +#ifdef __alpha_cix__ +# define HAVE_CIX() 1 +#else +# define HAVE_CIX() (amask(AMASK_CIX) == 0) +#endif + +inline static uint64_t BYTE_VEC(uint64_t x) +{ + x |= x << 8; + x |= x << 16; + x |= x << 32; + return x; +} +inline static uint64_t WORD_VEC(uint64_t x) +{ + x |= x << 16; + x |= x << 32; + return x; +} + +#define ldq(p) (*(const uint64_t *) (p)) +#define ldl(p) (*(const int32_t *) (p)) +#define stl(l, p) do { *(uint32_t *) (p) = (l); } while (0) +#define stq(l, p) do { *(uint64_t *) (p) = (l); } while (0) +#define sextw(x) ((int16_t) (x)) + +#ifdef __GNUC__ +struct unaligned_long { uint64_t l; } __attribute__((packed)); +#define ldq_u(p) (*(const uint64_t *) (((uint64_t) (p)) & ~7ul)) +#define uldq(a) (((const struct unaligned_long *) (a))->l) + +#if GNUC_PREREQ(3,0) +/* Unfortunately, __builtin_prefetch is slightly buggy on Alpha. The + defines here are kludged so we still get the right + instruction. This needs to be adapted as soon as gcc is fixed. */ +# define prefetch(p) __builtin_prefetch((p), 0, 1) +# define prefetch_en(p) __builtin_prefetch((p), 1, 1) +# define prefetch_m(p) __builtin_prefetch((p), 0, 0) +# define prefetch_men(p) __builtin_prefetch((p), 1, 0) +#else +# define prefetch(p) asm volatile("ldl $31,%0" : : "m"(*(const char *) (p)) : "memory") +# define prefetch_en(p) asm volatile("ldq $31,%0" : : "m"(*(const char *) (p)) : "memory") +# define prefetch_m(p) asm volatile("lds $f31,%0" : : "m"(*(const char *) (p)) : "memory") +# define prefetch_men(p) asm volatile("ldt $f31,%0" : : "m"(*(const char *) (p)) : "memory") +#endif + +#if GNUC_PREREQ(3,3) +#define cmpbge __builtin_alpha_cmpbge +/* Avoid warnings. */ +#define extql(a, b) __builtin_alpha_extql(a, (uint64_t) (b)) +#define extwl(a, b) __builtin_alpha_extwl(a, (uint64_t) (b)) +#define extqh(a, b) __builtin_alpha_extqh(a, (uint64_t) (b)) +#define zap __builtin_alpha_zap +#define zapnot __builtin_alpha_zapnot +#define amask __builtin_alpha_amask +#define implver __builtin_alpha_implver +#define rpcc __builtin_alpha_rpcc +#define minub8 __builtin_alpha_minub8 +#define minsb8 __builtin_alpha_minsb8 +#define minuw4 __builtin_alpha_minuw4 +#define minsw4 __builtin_alpha_minsw4 +#define maxub8 __builtin_alpha_maxub8 +#define maxsb8 __builtin_alpha_maxsb8 +#define maxuw4 __builtin_alpha_maxuw4 +#define maxsw4 __builtin_alpha_maxsw4 +#define perr __builtin_alpha_perr +#define pklb __builtin_alpha_pklb +#define pkwb __builtin_alpha_pkwb +#define unpkbl __builtin_alpha_unpkbl +#define unpkbw __builtin_alpha_unpkbw +#else +#define cmpbge(a, b) ({ uint64_t __r; asm ("cmpbge %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extql(a, b) ({ uint64_t __r; asm ("extql %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extwl(a, b) ({ uint64_t __r; asm ("extwl %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extqh(a, b) ({ uint64_t __r; asm ("extqh %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define zap(a, b) ({ uint64_t __r; asm ("zap %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define zapnot(a, b) ({ uint64_t __r; asm ("zapnot %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define amask(a) ({ uint64_t __r; asm ("amask %1,%0" : "=r" (__r) : "rI" (a)); __r; }) +#define implver() ({ uint64_t __r; asm ("implver %0" : "=r" (__r)); __r; }) +#define rpcc() ({ uint64_t __r; asm volatile ("rpcc %0" : "=r" (__r)); __r; }) +#define minub8(a, b) ({ uint64_t __r; asm ("minub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minsb8(a, b) ({ uint64_t __r; asm ("minsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minuw4(a, b) ({ uint64_t __r; asm ("minuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minsw4(a, b) ({ uint64_t __r; asm ("minsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxub8(a, b) ({ uint64_t __r; asm ("maxub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxsb8(a, b) ({ uint64_t __r; asm ("maxsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxuw4(a, b) ({ uint64_t __r; asm ("maxuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxsw4(a, b) ({ uint64_t __r; asm ("maxsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define perr(a, b) ({ uint64_t __r; asm ("perr %r1,%r2,%0" : "=r" (__r) : "%rJ" (a), "rJ" (b)); __r; }) +#define pklb(a) ({ uint64_t __r; asm ("pklb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define pkwb(a) ({ uint64_t __r; asm ("pkwb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define unpkbl(a) ({ uint64_t __r; asm ("unpkbl %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define unpkbw(a) ({ uint64_t __r; asm ("unpkbw %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#endif +#define wh64(p) asm volatile("wh64 (%0)" : : "r"(p) : "memory") + +#elif defined(__DECC) /* Digital/Compaq/hp "ccc" compiler */ + +#include +#define ldq_u(a) asm ("ldq_u %v0,0(%a0)", a) +#define uldq(a) (*(const __unaligned uint64_t *) (a)) +#define cmpbge(a, b) asm ("cmpbge %a0,%a1,%v0", a, b) +#define extql(a, b) asm ("extql %a0,%a1,%v0", a, b) +#define extwl(a, b) asm ("extwl %a0,%a1,%v0", a, b) +#define extqh(a, b) asm ("extqh %a0,%a1,%v0", a, b) +#define zap(a, b) asm ("zap %a0,%a1,%v0", a, b) +#define zapnot(a, b) asm ("zapnot %a0,%a1,%v0", a, b) +#define amask(a) asm ("amask %a0,%v0", a) +#define implver() asm ("implver %v0") +#define rpcc() asm ("rpcc %v0") +#define minub8(a, b) asm ("minub8 %a0,%a1,%v0", a, b) +#define minsb8(a, b) asm ("minsb8 %a0,%a1,%v0", a, b) +#define minuw4(a, b) asm ("minuw4 %a0,%a1,%v0", a, b) +#define minsw4(a, b) asm ("minsw4 %a0,%a1,%v0", a, b) +#define maxub8(a, b) asm ("maxub8 %a0,%a1,%v0", a, b) +#define maxsb8(a, b) asm ("maxsb8 %a0,%a1,%v0", a, b) +#define maxuw4(a, b) asm ("maxuw4 %a0,%a1,%v0", a, b) +#define maxsw4(a, b) asm ("maxsw4 %a0,%a1,%v0", a, b) +#define perr(a, b) asm ("perr %a0,%a1,%v0", a, b) +#define pklb(a) asm ("pklb %a0,%v0", a) +#define pkwb(a) asm ("pkwb %a0,%v0", a) +#define unpkbl(a) asm ("unpkbl %a0,%v0", a) +#define unpkbw(a) asm ("unpkbw %a0,%v0", a) +#define wh64(a) asm ("wh64 %a0", a) + +#else +#error "Unknown compiler!" +#endif + +#endif /* ALPHA_ASM_H */ diff --git a/vldp2/include/attributes.h b/vldp2/include/attributes.h new file mode 100644 index 000000000..96a86b26c --- /dev/null +++ b/vldp2/include/attributes.h @@ -0,0 +1,37 @@ +/* + * attributes.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* use gcc attribs to align critical data structures */ +#ifdef ATTRIBUTE_ALIGNED_MAX +#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) +#else +#define ATTR_ALIGN(align) +#endif + +#ifdef HAVE_BUILTIN_EXPECT +#define likely(x) __builtin_expect ((x) != 0, 1) +#define unlikely(x) __builtin_expect ((x) != 0, 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif diff --git a/vldp2/include/config.h.in b/vldp2/include/config.h.in new file mode 100644 index 000000000..653164d8e --- /dev/null +++ b/vldp2/include/config.h.in @@ -0,0 +1,148 @@ +/* include/config.h.in. Generated from configure.in by autoheader. */ + +/* autodetect accelerations */ +#undef ACCEL_DETECT + +/* alpha architecture */ +#undef ARCH_ALPHA + +/* ppc architecture */ +#undef ARCH_PPC + +/* x86 architecture */ +#undef ARCH_X86 + +/* maximum supported data alignment */ +#undef ATTRIBUTE_ALIGNED_MAX + +/* debug mode configuration */ +#undef DEBUG + +/* Define if you have the `__builtin_expect' function. */ +#undef HAVE_BUILTIN_EXPECT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DDRAW_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `ftime' function. */ +#undef HAVE_FTIME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IO_H + +/* Define to 1 if you have the `memalign' function. */ +#undef HAVE_MEMALIGN + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMEB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* libmpeg2 mediaLib support */ +#undef LIBMPEG2_MLIB + +/* libvo DirectX support */ +#undef LIBVO_DX + +/* libvo mediaLib support */ +#undef LIBVO_MLIB + +/* libvo SDL support */ +#undef LIBVO_SDL + +/* libvo X11 support */ +#undef LIBVO_X11 + +/* libvo Xv support */ +#undef LIBVO_XV + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* The size of a `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of a `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of a `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define as `__inline' if that's what the C compiler calls it, or to nothing + if it is not supported. */ +#undef inline + +/* Define as `__restrict' if that's what the C compiler calls it, or to + nothing if it is not supported. */ +#undef restrict + +/* Define to `unsigned' if does not define. */ +#undef size_t diff --git a/vldp2/include/convert.h b/vldp2/include/convert.h new file mode 100644 index 000000000..fd51fd84c --- /dev/null +++ b/vldp2/include/convert.h @@ -0,0 +1,56 @@ +/* + * convert.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CONVERT_H +#define CONVERT_H + +#define CONVERT_FRAME 0 +#define CONVERT_TOP_FIELD 1 +#define CONVERT_BOTTOM_FIELD 2 +#define CONVERT_BOTH_FIELDS 3 + +typedef struct convert_init_s { + void * id; + int id_size; + int buf_size[3]; + void (* start) (void * id, uint8_t * const * dest, int flags); + void (* copy) (void * id, uint8_t * const * src, unsigned int v_offset); +} convert_init_t; + +typedef void convert_t (int width, int height, uint32_t accel, void * arg, + convert_init_t * result); + +convert_t convert_rgb32; +convert_t convert_rgb24; +convert_t convert_rgb16; +convert_t convert_rgb15; +convert_t convert_bgr32; +convert_t convert_bgr24; +convert_t convert_bgr16; +convert_t convert_bgr15; + +#define CONVERT_RGB 0 +#define CONVERT_BGR 1 +convert_t * convert_rgb (int order, int bpp); + +#endif /* CONVERT_H */ diff --git a/vldp2/include/mmx.h b/vldp2/include/mmx.h new file mode 100644 index 000000000..c05bfe1cc --- /dev/null +++ b/vldp2/include/mmx.h @@ -0,0 +1,263 @@ +/* + * mmx.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* + * The type of an value that fits in an MMX register (note that long + * long constant values MUST be suffixed by LL and unsigned long long + * values by ULL, lest they be truncated by the compiler) + */ + +typedef union { + long long q; /* Quadword (64-bit) value */ + unsigned long long uq; /* Unsigned Quadword */ + int d[2]; /* 2 Doubleword (32-bit) values */ + unsigned int ud[2]; /* 2 Unsigned Doubleword */ + short w[4]; /* 4 Word (16-bit) values */ + unsigned short uw[4]; /* 4 Unsigned Word */ + char b[8]; /* 8 Byte (8-bit) values */ + unsigned char ub[8]; /* 8 Unsigned Byte */ + float s[2]; /* Single-precision (32-bit) value */ +} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ + + +#define mmx_i2r(op,imm,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "i" (imm) ) + +#define mmx_m2r(op,mem,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "m" (mem)) + +#define mmx_r2m(op,reg,mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=m" (mem) \ + : /* nothing */ ) + +#define mmx_r2r(op,regs,regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + + +#define emms() __asm__ __volatile__ ("emms") + +#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) +#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) +#define movd_v2r(var,reg) __asm__ __volatile__ ("movd %0, %%" #reg \ + : /* nothing */ \ + : "rm" (var)) +#define movd_r2v(reg,var) __asm__ __volatile__ ("movd %%" #reg ", %0" \ + : "=rm" (var) \ + : /* nothing */ ) + +#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) +#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) +#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) + +#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) +#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) +#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) +#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) + +#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) +#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) + +#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) +#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) +#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) +#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) +#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) +#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) + +#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) +#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) +#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) +#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) + +#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) +#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) +#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) +#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) + +#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) +#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) + +#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) +#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) + +#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) +#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) +#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) +#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) +#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) +#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) + +#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) +#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) +#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) +#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) +#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) +#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) + +#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) +#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) + +#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) +#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) + +#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) +#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) + +#define por_m2r(var,reg) mmx_m2r (por, var, reg) +#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) + +#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) +#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) +#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) +#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) +#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) +#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) +#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) +#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) +#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) + +#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) +#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) +#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) +#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) +#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) +#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) + +#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) +#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) +#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) +#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) +#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) +#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) +#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) +#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) +#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) + +#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) +#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) +#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) +#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) +#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) +#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) + +#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) +#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) +#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) +#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) + +#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) +#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) +#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) +#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) + +#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) +#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) +#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) +#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) +#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) +#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) + +#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) +#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) +#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) +#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) +#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) +#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) + +#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) +#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) + + +/* 3DNOW extensions */ + +#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) +#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) + + +/* AMD MMX extensions - also available in intel SSE */ + + +#define mmx_m2ri(op,mem,reg,imm) \ + __asm__ __volatile__ (#op " %1, %0, %%" #reg \ + : /* nothing */ \ + : "m" (mem), "i" (imm)) + +#define mmx_r2ri(op,regs,regd,imm) \ + __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ + : /* nothing */ \ + : "i" (imm) ) + +#define mmx_fetch(mem,hint) \ + __asm__ __volatile__ ("prefetch" #hint " %0" \ + : /* nothing */ \ + : "m" (mem)) + + +#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) + +#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) + +#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) +#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) +#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) +#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) + +#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) + +#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) + +#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) +#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) + +#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) +#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) + +#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) +#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) + +#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) +#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) + +#define pmovmskb(mmreg,reg) \ + __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) + +#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) +#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) + +#define prefetcht0(mem) mmx_fetch (mem, t0) +#define prefetcht1(mem) mmx_fetch (mem, t1) +#define prefetcht2(mem) mmx_fetch (mem, t2) +#define prefetchnta(mem) mmx_fetch (mem, nta) + +#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) +#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) + +#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) +#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) + +#define sfence() __asm__ __volatile__ ("sfence\n\t") diff --git a/vldp2/include/mpeg2.h b/vldp2/include/mpeg2.h new file mode 100644 index 000000000..22e2ca3f0 --- /dev/null +++ b/vldp2/include/mpeg2.h @@ -0,0 +1,147 @@ +/* + * mpeg2.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MPEG2_H +#define MPEG2_H + +#define SEQ_FLAG_MPEG2 1 +#define SEQ_FLAG_CONSTRAINED_PARAMETERS 2 +#define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4 +#define SEQ_FLAG_LOW_DELAY 8 +#define SEQ_FLAG_COLOUR_DESCRIPTION 16 + +#define SEQ_MASK_VIDEO_FORMAT 0xe0 +#define SEQ_VIDEO_FORMAT_COMPONENT 0 +#define SEQ_VIDEO_FORMAT_PAL 0x20 +#define SEQ_VIDEO_FORMAT_NTSC 0x40 +#define SEQ_VIDEO_FORMAT_SECAM 0x60 +#define SEQ_VIDEO_FORMAT_MAC 0x80 +#define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0 + +typedef struct { + unsigned int width, height; + unsigned int chroma_width, chroma_height; + unsigned int byte_rate; + unsigned int vbv_buffer_size; + uint32_t flags; + + unsigned int picture_width, picture_height; + unsigned int display_width, display_height; + unsigned int pixel_width, pixel_height; + unsigned int frame_period; + + uint8_t profile_level_id; + uint8_t colour_primaries; + uint8_t transfer_characteristics; + uint8_t matrix_coefficients; +} sequence_t; + +#define PIC_MASK_CODING_TYPE 7 +#define PIC_FLAG_CODING_TYPE_I 1 +#define PIC_FLAG_CODING_TYPE_P 2 +#define PIC_FLAG_CODING_TYPE_B 3 +#define PIC_FLAG_CODING_TYPE_D 4 + +#define PIC_FLAG_TOP_FIELD_FIRST 8 +#define PIC_FLAG_PROGRESSIVE_FRAME 16 +#define PIC_FLAG_COMPOSITE_DISPLAY 32 +#define PIC_FLAG_SKIP 64 +#define PIC_FLAG_PTS 128 +#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000 + +typedef struct { + unsigned int temporal_reference; + unsigned int nb_fields; + uint32_t pts; + uint32_t flags; + struct { + int x, y; + } display_offset[3]; +} picture_t; + +typedef struct { + uint8_t * buf[3]; + void * id; +} fbuf_t; + +typedef struct { + const sequence_t * sequence; + const picture_t * current_picture; + const picture_t * current_picture_2nd; + const fbuf_t * current_fbuf; + const picture_t * display_picture; + const picture_t * display_picture_2nd; + const fbuf_t * display_fbuf; + const fbuf_t * discard_fbuf; + const uint8_t * user_data; + int user_data_len; +} mpeg2_info_t; + +typedef struct mpeg2dec_s mpeg2dec_t; +typedef struct decoder_s decoder_t; + +#define STATE_SEQUENCE 1 +#define STATE_SEQUENCE_REPEATED 2 +#define STATE_GOP 3 +#define STATE_PICTURE 4 +#define STATE_SLICE_1ST 5 +#define STATE_PICTURE_2ND 6 +#define STATE_SLICE 7 +#define STATE_END 8 +#define STATE_INVALID 9 + +struct convert_init_s; +void mpeg2_convert (mpeg2dec_t * mpeg2dec, + void (* convert) (int, int, uint32_t, void *, + struct convert_init_s *), void * arg); +void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id); +void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf); +void mpeg2_init_fbuf (decoder_t * decoder, uint8_t * current_fbuf[3], + uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]); + +void mpeg2_slice (decoder_t * decoder, int code, const uint8_t * buffer); + +#define MPEG2_ACCEL_X86_MMX 1 +#define MPEG2_ACCEL_X86_3DNOW 2 +#define MPEG2_ACCEL_X86_MMXEXT 4 +#define MPEG2_ACCEL_PPC_ALTIVEC 1 +#define MPEG2_ACCEL_ALPHA 1 +#define MPEG2_ACCEL_ALPHA_MVI 2 +#define MPEG2_ACCEL_MLIB 0x40000000 +#define MPEG2_ACCEL_DETECT 0x80000000 + +uint32_t mpeg2_accel (uint32_t accel); +mpeg2dec_t * mpeg2_init (void); +void mpeg2_partial_init(mpeg2dec_t *); // MPO added +const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec); +void mpeg2_close (mpeg2dec_t * mpeg2dec); + +void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end); +int mpeg2_parse (mpeg2dec_t * mpeg2dec); + +void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip); +void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end); + +void mpeg2_pts (mpeg2dec_t * mpeg2dec, uint32_t pts); + +#endif /* MPEG2_H */ diff --git a/vldp2/include/tendra.h b/vldp2/include/tendra.h new file mode 100644 index 000000000..95754a05e --- /dev/null +++ b/vldp2/include/tendra.h @@ -0,0 +1,35 @@ +/* + * tendra.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#pragma TenDRA begin +#pragma TenDRA longlong type warning + +#ifdef TenDRA_check + +#pragma TenDRA conversion analysis (pointer-int explicit) off +#pragma TenDRA implicit function declaration off + +/* avoid the "No declarations in translation unit" problem */ +int TenDRA; + +#endif /* TenDRA_check */ diff --git a/vldp2/include/video_out.h b/vldp2/include/video_out.h new file mode 100644 index 000000000..0b8fe51be --- /dev/null +++ b/vldp2/include/video_out.h @@ -0,0 +1,60 @@ +/* + * video_out.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VIDEO_OUT_H +#define VIDEO_OUT_H + +struct convert_init_s; +typedef struct { + void (* convert) (int, int, uint32_t, void *, struct convert_init_s *); +} vo_setup_result_t; + +typedef struct vo_instance_s vo_instance_t; +struct vo_instance_s { + int (* setup) (vo_instance_t * instance, int width, int height, + vo_setup_result_t * result); + void (* setup_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id); + void (* set_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id); + void (* start_fbuf) (vo_instance_t * instance, + uint8_t * const * buf, void * id); + void (* draw) (vo_instance_t * instance, uint8_t * const * buf, void * id); + void (* discard) (vo_instance_t * instance, + uint8_t * const * buf, void * id); + void (* close) (vo_instance_t * instance); +}; + +typedef vo_instance_t * vo_open_t (void); + +typedef struct { + char * name; + vo_open_t * open; +} vo_driver_t; + +void vo_accel (uint32_t accel); + +/* return NULL terminated array of all drivers */ +vo_driver_t * vo_drivers (void); + +vo_instance_t * vo_null_open (void); // MPO added because this isn't declared elsewhere ... + +#endif /* VIDEO_OUT_H */ diff --git a/vldp2/libmpeg2/Makefile.am b/vldp2/libmpeg2/Makefile.am new file mode 100644 index 000000000..2eea657e6 --- /dev/null +++ b/vldp2/libmpeg2/Makefile.am @@ -0,0 +1,16 @@ +AM_CFLAGS = @LIBMPEG2_CFLAGS@ + +lib_LTLIBRARIES = libmpeg2.la +libmpeg2_la_SOURCES = alloc.c cpu_accel.c header.c decode.c cpu_state.c \ + slice.c motion_comp_mmx.c idct_mmx.c \ + motion_comp_altivec.c idct_altivec.c \ + motion_comp_alpha.c idct_alpha.c \ + motion_comp_mlib.c idct_mlib.c \ + motion_comp.c idct.c +libmpeg2_la_LIBADD = @LIBMPEG2_LIBS@ +libmpeg2_la_LDFLAGS = -no-undefined + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libmpeg2.pc + +EXTRA_DIST = configure.incl vlc.h mpeg2_internal.h diff --git a/vldp2/libmpeg2/Makefile.in b/vldp2/libmpeg2/Makefile.in new file mode 100644 index 000000000..c99560105 --- /dev/null +++ b/vldp2/libmpeg2/Makefile.in @@ -0,0 +1,498 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +AM_CFLAGS = @LIBMPEG2_CFLAGS@ + +lib_LTLIBRARIES = libmpeg2.la +libmpeg2_la_SOURCES = alloc.c cpu_accel.c header.c decode.c cpu_state.c \ + slice.c motion_comp_mmx.c idct_mmx.c \ + motion_comp_altivec.c idct_altivec.c \ + motion_comp_alpha.c idct_alpha.c \ + motion_comp_mlib.c idct_mlib.c \ + motion_comp.c idct.c + +libmpeg2_la_LIBADD = @LIBMPEG2_LIBS@ +libmpeg2_la_LDFLAGS = -no-undefined + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libmpeg2.pc + +EXTRA_DIST = configure.incl vlc.h mpeg2_internal.h +subdir = libmpeg2 +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = libmpeg2.pc +LTLIBRARIES = $(lib_LTLIBRARIES) + +libmpeg2_la_DEPENDENCIES = +am_libmpeg2_la_OBJECTS = alloc.lo cpu_accel.lo header.lo decode.lo \ + cpu_state.lo slice.lo motion_comp_mmx.lo idct_mmx.lo \ + motion_comp_altivec.lo idct_altivec.lo motion_comp_alpha.lo \ + idct_alpha.lo motion_comp_mlib.lo idct_mlib.lo motion_comp.lo \ + idct.lo +libmpeg2_la_OBJECTS = $(am_libmpeg2_la_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/alloc.Plo ./$(DEPDIR)/cpu_accel.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/cpu_state.Plo ./$(DEPDIR)/decode.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/header.Plo ./$(DEPDIR)/idct.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/idct_alpha.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/idct_altivec.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/idct_mlib.Plo ./$(DEPDIR)/idct_mmx.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/motion_comp.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/motion_comp_alpha.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/motion_comp_altivec.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/motion_comp_mlib.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/motion_comp_mmx.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/slice.Plo +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(libmpeg2_la_SOURCES) +DATA = $(pkgconfig_DATA) + +DIST_COMMON = Makefile.am Makefile.in libmpeg2.pc.in +SOURCES = $(libmpeg2_la_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libmpeg2/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +libmpeg2.pc: $(top_builddir)/config.status libmpeg2.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +libLTLIBRARIES_INSTALL = $(INSTALL) +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" = "$$p" && dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libmpeg2.la: $(libmpeg2_la_OBJECTS) $(libmpeg2_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libmpeg2_la_LDFLAGS) $(libmpeg2_la_OBJECTS) $(libmpeg2_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu_accel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu_state.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/header.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idct.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idct_alpha.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idct_altivec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idct_mlib.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idct_mmx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motion_comp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motion_comp_alpha.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motion_comp_altivec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motion_comp_mlib.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motion_comp_mmx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slice.Plo@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +pkgconfigDATA_INSTALL = $(INSTALL_DATA) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(pkgconfigdir) + @list='$(pkgconfig_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f"; \ + $(pkgconfigDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgconfigdir)/$$f; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(pkgconfigdir)/$$f"; \ + rm -f $(DESTDIR)$(pkgconfigdir)/$$f; \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(pkgconfigdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-pkgconfigDATA + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \ + uninstall-pkgconfigDATA + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pkgconfigDATA \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \ + pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \ + uninstall-libLTLIBRARIES uninstall-pkgconfigDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/libmpeg2/alloc.c b/vldp2/libmpeg2/alloc.c new file mode 100644 index 000000000..0a434d978 --- /dev/null +++ b/vldp2/libmpeg2/alloc.c @@ -0,0 +1,76 @@ +/* + * alloc.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" + +#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) +/* some systems have memalign() but no declaration for it */ +void * memalign (size_t align, size_t size); +#endif + +void * (* mpeg2_malloc_hook) (int size, int reason) = NULL; +int (* mpeg2_free_hook) (void * buf) = NULL; + +void * mpeg2_malloc (int size, int reason) +{ + char * buf; + + if (mpeg2_malloc_hook) { + buf = (char *) mpeg2_malloc_hook (size, reason); + if (buf) + return buf; + } + +#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) && !defined(DEBUG) + return memalign (16, size); +#else + buf = (char *) malloc (size + 15 + sizeof (void **)); + if (buf) { + char * align_buf; + + align_buf = buf + 15 + sizeof (void **); + align_buf -= (long)align_buf & 15; + *(((void **)align_buf) - 1) = buf; + return align_buf; + } + return NULL; +#endif +} + +void mpeg2_free (void * buf) +{ + if (mpeg2_free_hook && mpeg2_free_hook (buf)) + return; + +#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) && !defined(DEBUG) + free (buf); +#else + free (*(((void **)buf) - 1)); +#endif +} diff --git a/vldp2/libmpeg2/configure.incl b/vldp2/libmpeg2/configure.incl new file mode 100644 index 000000000..95d497dbd --- /dev/null +++ b/vldp2/libmpeg2/configure.incl @@ -0,0 +1,25 @@ +AC_SUBST([LIBMPEG2_CFLAGS]) +AC_SUBST([LIBMPEG2_LIBS]) + +dnl avoid -fPIC when possible +AC_LIBTOOL_NON_PIC([LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -prefer-non-pic"]) + +dnl check for cpudetect +AC_ARG_ENABLE([accel-detect], + [ --disable-accel-detect make a version without accel detection code]) +if test x"$enable_accel_detect" != x"no"; then + AC_DEFINE([ACCEL_DETECT],,[autodetect accelerations]) +fi + +dnl check for mlib +AC_ARG_ENABLE([mlib], + [ --disable-mlib make a version not using mediaLib]) +if test x"$enable_mlib" != x"no"; then + cflags_save="$CFLAGS" + CFLAGS="$CFLAGS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib" + AC_CHECK_LIB([mlib],[mlib_VideoColorYUV2RGB420], + [AC_DEFINE([LIBMPEG2_MLIB],,[libmpeg2 mediaLib support]) + LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -I/opt/SUNWmlib/include" + LIBMPEG2_LIBS="$LIBMPEG2_LIBS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib -lmlib"]) + CFLAGS="$cflags_save" +fi diff --git a/vldp2/libmpeg2/cpu_accel.c b/vldp2/libmpeg2/cpu_accel.c new file mode 100644 index 000000000..809deabcd --- /dev/null +++ b/vldp2/libmpeg2/cpu_accel.c @@ -0,0 +1,175 @@ +/* + * cpu_accel.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include + +#include "mpeg2.h" + +#ifdef ACCEL_DETECT +#ifdef ARCH_X86 +static inline uint32_t arch_accel (void) +{ + uint32_t eax, ebx, ecx, edx; + int AMD; + uint32_t caps; + +#ifndef PIC +#define cpuid(op,eax,ebx,ecx,edx) \ + __asm__ ("cpuid" \ + : "=a" (eax), \ + "=b" (ebx), \ + "=c" (ecx), \ + "=d" (edx) \ + : "a" (op) \ + : "cc") +#else /* PIC version : save ebx */ +#define cpuid(op,eax,ebx,ecx,edx) \ + __asm__ ("push %%ebx\n\t" \ + "cpuid\n\t" \ + "movl %%ebx,%1\n\t" \ + "pop %%ebx" \ + : "=a" (eax), \ + "=r" (ebx), \ + "=c" (ecx), \ + "=d" (edx) \ + : "a" (op) \ + : "cc") +#endif + + __asm__ ("pushf\n\t" + "pushf\n\t" + "pop %0\n\t" + "movl %0,%1\n\t" + "xorl $0x200000,%0\n\t" + "push %0\n\t" + "popf\n\t" + "pushf\n\t" + "pop %0\n\t" + "popf" + : "=r" (eax), + "=r" (ebx) + : + : "cc"); + + if (eax == ebx) /* no cpuid */ + return 0; + + cpuid (0x00000000, eax, ebx, ecx, edx); + if (!eax) /* vendor string only */ + return 0; + + AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); + + cpuid (0x00000001, eax, ebx, ecx, edx); + if (! (edx & 0x00800000)) /* no MMX */ + return 0; + + caps = MPEG2_ACCEL_X86_MMX; + if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ + caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT; + + cpuid (0x80000000, eax, ebx, ecx, edx); + if (eax < 0x80000001) /* no extended capabilities */ + return caps; + + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & 0x80000000) + caps |= MPEG2_ACCEL_X86_3DNOW; + + if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ + caps |= MPEG2_ACCEL_X86_MMXEXT; + + return caps; +} +#endif /* ARCH_X86 */ + +#ifdef ARCH_PPC +#include +#include + +static sigjmp_buf jmpbuf; +static volatile sig_atomic_t canjump = 0; + +static RETSIGTYPE sigill_handler (int sig) +{ + if (!canjump) { + signal (sig, SIG_DFL); + raise (sig); + } + + canjump = 0; + siglongjmp (jmpbuf, 1); +} + +static inline uint32_t arch_accel (void) +{ + signal (SIGILL, sigill_handler); + if (sigsetjmp (jmpbuf, 1)) { + signal (SIGILL, SIG_DFL); + return 0; + } + + canjump = 1; + + asm volatile ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + signal (SIGILL, SIG_DFL); + return MPEG2_ACCEL_PPC_ALTIVEC; +} +#endif /* ARCH_PPC */ + +#ifdef ARCH_ALPHA +static inline uint32_t arch_accel (void) +{ + uint64_t no_mvi; + + asm volatile ("amask %1, %0" + : "=r" (no_mvi) + : "rI" (256)); /* AMASK_MVI */ + return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA | + MPEG2_ACCEL_ALPHA_MVI); +} +#endif /* ARCH_ALPHA */ +#endif + +uint32_t mpeg2_detect_accel (void) +{ + uint32_t accel; + + accel = 0; +#ifdef ACCEL_DETECT +#ifdef LIBMPEG2_MLIB + accel = MPEG2_ACCEL_MLIB; +#endif +#if defined (ARCH_X86) || defined (ARCH_PPC) || defined (ARCH_ALPHA) + accel |= arch_accel (); +#endif +#endif + return accel; +} diff --git a/vldp2/libmpeg2/cpu_state.c b/vldp2/libmpeg2/cpu_state.c new file mode 100644 index 000000000..7ba513367 --- /dev/null +++ b/vldp2/libmpeg2/cpu_state.c @@ -0,0 +1,119 @@ +/* + * cpu_state.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" +#ifdef ARCH_X86 +#include "mmx.h" +#endif + +void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; +void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; + +#ifdef ARCH_X86 +static void state_restore_mmx (cpu_state_t * state) +{ + emms (); +} +#endif + +#ifdef ARCH_PPC +static void state_save_altivec (cpu_state_t * state) +{ + asm (" \n" + " li %r9, 16 \n" + " stvx %v20, 0, %r3 \n" + " li %r11, 32 \n" + " stvx %v21, %r9, %r3 \n" + " li %r9, 48 \n" + " stvx %v22, %r11, %r3 \n" + " li %r11, 64 \n" + " stvx %v23, %r9, %r3 \n" + " li %r9, 80 \n" + " stvx %v24, %r11, %r3 \n" + " li %r11, 96 \n" + " stvx %v25, %r9, %r3 \n" + " li %r9, 112 \n" + " stvx %v26, %r11, %r3 \n" + " li %r11, 128 \n" + " stvx %v27, %r9, %r3 \n" + " li %r9, 144 \n" + " stvx %v28, %r11, %r3 \n" + " li %r11, 160 \n" + " stvx %v29, %r9, %r3 \n" + " li %r9, 176 \n" + " stvx %v30, %r11, %r3 \n" + " stvx %v31, %r9, %r3 \n" + ); +} + +static void state_restore_altivec (cpu_state_t * state) +{ + asm (" \n" + " li %r9, 16 \n" + " lvx %v20, 0, %r3 \n" + " li %r11, 32 \n" + " lvx %v21, %r9, %r3 \n" + " li %r9, 48 \n" + " lvx %v22, %r11, %r3 \n" + " li %r11, 64 \n" + " lvx %v23, %r9, %r3 \n" + " li %r9, 80 \n" + " lvx %v24, %r11, %r3 \n" + " li %r11, 96 \n" + " lvx %v25, %r9, %r3 \n" + " li %r9, 112 \n" + " lvx %v26, %r11, %r3 \n" + " li %r11, 128 \n" + " lvx %v27, %r9, %r3 \n" + " li %r9, 144 \n" + " lvx %v28, %r11, %r3 \n" + " li %r11, 160 \n" + " lvx %v29, %r9, %r3 \n" + " li %r9, 176 \n" + " lvx %v30, %r11, %r3 \n" + " lvx %v31, %r9, %r3 \n" + ); +} +#endif + +void mpeg2_cpu_state_init (uint32_t accel) +{ +#ifdef ARCH_X86 + if (accel & MPEG2_ACCEL_X86_MMX) { + mpeg2_cpu_state_restore = state_restore_mmx; + } +#endif +#ifdef ARCH_PPC + if (accel & MPEG2_ACCEL_PPC_ALTIVEC) { + mpeg2_cpu_state_save = state_save_altivec; + mpeg2_cpu_state_restore = state_restore_altivec; + } +#endif +} diff --git a/vldp2/libmpeg2/decode.c b/vldp2/libmpeg2/decode.c new file mode 100644 index 000000000..d222a2136 --- /dev/null +++ b/vldp2/libmpeg2/decode.c @@ -0,0 +1,460 @@ +/* + * decode.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include /* memcmp/memset, try to remove */ +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "convert.h" + +static int mpeg2_accels = 0; + +#define BUFFER_SIZE (1194 * 1024) + +const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec) +{ + return &(mpeg2dec->info); +} + +static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes) +{ + uint8_t * current; + uint32_t shift; + uint8_t * chunk_ptr; + uint8_t * limit; + uint8_t byte; + + if (!bytes) + return 0; + + current = mpeg2dec->buf_start; + shift = mpeg2dec->shift; + chunk_ptr = mpeg2dec->chunk_ptr; + limit = current + bytes; + + do { + byte = *current++; + if (shift == 0x00000100) { + int skipped; + + mpeg2dec->shift = 0xffffff00; + skipped = current - mpeg2dec->buf_start; + mpeg2dec->buf_start = current; + return skipped; + } + shift = (shift | byte) << 8; + } while (current < limit); + + mpeg2dec->shift = shift; + mpeg2dec->buf_start = current; + return 0; +} + +static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes) +{ + uint8_t * current; + uint32_t shift; + uint8_t * chunk_ptr; + uint8_t * limit; + uint8_t byte; + + if (!bytes) + return 0; + + current = mpeg2dec->buf_start; + shift = mpeg2dec->shift; + chunk_ptr = mpeg2dec->chunk_ptr; + limit = current + bytes; + + do { + byte = *current++; + if (shift == 0x00000100) { + int copied; + + mpeg2dec->shift = 0xffffff00; + mpeg2dec->chunk_ptr = chunk_ptr + 1; + copied = current - mpeg2dec->buf_start; + mpeg2dec->buf_start = current; + return copied; + } + shift = (shift | byte) << 8; + *chunk_ptr++ = byte; + } while (current < limit); + + mpeg2dec->shift = shift; + mpeg2dec->buf_start = current; + return 0; +} + +void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end) +{ + mpeg2dec->buf_start = start; + mpeg2dec->buf_end = end; +} + +static inline int seek_chunk (mpeg2dec_t * mpeg2dec) +{ + int size, skipped; + + size = mpeg2dec->buf_end - mpeg2dec->buf_start; + skipped = skip_chunk (mpeg2dec, size); + if (!skipped) { + mpeg2dec->bytes_since_pts += size; + return -1; + } + mpeg2dec->bytes_since_pts += skipped; + mpeg2dec->code = mpeg2dec->buf_start[-1]; + return 0; +} + +int mpeg2_seek_header (mpeg2dec_t * mpeg2dec) +{ + while (mpeg2dec->code != 0xb3 && + ((mpeg2dec->code != 0xb7 && mpeg2dec->code != 0xb8 && + mpeg2dec->code) || mpeg2dec->sequence.width == -1)) + if (seek_chunk (mpeg2dec)) + return -1; + mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + return mpeg2_parse_header (mpeg2dec); +} + +int mpeg2_seek_sequence (mpeg2dec_t * mpeg2dec) +{ + mpeg2dec->sequence.width = -1; + return mpeg2_seek_header (mpeg2dec); +} + +#define RECEIVED(code,state) (((state) << 8) + (code)) + +int mpeg2_parse (mpeg2dec_t * mpeg2dec) +{ + int size_buffer, size_chunk, copied; + + if (mpeg2dec->action) { + int state; + + state = mpeg2dec->action (mpeg2dec); + if (state) + return state; + } + + while (1) { + while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) < + mpeg2dec->nb_decode_slices) { + size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; + size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - + mpeg2dec->chunk_ptr); + if (size_buffer <= size_chunk) { + copied = copy_chunk (mpeg2dec, size_buffer); + if (!copied) { + mpeg2dec->bytes_since_pts += size_buffer; + mpeg2dec->chunk_ptr += size_buffer; + return -1; + } + } else { + copied = copy_chunk (mpeg2dec, size_chunk); + if (!copied) { + /* filled the chunk buffer without finding a start code */ + mpeg2dec->bytes_since_pts += size_chunk; + mpeg2dec->action = seek_chunk; + return STATE_INVALID; + } + } + mpeg2dec->bytes_since_pts += copied; + + mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code, + mpeg2dec->chunk_start); + mpeg2dec->code = mpeg2dec->buf_start[-1]; + mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; + } + if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1) + break; + if (seek_chunk (mpeg2dec)) + return -1; + } + + switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) { + case RECEIVED (0x00, STATE_SLICE_1ST): + case RECEIVED (0x00, STATE_SLICE): + mpeg2dec->action = mpeg2_header_picture_start; + break; + case RECEIVED (0xb7, STATE_SLICE): + mpeg2dec->action = mpeg2_header_end; + break; + case RECEIVED (0xb3, STATE_SLICE): + case RECEIVED (0xb8, STATE_SLICE): + mpeg2dec->action = mpeg2_parse_header; + break; + default: + mpeg2dec->action = mpeg2_seek_header; + return STATE_INVALID; + } + return mpeg2dec->state; +} + +int mpeg2_parse_header (mpeg2dec_t * mpeg2dec) +{ + static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = { + mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data, + mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop + }; + int size_buffer, size_chunk, copied; + + mpeg2dec->action = mpeg2_parse_header; + while (1) { + size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; + size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - + mpeg2dec->chunk_ptr); + if (size_buffer <= size_chunk) { + copied = copy_chunk (mpeg2dec, size_buffer); + if (!copied) { + mpeg2dec->bytes_since_pts += size_buffer; + mpeg2dec->chunk_ptr += size_buffer; + return -1; + } + } else { + copied = copy_chunk (mpeg2dec, size_chunk); + if (!copied) { + /* filled the chunk buffer without finding a start code */ + mpeg2dec->bytes_since_pts += size_chunk; + mpeg2dec->code = 0xb4; + mpeg2dec->action = mpeg2_seek_header; + return STATE_INVALID; + } + } + mpeg2dec->bytes_since_pts += copied; + + if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) { + mpeg2dec->code = mpeg2dec->buf_start[-1]; + mpeg2dec->action = mpeg2_seek_header; + return STATE_INVALID; + } + + mpeg2dec->code = mpeg2dec->buf_start[-1]; + switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) { + + /* state transition after a sequence header */ + case RECEIVED (0x00, STATE_SEQUENCE): + mpeg2dec->action = mpeg2_header_picture_start; + case RECEIVED (0xb8, STATE_SEQUENCE): + mpeg2_header_sequence_finalize (mpeg2dec); + break; + + /* other legal state transitions */ + case RECEIVED (0x00, STATE_GOP): + mpeg2dec->action = mpeg2_header_picture_start; + break; + case RECEIVED (0x01, STATE_PICTURE): + case RECEIVED (0x01, STATE_PICTURE_2ND): + mpeg2dec->action = mpeg2_header_slice_start; + break; + + /* legal headers within a given state */ + case RECEIVED (0xb2, STATE_SEQUENCE): + case RECEIVED (0xb2, STATE_GOP): + case RECEIVED (0xb2, STATE_PICTURE): + case RECEIVED (0xb2, STATE_PICTURE_2ND): + case RECEIVED (0xb5, STATE_SEQUENCE): + case RECEIVED (0xb5, STATE_PICTURE): + case RECEIVED (0xb5, STATE_PICTURE_2ND): + mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; + continue; + + default: + mpeg2dec->action = mpeg2_seek_header; + return STATE_INVALID; + } + + mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; + return mpeg2dec->state; + } +} + +void mpeg2_convert (mpeg2dec_t * mpeg2dec, + void (* convert) (int, int, uint32_t, void *, + struct convert_init_s *), void * arg) +{ + convert_init_t convert_init; + int size; + + convert_init.id = NULL; + convert (mpeg2dec->decoder.width, mpeg2dec->decoder.height, + mpeg2_accels, arg, &convert_init); + if (convert_init.id_size) { + convert_init.id = mpeg2dec->convert_id = + mpeg2_malloc (convert_init.id_size, ALLOC_CONVERT_ID); + convert (mpeg2dec->decoder.width, mpeg2dec->decoder.height, + mpeg2_accels, arg, &convert_init); + } + mpeg2dec->convert_size[0] = size = convert_init.buf_size[0]; + mpeg2dec->convert_size[1] = size += convert_init.buf_size[1]; + mpeg2dec->convert_size[2] = size += convert_init.buf_size[2]; + mpeg2dec->convert_start = convert_init.start; + mpeg2dec->convert_copy = convert_init.copy; + + size = mpeg2dec->decoder.width * mpeg2dec->decoder.height >> 2; + mpeg2dec->yuv_buf[0][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV); + mpeg2dec->yuv_buf[0][1] = mpeg2dec->yuv_buf[0][0] + 4 * size; + mpeg2dec->yuv_buf[0][2] = mpeg2dec->yuv_buf[0][0] + 5 * size; + mpeg2dec->yuv_buf[1][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV); + mpeg2dec->yuv_buf[1][1] = mpeg2dec->yuv_buf[1][0] + 4 * size; + mpeg2dec->yuv_buf[1][2] = mpeg2dec->yuv_buf[1][0] + 5 * size; + size = mpeg2dec->decoder.width * 8; + mpeg2dec->yuv_buf[2][0] = (uint8_t *) mpeg2_malloc (6 * size, ALLOC_YUV); + mpeg2dec->yuv_buf[2][1] = mpeg2dec->yuv_buf[2][0] + 4 * size; + mpeg2dec->yuv_buf[2][2] = mpeg2dec->yuv_buf[2][0] + 5 * size; +} + +void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id) +{ + fbuf_t * fbuf; + + if (mpeg2dec->custom_fbuf) { + mpeg2_set_fbuf (mpeg2dec, mpeg2dec->decoder.coding_type); + fbuf = mpeg2dec->fbuf[0]; + if (mpeg2dec->state == STATE_SEQUENCE) { + mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1]; + mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0]; + } + } else { + fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index].fbuf); + mpeg2dec->alloc_index_user = ++mpeg2dec->alloc_index; + } + fbuf->buf[0] = buf[0]; + fbuf->buf[1] = buf[1]; + fbuf->buf[2] = buf[2]; + fbuf->id = id; +} + +void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf) +{ + mpeg2dec->custom_fbuf = custom_fbuf; +} + +void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip) +{ + mpeg2dec->first_decode_slice = 1; + mpeg2dec->nb_decode_slices = skip ? 0 : (0xb0 - 1); +} + +void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end) +{ + start = (start < 1) ? 1 : (start > 0xb0) ? 0xb0 : start; + end = (end < start) ? start : (end > 0xb0) ? 0xb0 : end; + mpeg2dec->first_decode_slice = start; + mpeg2dec->nb_decode_slices = end - start; +} + +void mpeg2_pts (mpeg2dec_t * mpeg2dec, uint32_t pts) +{ + mpeg2dec->pts_previous = mpeg2dec->pts_current; + mpeg2dec->pts_current = pts; + mpeg2dec->num_pts++; + mpeg2dec->bytes_since_pts = 0; +} + +uint32_t mpeg2_accel (uint32_t accel) +{ + if (!mpeg2_accels) { + if (accel & MPEG2_ACCEL_DETECT) + accel |= mpeg2_detect_accel (); + mpeg2_accels = accel |= MPEG2_ACCEL_DETECT; + mpeg2_cpu_state_init (accel); + mpeg2_idct_init (accel); + mpeg2_mc_init (accel); + } + return mpeg2_accels & ~MPEG2_ACCEL_DETECT; +} + +mpeg2dec_t * mpeg2_init (void) +{ + mpeg2dec_t * mpeg2dec; + + mpeg2_accel (MPEG2_ACCEL_DETECT); + + mpeg2dec = (mpeg2dec_t *) mpeg2_malloc (sizeof (mpeg2dec_t), + ALLOC_MPEG2DEC); + if (mpeg2dec == NULL) + return NULL; + + memset (mpeg2dec, 0, sizeof (mpeg2dec_t)); + + mpeg2dec->chunk_buffer = (uint8_t *) mpeg2_malloc (BUFFER_SIZE + 4, + ALLOC_CHUNK); + + mpeg2dec->shift = 0xffffff00; + mpeg2dec->action = mpeg2_seek_sequence; + mpeg2dec->code = 0xb4; + mpeg2dec->first_decode_slice = 1; + mpeg2dec->nb_decode_slices = 0xb0 - 1; + mpeg2dec->convert_id = NULL; + + /* initialize substructures */ + mpeg2_header_state_init (mpeg2dec); + + return mpeg2dec; +} + +// start MPO +// Same as mpeg2_init without the malloc's, so this can be used to reset libmpeg2 +void mpeg2_partial_init(mpeg2dec_t *mpeg2dec) +{ + uint8_t *tmp = mpeg2dec->chunk_buffer; // save this since the whole struct is about to get wiped + + memset (mpeg2dec, 0, sizeof (mpeg2dec_t)); + + mpeg2dec->chunk_buffer = tmp; + mpeg2dec->shift = 0xffffff00; + mpeg2dec->action = mpeg2_seek_sequence; + mpeg2dec->code = 0xb4; + mpeg2dec->first_decode_slice = 1; + mpeg2dec->nb_decode_slices = 0xb0 - 1; + mpeg2dec->convert_id = NULL; + + /* initialize substructures */ + mpeg2_header_state_init (mpeg2dec); +} +// stop MPO + +void mpeg2_close (mpeg2dec_t * mpeg2dec) +{ + int i; + + /* static uint8_t finalizer[] = {0,0,1,0xb4}; */ + /* mpeg2_decode_data (mpeg2dec, finalizer, finalizer+4); */ + + mpeg2_free (mpeg2dec->chunk_buffer); + if (!mpeg2dec->custom_fbuf) + for (i = mpeg2dec->alloc_index_user; i < mpeg2dec->alloc_index; i++) + mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[0]); + if (mpeg2dec->convert_start) + for (i = 0; i < 3; i++) + mpeg2_free (mpeg2dec->yuv_buf[i][0]); + if (mpeg2dec->convert_id) + mpeg2_free (mpeg2dec->convert_id); + mpeg2_free (mpeg2dec); +} diff --git a/vldp2/libmpeg2/header.c b/vldp2/libmpeg2/header.c new file mode 100644 index 000000000..548d6bf21 --- /dev/null +++ b/vldp2/libmpeg2/header.c @@ -0,0 +1,691 @@ +/* + * header.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include /* defines NULL */ +#include /* memcmp */ + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "convert.h" +#include "attributes.h" + +#define SEQ_EXT 2 +#define SEQ_DISPLAY_EXT 4 +#define QUANT_MATRIX_EXT 8 +#define COPYRIGHT_EXT 0x10 +#define PIC_DISPLAY_EXT 0x80 +#define PIC_CODING_EXT 0x100 + +/* default intra quant matrix, in zig-zag order */ +static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { + 8, + 16, 16, + 19, 16, 19, + 22, 22, 22, 22, + 22, 22, 26, 24, 26, + 27, 27, 27, 26, 26, 26, + 26, 27, 27, 27, 29, 29, 29, + 34, 34, 34, 29, 29, 29, 27, 27, + 29, 29, 32, 32, 34, 34, 37, + 38, 37, 35, 35, 34, 35, + 38, 38, 40, 40, 40, + 48, 48, 46, 46, + 56, 56, 58, + 69, 69, + 83 +}; + +uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = { + /* Zig-Zag scan pattern */ + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = { + /* Alternate scan pattern */ + 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63 +}; + +void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec) +{ + mpeg2dec->decoder.scan = mpeg2_scan_norm; + mpeg2dec->picture = mpeg2dec->pictures; + mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf; + mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf; + mpeg2dec->fbuf[2] = &mpeg2dec->fbuf_alloc[2].fbuf; + mpeg2dec->first = 1; + mpeg2dec->alloc_index = 0; + mpeg2dec->alloc_index_user = 0; +} + +static void reset_info (mpeg2_info_t * info) +{ + info->current_picture = info->current_picture_2nd = NULL; + info->display_picture = info->display_picture_2nd = NULL; + info->current_fbuf = info->display_fbuf = info->discard_fbuf = NULL; + info->user_data = NULL; info->user_data_len = 0; +} + +int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + sequence_t * sequence = &(mpeg2dec->new_sequence); + decoder_t * decoder = &(mpeg2dec->decoder); + static unsigned int frame_period[9] = { + 0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000 + }; + int width, height; + int i; + + if ((buffer[6] & 0x20) != 0x20) /* missing marker_bit */ + return 1; + + i = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; + sequence->display_width = sequence->picture_width = width = i >> 12; + sequence->display_height = sequence->picture_height = height = i & 0xfff; + decoder->width = sequence->width = width = (width + 15) & ~15; + decoder->height = sequence->height = height = (height + 15) & ~15; + decoder->vertical_position_extension = (height > 2800); + sequence->chroma_width = width >> 1; + sequence->chroma_height = height >> 1; + + sequence->flags = SEQ_FLAG_PROGRESSIVE_SEQUENCE; + + sequence->pixel_width = buffer[3] >> 4; /* aspect ratio */ + sequence->frame_period = 0; + if ((buffer[3] & 15) < 9) + sequence->frame_period = frame_period[buffer[3] & 15]; + + sequence->byte_rate = (buffer[4]<<10) | (buffer[5]<<2) | (buffer[6]>>6); + + sequence->vbv_buffer_size = ((buffer[6]<<16)|(buffer[7]<<8))&0x1ff800; + + if (buffer[7] & 4) + sequence->flags |= SEQ_FLAG_CONSTRAINED_PARAMETERS; + + if (buffer[7] & 2) { + for (i = 0; i < 64; i++) + decoder->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i+7] << 7) | (buffer[i+8] >> 1); + buffer += 64; + } else + for (i = 0; i < 64; i++) + decoder->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + default_intra_quantizer_matrix [i]; + + if (buffer[7] & 1) + for (i = 0; i < 64; i++) + decoder->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = + buffer[i+8]; + else + for (i = 0; i < 64; i++) + decoder->non_intra_quantizer_matrix[i] = 16; + + sequence->profile_level_id = 0x80; + sequence->colour_primaries = 1; + sequence->transfer_characteristics = 1; + sequence->matrix_coefficients = 1; + + decoder->mpeg1 = 1; + decoder->intra_dc_precision = 0; + decoder->frame_pred_frame_dct = 1; + decoder->q_scale_type = 0; + decoder->concealment_motion_vectors = 0; + decoder->scan = mpeg2_scan_norm; + decoder->picture_structure = FRAME_PICTURE; + + mpeg2dec->ext_state = SEQ_EXT; + mpeg2dec->state = STATE_SEQUENCE; + mpeg2dec->display_offset_x = mpeg2dec->display_offset_y = 0; + + reset_info (&(mpeg2dec->info)); + return 0; +} + +static int sequence_ext (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + sequence_t * sequence = &(mpeg2dec->new_sequence); + decoder_t * decoder = &(mpeg2dec->decoder); + int width, height; + uint32_t flags; + + if (!(buffer[3] & 1)) + return 1; + + sequence->profile_level_id = (buffer[0] << 4) | (buffer[1] >> 4); + + width = sequence->display_width = sequence->picture_width += + ((buffer[1] << 13) | (buffer[2] << 5)) & 0x3000; + height = sequence->display_height = sequence->picture_height += + (buffer[2] << 7) & 0x3000; + decoder->vertical_position_extension = (height > 2800); + flags = sequence->flags | SEQ_FLAG_MPEG2; + if (!(buffer[1] & 8)) { + flags &= ~SEQ_FLAG_PROGRESSIVE_SEQUENCE; + height = (height + 31) & ~31; + } + if (buffer[5] & 0x80) + flags |= SEQ_FLAG_LOW_DELAY; + sequence->flags = flags; + decoder->width = sequence->width = width = (width + 15) & ~15; + decoder->height = sequence->height = height = (height + 15) & ~15; + switch (buffer[1] & 6) { + case 0: /* invalid */ + return 1; + case 2: /* 4:2:0 */ + height >>= 1; + case 4: /* 4:2:2 */ + width >>= 1; + } + sequence->chroma_width = width; + sequence->chroma_height = height; + + sequence->byte_rate += ((buffer[2]<<25) | (buffer[3]<<17)) & 0x3ffc0000; + + sequence->vbv_buffer_size |= buffer[4] << 21; + + sequence->frame_period = + sequence->frame_period * ((buffer[5]&31)+1) / (((buffer[5]>>2)&3)+1); + + decoder->mpeg1 = 0; + + mpeg2dec->ext_state = SEQ_DISPLAY_EXT; + + return 0; +} + +static int sequence_display_ext (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + sequence_t * sequence = &(mpeg2dec->new_sequence); + uint32_t flags; + + flags = ((sequence->flags & ~SEQ_MASK_VIDEO_FORMAT) | + ((buffer[0]<<4) & SEQ_MASK_VIDEO_FORMAT)); + if (buffer[0] & 1) { + flags |= SEQ_FLAG_COLOUR_DESCRIPTION; + sequence->colour_primaries = buffer[1]; + sequence->transfer_characteristics = buffer[2]; + sequence->matrix_coefficients = buffer[3]; + buffer += 3; + } + + if (!(buffer[2] & 2)) /* missing marker_bit */ + return 1; + + sequence->display_width = (buffer[1] << 6) | (buffer[2] >> 2); + sequence->display_height = + ((buffer[2]& 1 ) << 13) | (buffer[3] << 5) | (buffer[4] >> 3); + + return 0; +} + +static inline void finalize_sequence (sequence_t * sequence) +{ + int width; + int height; + + sequence->byte_rate *= 50; + + if (sequence->flags & SEQ_FLAG_MPEG2) { + switch (sequence->pixel_width) { + case 1: /* square pixels */ + sequence->pixel_width = sequence->pixel_height = 1; return; + case 2: /* 4:3 aspect ratio */ + width = 4; height = 3; break; + case 3: /* 16:9 aspect ratio */ + width = 16; height = 9; break; + case 4: /* 2.21:1 aspect ratio */ + width = 221; height = 100; break; + default: /* illegal */ + sequence->pixel_width = sequence->pixel_height = 0; return; + } + width *= sequence->display_height; + height *= sequence->display_width; + + } else { + if (sequence->byte_rate == 50 * 0x3ffff) + sequence->byte_rate = 0; /* mpeg-1 VBR */ + + switch (sequence->pixel_width) { + case 0: case 15: /* illegal */ + sequence->pixel_width = sequence->pixel_height = 0; return; + case 1: /* square pixels */ + sequence->pixel_width = sequence->pixel_height = 1; return; + case 3: /* 720x576 16:9 */ + sequence->pixel_width = 64; sequence->pixel_height = 45; return; + case 6: /* 720x480 16:9 */ + sequence->pixel_width = 32; sequence->pixel_height = 27; return; + case 12: /* 720*480 4:3 */ + sequence->pixel_width = 8; sequence->pixel_height = 9; return; + default: + height = 88 * sequence->pixel_width + 1171; + width = 2000; + } + } + + sequence->pixel_width = width; + sequence->pixel_height = height; + while (width) { /* find greatest common divisor */ + int tmp = width; + width = height % tmp; + height = tmp; + } + sequence->pixel_width /= height; + sequence->pixel_height /= height; +} + +void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec) +{ + sequence_t * sequence = &(mpeg2dec->new_sequence); + + finalize_sequence (sequence); + + /* + * according to 6.1.1.6, repeat sequence headers should be + * identical to the original. However some DVDs dont respect that + * and have different bitrates in the repeat sequence headers. So + * we'll ignore that in the comparison and still consider these as + * repeat sequence headers. + */ + mpeg2dec->sequence.byte_rate = sequence->byte_rate; + if (!memcmp (&(mpeg2dec->sequence), sequence, sizeof (sequence_t))) + mpeg2dec->state = STATE_SEQUENCE_REPEATED; + mpeg2dec->sequence = *sequence; + + mpeg2dec->info.sequence = &(mpeg2dec->sequence); +} + +int mpeg2_header_gop (mpeg2dec_t * mpeg2dec) +{ + mpeg2dec->state = STATE_GOP; + reset_info (&(mpeg2dec->info)); + return 0; +} + +void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int coding_type) +{ + int i; + + for (i = 0; i < 3; i++) + if (mpeg2dec->fbuf[1] != &mpeg2dec->fbuf_alloc[i].fbuf && + mpeg2dec->fbuf[2] != &mpeg2dec->fbuf_alloc[i].fbuf) { + mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[i].fbuf; + mpeg2dec->info.current_fbuf = mpeg2dec->fbuf[0]; + if ((coding_type == B_TYPE) || + (mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) { + if ((coding_type == B_TYPE) || (mpeg2dec->convert_start)) + mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[0]; + mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[0]; + } + break; + } +} + +int mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec) +{ + decoder_t * decoder = &(mpeg2dec->decoder); + picture_t * picture; + + if (mpeg2dec->state != STATE_SLICE_1ST) { + mpeg2dec->state = STATE_PICTURE; + picture = mpeg2dec->pictures; + if ((decoder->coding_type != PIC_FLAG_CODING_TYPE_B) ^ + (mpeg2dec->picture >= mpeg2dec->pictures + 2)) + picture += 2; + } else { + mpeg2dec->state = STATE_PICTURE_2ND; + picture = mpeg2dec->picture + 1; /* second field picture */ + } + mpeg2dec->picture = picture; + picture->flags = 0; + if (mpeg2dec->num_pts) { + if (mpeg2dec->bytes_since_pts >= 4) { + mpeg2dec->num_pts = 0; + picture->pts = mpeg2dec->pts_current; + picture->flags = PIC_FLAG_PTS; + } else if (mpeg2dec->num_pts > 1) { + mpeg2dec->num_pts = 1; + picture->pts = mpeg2dec->pts_previous; + picture->flags = PIC_FLAG_PTS; + } + } + picture->display_offset[0].x = picture->display_offset[1].x = + picture->display_offset[2].x = mpeg2dec->display_offset_x; + picture->display_offset[0].y = picture->display_offset[1].y = + picture->display_offset[2].y = mpeg2dec->display_offset_y; + return mpeg2_parse_header (mpeg2dec); +} + +int mpeg2_header_picture (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + picture_t * picture = mpeg2dec->picture; + decoder_t * decoder = &(mpeg2dec->decoder); + int type; + int low_delay; + + type = (buffer [1] >> 3) & 7; + low_delay = mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY; + + if (mpeg2dec->state == STATE_PICTURE) { + picture_t * other; + + decoder->second_field = 0; + other = mpeg2dec->pictures; + if (other == picture) + other += 2; + if (decoder->coding_type != PIC_FLAG_CODING_TYPE_B) { + mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1]; + mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0]; + } + mpeg2dec->fbuf[0] = NULL; + reset_info (&(mpeg2dec->info)); + mpeg2dec->info.current_picture = picture; + mpeg2dec->info.display_picture = picture; + if (type != PIC_FLAG_CODING_TYPE_B) { + if (!low_delay) { + if (mpeg2dec->first) { + mpeg2dec->info.display_picture = NULL; + mpeg2dec->first = 0; + } else { + mpeg2dec->info.display_picture = other; + if (other->nb_fields == 1) + mpeg2dec->info.display_picture_2nd = other + 1; + mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[1]; + } + } + if (!low_delay + !mpeg2dec->convert_start) + mpeg2dec->info.discard_fbuf = + mpeg2dec->fbuf[!low_delay + !mpeg2dec->convert_start]; + } + if (!mpeg2dec->custom_fbuf) { + while (mpeg2dec->alloc_index < 3) { + fbuf_t * fbuf; + + fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf); + fbuf->id = NULL; + if (mpeg2dec->convert_start) { + fbuf->buf[0] = + (uint8_t *) mpeg2_malloc (mpeg2dec->convert_size[0], + ALLOC_CONVERTED); + fbuf->buf[1] = fbuf->buf[0] + mpeg2dec->convert_size[1]; + fbuf->buf[2] = fbuf->buf[0] + mpeg2dec->convert_size[2]; + } else { + int size; + size = mpeg2dec->decoder.width * mpeg2dec->decoder.height; + fbuf->buf[0] = (uint8_t *) mpeg2_malloc (6 * size >> 2, + ALLOC_YUV); + fbuf->buf[1] = fbuf->buf[0] + size; + fbuf->buf[2] = fbuf->buf[1] + (size >> 2); + } + } + mpeg2_set_fbuf (mpeg2dec, type); + } + } else { + decoder->second_field = 1; + mpeg2dec->info.current_picture_2nd = picture; + mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0; + if (low_delay || type == PIC_FLAG_CODING_TYPE_B) + mpeg2dec->info.display_picture_2nd = picture; + } + mpeg2dec->ext_state = PIC_CODING_EXT; + + picture->temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); + + decoder->coding_type = type; + picture->flags |= type; + + if (type == PIC_FLAG_CODING_TYPE_P || type == PIC_FLAG_CODING_TYPE_B) { + /* forward_f_code and backward_f_code - used in mpeg1 only */ + decoder->f_motion.f_code[1] = (buffer[3] >> 2) & 1; + decoder->f_motion.f_code[0] = + (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; + decoder->b_motion.f_code[1] = (buffer[4] >> 6) & 1; + decoder->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; + } + + /* XXXXXX decode extra_information_picture as well */ + + picture->nb_fields = 2; + + return 0; +} + +static int picture_coding_ext (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + picture_t * picture = mpeg2dec->picture; + decoder_t * decoder = &(mpeg2dec->decoder); + uint32_t flags; + + /* pre subtract 1 for use later in compute_motion_vector */ + decoder->f_motion.f_code[0] = (buffer[0] & 15) - 1; + decoder->f_motion.f_code[1] = (buffer[1] >> 4) - 1; + decoder->b_motion.f_code[0] = (buffer[1] & 15) - 1; + decoder->b_motion.f_code[1] = (buffer[2] >> 4) - 1; + + flags = picture->flags; + decoder->intra_dc_precision = (buffer[2] >> 2) & 3; + decoder->picture_structure = buffer[2] & 3; + switch (decoder->picture_structure) { + case TOP_FIELD: + flags |= PIC_FLAG_TOP_FIELD_FIRST; + case BOTTOM_FIELD: + picture->nb_fields = 1; + break; + case FRAME_PICTURE: + if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)) { + picture->nb_fields = (buffer[3] & 2) ? 3 : 2; + flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0; + } else + picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2; + break; + default: + return 1; + } + decoder->top_field_first = buffer[3] >> 7; + decoder->frame_pred_frame_dct = (buffer[3] >> 6) & 1; + decoder->concealment_motion_vectors = (buffer[3] >> 5) & 1; + decoder->q_scale_type = (buffer[3] >> 4) & 1; + decoder->intra_vlc_format = (buffer[3] >> 3) & 1; + decoder->scan = (buffer[3] & 4) ? mpeg2_scan_alt : mpeg2_scan_norm; + flags |= (buffer[4] & 0x80) ? PIC_FLAG_PROGRESSIVE_FRAME : 0; + if (buffer[4] & 0x40) + flags |= (((buffer[4]<<26) | (buffer[5]<<18) | (buffer[6]<<10)) & + PIC_MASK_COMPOSITE_DISPLAY) | PIC_FLAG_COMPOSITE_DISPLAY; + picture->flags = flags; + + mpeg2dec->ext_state = PIC_DISPLAY_EXT | COPYRIGHT_EXT | QUANT_MATRIX_EXT; + + return 0; +} + +static int picture_display_ext (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + picture_t * picture = mpeg2dec->picture; + int i, nb_pos; + + nb_pos = picture->nb_fields; + if (mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE) + nb_pos >>= 1; + + for (i = 0; i < nb_pos; i++) { + int x, y; + + x = ((buffer[4*i] << 24) | (buffer[4*i+1] << 16) | + (buffer[4*i+2] << 8) | buffer[4*i+3]) >> (11-2*i); + y = ((buffer[4*i+2] << 24) | (buffer[4*i+3] << 16) | + (buffer[4*i+4] << 8) | buffer[4*i+5]) >> (10-2*i); + if (! (x & y & 1)) + return 1; + picture->display_offset[i].x = mpeg2dec->display_offset_x = x >> 1; + picture->display_offset[i].y = mpeg2dec->display_offset_y = y >> 1; + } + for (; i < 3; i++) { + picture->display_offset[i].x = mpeg2dec->display_offset_x; + picture->display_offset[i].y = mpeg2dec->display_offset_y; + } + return 0; +} + +static int copyright_ext (mpeg2dec_t * mpeg2dec) +{ + return 0; +} + +static int quant_matrix_ext (mpeg2dec_t * mpeg2dec) +{ + uint8_t * buffer = mpeg2dec->chunk_start; + decoder_t * decoder = &(mpeg2dec->decoder); + int i; + + if (buffer[0] & 8) { + for (i = 0; i < 64; i++) + decoder->intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i] << 5) | (buffer[i+1] >> 3); + buffer += 64; + } + + if (buffer[0] & 4) + for (i = 0; i < 64; i++) + decoder->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = + (buffer[i] << 6) | (buffer[i+1] >> 2); + + return 0; +} + +int mpeg2_header_extension (mpeg2dec_t * mpeg2dec) +{ + static int (* parser[]) (mpeg2dec_t *) = { + 0, sequence_ext, sequence_display_ext, quant_matrix_ext, + copyright_ext, 0, 0, picture_display_ext, picture_coding_ext + }; + int ext, ext_bit; + + ext = mpeg2dec->chunk_start[0] >> 4; + ext_bit = 1 << ext; + + if (!(mpeg2dec->ext_state & ext_bit)) + return 0; /* ignore illegal extensions */ + mpeg2dec->ext_state &= ~ext_bit; + return parser[ext] (mpeg2dec); +} + +int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec) +{ + if (!mpeg2dec->info.user_data_len) + mpeg2dec->info.user_data = mpeg2dec->chunk_start; + else + mpeg2dec->info.user_data_len += 3; + mpeg2dec->info.user_data_len += (mpeg2dec->chunk_ptr - 4 - + mpeg2dec->chunk_start); + mpeg2dec->chunk_start = mpeg2dec->chunk_ptr - 1; + + return 0; +} + +int mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec) +{ + mpeg2dec->state = ((mpeg2dec->picture->nb_fields > 1 || + mpeg2dec->state == STATE_PICTURE_2ND) ? + STATE_SLICE : STATE_SLICE_1ST); + + if (!(mpeg2dec->nb_decode_slices)) + mpeg2dec->picture->flags |= PIC_FLAG_SKIP; + else if (mpeg2dec->convert_start) { + int flags; + + switch (mpeg2dec->decoder.picture_structure) { + case TOP_FIELD: flags = CONVERT_TOP_FIELD; break; + case BOTTOM_FIELD: flags = CONVERT_BOTTOM_FIELD; break; + default: + flags = + ((mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE) ? + CONVERT_FRAME : CONVERT_BOTH_FIELDS); + } + mpeg2dec->convert_start (mpeg2dec->convert_id, + mpeg2dec->fbuf[0]->buf, flags); + + mpeg2dec->decoder.convert = mpeg2dec->convert_copy; + mpeg2dec->decoder.fbuf_id = mpeg2dec->convert_id; + + if (mpeg2dec->decoder.coding_type == B_TYPE) + mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->yuv_buf[2], + mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1], + mpeg2dec->yuv_buf[mpeg2dec->yuv_index]); + else { + mpeg2_init_fbuf (&(mpeg2dec->decoder), + mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1], + mpeg2dec->yuv_buf[mpeg2dec->yuv_index], + mpeg2dec->yuv_buf[mpeg2dec->yuv_index]); + if (mpeg2dec->state == STATE_SLICE) + mpeg2dec->yuv_index ^= 1; + } + } else { + int b_type; + + mpeg2dec->decoder.convert = NULL; + b_type = (mpeg2dec->decoder.coding_type == B_TYPE); + mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->fbuf[0]->buf, + mpeg2dec->fbuf[b_type + 1]->buf, + mpeg2dec->fbuf[b_type]->buf); + } + mpeg2dec->action = NULL; + return 0; +} + +int mpeg2_header_end (mpeg2dec_t * mpeg2dec) +{ + picture_t * picture; + int b_type; + + picture = mpeg2dec->pictures; + if (mpeg2dec->picture < picture + 2) + picture = mpeg2dec->pictures + 2; + + mpeg2dec->state = STATE_INVALID; + reset_info (&(mpeg2dec->info)); + b_type = (mpeg2dec->decoder.coding_type == B_TYPE); + if (!(mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) { + mpeg2dec->info.display_picture = picture; + if (picture->nb_fields == 1) + mpeg2dec->info.display_picture_2nd = picture + 1; + mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[b_type]; + if (!mpeg2dec->convert_start) + mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type + 1]; + } else if (!mpeg2dec->convert_start) + mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type]; + mpeg2dec->action = mpeg2_seek_sequence; + return STATE_END; +} diff --git a/vldp2/libmpeg2/idct.c b/vldp2/libmpeg2/idct.c new file mode 100644 index 000000000..bcae07815 --- /dev/null +++ b/vldp2/libmpeg2/idct.c @@ -0,0 +1,284 @@ +/* + * idct.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" + +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +/* idct main entry point */ +void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); +void (* mpeg2_idct_add) (int last, int16_t * block, + uint8_t * dest, int stride); + +static uint8_t clip_lut[1024]; +#define CLIP(i) ((clip_lut+384)[(i)]) + +#if 0 +#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ +do { \ + t0 = W0*d0 + W1*d1; \ + t1 = W0*d1 - W1*d0; \ +} while (0) +#else +#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ +do { \ + int tmp = W0 * (d0 + d1); \ + t0 = tmp + (W1 - W0) * d1; \ + t1 = tmp - (W1 + W0) * d0; \ +} while (0) +#endif + +static void inline idct_row (int16_t * const block) +{ + int d0, d1, d2, d3; + int a0, a1, a2, a3, b0, b1, b2, b3; + int t0, t1, t2, t3; + + /* shortcut */ + if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] | + ((int32_t *)block)[3]))) { + uint32_t tmp = (uint16_t) (block[0] << 3); + tmp |= tmp << 16; + ((int32_t *)block)[0] = tmp; + ((int32_t *)block)[1] = tmp; + ((int32_t *)block)[2] = tmp; + ((int32_t *)block)[3] = tmp; + return; + } + + d0 = (block[0] << 11) + 128; + d1 = block[1]; + d2 = block[2] << 11; + d3 = block[3]; + t0 = d0 + d2; + t1 = d0 - d2; + BUTTERFLY (t2, t3, W6, W2, d3, d1); + a0 = t0 + t2; + a1 = t1 + t3; + a2 = t1 - t3; + a3 = t0 - t2; + + d0 = block[4]; + d1 = block[5]; + d2 = block[6]; + d3 = block[7]; + BUTTERFLY (t0, t1, W7, W1, d3, d0); + BUTTERFLY (t2, t3, W3, W5, d1, d2); + b0 = t0 + t2; + b3 = t1 + t3; + t0 -= t2; + t1 -= t3; + b1 = ((t0 + t1) * 181) >> 8; + b2 = ((t0 - t1) * 181) >> 8; + + block[0] = (a0 + b0) >> 8; + block[1] = (a1 + b1) >> 8; + block[2] = (a2 + b2) >> 8; + block[3] = (a3 + b3) >> 8; + block[4] = (a3 - b3) >> 8; + block[5] = (a2 - b2) >> 8; + block[6] = (a1 - b1) >> 8; + block[7] = (a0 - b0) >> 8; +} + +static void inline idct_col (int16_t * const block) +{ + int d0, d1, d2, d3; + int a0, a1, a2, a3, b0, b1, b2, b3; + int t0, t1, t2, t3; + + d0 = (block[8*0] << 11) + 65536; + d1 = block[8*1]; + d2 = block[8*2] << 11; + d3 = block[8*3]; + t0 = d0 + d2; + t1 = d0 - d2; + BUTTERFLY (t2, t3, W6, W2, d3, d1); + a0 = t0 + t2; + a1 = t1 + t3; + a2 = t1 - t3; + a3 = t0 - t2; + + d0 = block[8*4]; + d1 = block[8*5]; + d2 = block[8*6]; + d3 = block[8*7]; + BUTTERFLY (t0, t1, W7, W1, d3, d0); + BUTTERFLY (t2, t3, W3, W5, d1, d2); + b0 = t0 + t2; + b3 = t1 + t3; + t0 = (t0 - t2) >> 8; + t1 = (t1 - t3) >> 8; + b1 = (t0 + t1) * 181; + b2 = (t0 - t1) * 181; + + block[8*0] = (a0 + b0) >> 17; + block[8*1] = (a1 + b1) >> 17; + block[8*2] = (a2 + b2) >> 17; + block[8*3] = (a3 + b3) >> 17; + block[8*4] = (a3 - b3) >> 17; + block[8*5] = (a2 - b2) >> 17; + block[8*6] = (a1 - b1) >> 17; + block[8*7] = (a0 - b0) >> 17; +} + +static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, + const int stride) +{ + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + for (i = 0; i < 8; i++) + idct_col (block + i); + do { + dest[0] = CLIP (block[0]); + dest[1] = CLIP (block[1]); + dest[2] = CLIP (block[2]); + dest[3] = CLIP (block[3]); + dest[4] = CLIP (block[4]); + dest[5] = CLIP (block[5]); + dest[6] = CLIP (block[6]); + dest[7] = CLIP (block[7]); + + block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; + block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; + + dest += stride; + block += 8; + } while (--i); +} + +static void mpeg2_idct_add_c (const int last, int16_t * block, + uint8_t * dest, const int stride) +{ + int i; + + if (last != 129 || (block[0] & 7) == 4) { + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + for (i = 0; i < 8; i++) + idct_col (block + i); + do { + dest[0] = CLIP (block[0] + dest[0]); + dest[1] = CLIP (block[1] + dest[1]); + dest[2] = CLIP (block[2] + dest[2]); + dest[3] = CLIP (block[3] + dest[3]); + dest[4] = CLIP (block[4] + dest[4]); + dest[5] = CLIP (block[5] + dest[5]); + dest[6] = CLIP (block[6] + dest[6]); + dest[7] = CLIP (block[7] + dest[7]); + + block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; + block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; + + dest += stride; + block += 8; + } while (--i); + } else { + int DC; + + DC = (block[0] + 4) >> 3; + block[0] = block[63] = 0; + i = 8; + do { + dest[0] = CLIP (DC + dest[0]); + dest[1] = CLIP (DC + dest[1]); + dest[2] = CLIP (DC + dest[2]); + dest[3] = CLIP (DC + dest[3]); + dest[4] = CLIP (DC + dest[4]); + dest[5] = CLIP (DC + dest[5]); + dest[6] = CLIP (DC + dest[6]); + dest[7] = CLIP (DC + dest[7]); + dest += stride; + } while (--i); + } +} + +void mpeg2_idct_init (uint32_t accel) +{ +#ifdef ARCH_X86 + if (accel & MPEG2_ACCEL_X86_MMXEXT) { + mpeg2_idct_copy = mpeg2_idct_copy_mmxext; + mpeg2_idct_add = mpeg2_idct_add_mmxext; + mpeg2_idct_mmx_init (); + } else if (accel & MPEG2_ACCEL_X86_MMX) { + mpeg2_idct_copy = mpeg2_idct_copy_mmx; + mpeg2_idct_add = mpeg2_idct_add_mmx; + mpeg2_idct_mmx_init (); + } else +#endif +#ifdef ARCH_PPC + if (accel & MPEG2_ACCEL_PPC_ALTIVEC) { + mpeg2_idct_copy = mpeg2_idct_copy_altivec; + mpeg2_idct_add = mpeg2_idct_add_altivec; + mpeg2_idct_altivec_init (); + } else +#endif +#ifdef ARCH_ALPHA + if (accel & MPEG2_ACCEL_ALPHA_MVI) { + mpeg2_idct_copy = mpeg2_idct_copy_mvi; + mpeg2_idct_add = mpeg2_idct_add_mvi; + mpeg2_idct_alpha_init (0); + } else if (accel & MPEG2_ACCEL_ALPHA) { + mpeg2_idct_copy = mpeg2_idct_copy_alpha; + mpeg2_idct_add = mpeg2_idct_add_alpha; + mpeg2_idct_alpha_init (1); + } else +#endif +#ifdef LIBMPEG2_MLIB + if (accel & MPEG2_ACCEL_MLIB) { + mpeg2_idct_copy = mpeg2_idct_copy_mlib_non_ieee; + mpeg2_idct_add = (getenv ("MLIB_NON_IEEE") ? + mpeg2_idct_add_mlib_non_ieee : mpeg2_idct_add_mlib); + } else +#endif + { + extern uint8_t mpeg2_scan_norm[64]; + extern uint8_t mpeg2_scan_alt[64]; + int i, j; + + mpeg2_idct_copy = mpeg2_idct_copy_c; + mpeg2_idct_add = mpeg2_idct_add_c; + for (i = -384; i < 640; i++) + clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i); + for (i = 0; i < 64; i++) { + j = mpeg2_scan_norm[i]; + mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); + } + } +} diff --git a/vldp2/libmpeg2/idct_alpha.c b/vldp2/libmpeg2/idct_alpha.c new file mode 100644 index 000000000..fc2911259 --- /dev/null +++ b/vldp2/libmpeg2/idct_alpha.c @@ -0,0 +1,380 @@ +/* + * idct_alpha.c + * Copyright (C) 2002 Falk Hueffner + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef ARCH_ALPHA + +#include +#include + +#include "alpha_asm.h" +#include "attributes.h" + +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +static uint8_t clip_lut[1024]; +#define CLIP(i) ((clip_lut+384)[(i)]) + +#if 0 +#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ +do { \ + t0 = W0*d0 + W1*d1; \ + t1 = W0*d1 - W1*d0; \ +} while (0) +#else +#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ +do { \ + int_fast32_t tmp = W0 * (d0 + d1); \ + t0 = tmp + (W1 - W0) * d1; \ + t1 = tmp - (W1 + W0) * d0; \ +} while (0) +#endif + +static void inline idct_row (int16_t * const block) +{ + uint64_t l, r; + int_fast32_t d0, d1, d2, d3; + int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; + int_fast32_t t0, t1, t2, t3; + + l = ldq (block); + r = ldq (block + 4); + + /* shortcut */ + if (likely (!((l & ~0xffffUL) | r))) { + uint64_t tmp = (uint16_t) (l << 3); + tmp |= tmp << 16; + tmp |= tmp << 32; + ((int32_t *)block)[0] = tmp; + ((int32_t *)block)[1] = tmp; + ((int32_t *)block)[2] = tmp; + ((int32_t *)block)[3] = tmp; + return; + } + + d0 = (sextw (l) << 11) + 128; + d1 = sextw (extwl (l, 2)); + d2 = sextw (extwl (l, 4)) << 11; + d3 = sextw (extwl (l, 6)); + t0 = d0 + d2; + t1 = d0 - d2; + BUTTERFLY (t2, t3, W6, W2, d3, d1); + a0 = t0 + t2; + a1 = t1 + t3; + a2 = t1 - t3; + a3 = t0 - t2; + + d0 = sextw (r); + d1 = sextw (extwl (r, 2)); + d2 = sextw (extwl (r, 4)); + d3 = sextw (extwl (r, 6)); + BUTTERFLY (t0, t1, W7, W1, d3, d0); + BUTTERFLY (t2, t3, W3, W5, d1, d2); + b0 = t0 + t2; + b3 = t1 + t3; + t0 -= t2; + t1 -= t3; + b1 = ((t0 + t1) * 181) >> 8; + b2 = ((t0 - t1) * 181) >> 8; + + block[0] = (a0 + b0) >> 8; + block[1] = (a1 + b1) >> 8; + block[2] = (a2 + b2) >> 8; + block[3] = (a3 + b3) >> 8; + block[4] = (a3 - b3) >> 8; + block[5] = (a2 - b2) >> 8; + block[6] = (a1 - b1) >> 8; + block[7] = (a0 - b0) >> 8; +} + +static void inline idct_col (int16_t * const block) +{ + int_fast32_t d0, d1, d2, d3; + int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; + int_fast32_t t0, t1, t2, t3; + + d0 = (block[8*0] << 11) + 65536; + d1 = block[8*1]; + d2 = block[8*2] << 11; + d3 = block[8*3]; + t0 = d0 + d2; + t1 = d0 - d2; + BUTTERFLY (t2, t3, W6, W2, d3, d1); + a0 = t0 + t2; + a1 = t1 + t3; + a2 = t1 - t3; + a3 = t0 - t2; + + d0 = block[8*4]; + d1 = block[8*5]; + d2 = block[8*6]; + d3 = block[8*7]; + BUTTERFLY (t0, t1, W7, W1, d3, d0); + BUTTERFLY (t2, t3, W3, W5, d1, d2); + b0 = t0 + t2; + b3 = t1 + t3; + t0 = (t0 - t2) >> 8; + t1 = (t1 - t3) >> 8; + b1 = (t0 + t1) * 181; + b2 = (t0 - t1) * 181; + + block[8*0] = (a0 + b0) >> 17; + block[8*1] = (a1 + b1) >> 17; + block[8*2] = (a2 + b2) >> 17; + block[8*3] = (a3 + b3) >> 17; + block[8*4] = (a3 - b3) >> 17; + block[8*5] = (a2 - b2) >> 17; + block[8*6] = (a1 - b1) >> 17; + block[8*7] = (a0 - b0) >> 17; +} + +void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, const int stride) +{ + uint64_t clampmask; + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + + for (i = 0; i < 8; i++) + idct_col (block + i); + + clampmask = zap (-1, 0xaa); /* 0x00ff00ff00ff00ff */ + do { + uint64_t shorts0, shorts1; + + shorts0 = ldq (block); + shorts0 = maxsw4 (shorts0, 0); + shorts0 = minsw4 (shorts0, clampmask); + stl (pkwb (shorts0), dest); + + shorts1 = ldq (block + 4); + shorts1 = maxsw4 (shorts1, 0); + shorts1 = minsw4 (shorts1, clampmask); + stl (pkwb (shorts1), dest + 4); + + stq (0, block); + stq (0, block + 4); + + dest += stride; + block += 8; + } while (--i); +} + +void mpeg2_idct_add_mvi (const int last, int16_t * block, + uint8_t * dest, const int stride) +{ + uint64_t clampmask; + uint64_t signmask; + int i; + + if (last != 129 || (block[0] & 7) == 4) { + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + for (i = 0; i < 8; i++) + idct_col (block + i); + clampmask = zap (-1, 0xaa); /* 0x00ff00ff00ff00ff */ + signmask = zap (-1, 0x33); + signmask ^= signmask >> 1; /* 0x8000800080008000 */ + + do { + uint64_t shorts0, pix0, signs0; + uint64_t shorts1, pix1, signs1; + + shorts0 = ldq (block); + shorts1 = ldq (block + 4); + + pix0 = unpkbw (ldl (dest)); + /* signed subword add (MMX paddw). */ + signs0 = shorts0 & signmask; + shorts0 &= ~signmask; + shorts0 += pix0; + shorts0 ^= signs0; + /* clamp. */ + shorts0 = maxsw4 (shorts0, 0); + shorts0 = minsw4 (shorts0, clampmask); + + /* next 4. */ + pix1 = unpkbw (ldl (dest + 4)); + signs1 = shorts1 & signmask; + shorts1 &= ~signmask; + shorts1 += pix1; + shorts1 ^= signs1; + shorts1 = maxsw4 (shorts1, 0); + shorts1 = minsw4 (shorts1, clampmask); + + stl (pkwb (shorts0), dest); + stl (pkwb (shorts1), dest + 4); + stq (0, block); + stq (0, block + 4); + + dest += stride; + block += 8; + } while (--i); + } else { + int DC; + uint64_t p0, p1, p2, p3, p4, p5, p6, p7; + uint64_t DCs; + + DC = (block[0] + 4) >> 3; + block[0] = block[63] = 0; + + p0 = ldq (dest + 0 * stride); + p1 = ldq (dest + 1 * stride); + p2 = ldq (dest + 2 * stride); + p3 = ldq (dest + 3 * stride); + p4 = ldq (dest + 4 * stride); + p5 = ldq (dest + 5 * stride); + p6 = ldq (dest + 6 * stride); + p7 = ldq (dest + 7 * stride); + + if (DC > 0) { + DCs = BYTE_VEC (likely (DC <= 255) ? DC : 255); + p0 += minub8 (DCs, ~p0); + p1 += minub8 (DCs, ~p1); + p2 += minub8 (DCs, ~p2); + p3 += minub8 (DCs, ~p3); + p4 += minub8 (DCs, ~p4); + p5 += minub8 (DCs, ~p5); + p6 += minub8 (DCs, ~p6); + p7 += minub8 (DCs, ~p7); + } else { + DCs = BYTE_VEC (likely (-DC <= 255) ? -DC : 255); + p0 -= minub8 (DCs, p0); + p1 -= minub8 (DCs, p1); + p2 -= minub8 (DCs, p2); + p3 -= minub8 (DCs, p3); + p4 -= minub8 (DCs, p4); + p5 -= minub8 (DCs, p5); + p6 -= minub8 (DCs, p6); + p7 -= minub8 (DCs, p7); + } + + stq (p0, dest + 0 * stride); + stq (p1, dest + 1 * stride); + stq (p2, dest + 2 * stride); + stq (p3, dest + 3 * stride); + stq (p4, dest + 4 * stride); + stq (p5, dest + 5 * stride); + stq (p6, dest + 6 * stride); + stq (p7, dest + 7 * stride); + } +} + +void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, const int stride) +{ + int i; + + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + for (i = 0; i < 8; i++) + idct_col (block + i); + do { + dest[0] = CLIP (block[0]); + dest[1] = CLIP (block[1]); + dest[2] = CLIP (block[2]); + dest[3] = CLIP (block[3]); + dest[4] = CLIP (block[4]); + dest[5] = CLIP (block[5]); + dest[6] = CLIP (block[6]); + dest[7] = CLIP (block[7]); + + stq(0, block); + stq(0, block + 4); + + dest += stride; + block += 8; + } while (--i); +} + +void mpeg2_idct_add_alpha (const int last, int16_t * block, + uint8_t * dest, const int stride) +{ + int i; + + if (last != 129 || (block[0] & 7) == 4) { + for (i = 0; i < 8; i++) + idct_row (block + 8 * i); + for (i = 0; i < 8; i++) + idct_col (block + i); + do { + dest[0] = CLIP (block[0] + dest[0]); + dest[1] = CLIP (block[1] + dest[1]); + dest[2] = CLIP (block[2] + dest[2]); + dest[3] = CLIP (block[3] + dest[3]); + dest[4] = CLIP (block[4] + dest[4]); + dest[5] = CLIP (block[5] + dest[5]); + dest[6] = CLIP (block[6] + dest[6]); + dest[7] = CLIP (block[7] + dest[7]); + + stq(0, block); + stq(0, block + 4); + + dest += stride; + block += 8; + } while (--i); + } else { + int DC; + + DC = (block[0] + 4) >> 3; + block[0] = block[63] = 0; + i = 8; + do { + dest[0] = CLIP (DC + dest[0]); + dest[1] = CLIP (DC + dest[1]); + dest[2] = CLIP (DC + dest[2]); + dest[3] = CLIP (DC + dest[3]); + dest[4] = CLIP (DC + dest[4]); + dest[5] = CLIP (DC + dest[5]); + dest[6] = CLIP (DC + dest[6]); + dest[7] = CLIP (DC + dest[7]); + dest += stride; + } while (--i); + } +} + +void mpeg2_idct_alpha_init(int no_mvi) +{ + extern uint8_t mpeg2_scan_norm[64]; + extern uint8_t mpeg2_scan_alt[64]; + int i, j; + + if (no_mvi) + for (i = -384; i < 640; i++) + clip_lut[i + 384] = (i < 0) ? 0 : ((i > 255) ? 255 : i); + for (i = 0; i < 64; i++) { + j = mpeg2_scan_norm[i]; + mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); + } +} + +#endif /* ARCH_ALPHA */ diff --git a/vldp2/libmpeg2/idct_altivec.c b/vldp2/libmpeg2/idct_altivec.c new file mode 100644 index 000000000..ff9eea7dd --- /dev/null +++ b/vldp2/libmpeg2/idct_altivec.c @@ -0,0 +1,705 @@ +/* + * idct_altivec.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ALTIVEC__ + +#include "config.h" + +#ifdef ARCH_PPC + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" + +static const int16_t constants[5][8] ATTR_ALIGN(16) = { + {23170, 13573, 6518, 21895, -23170, -21895, 32, 31}, + {16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725}, + {22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521}, + {21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692}, + {19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722} +}; + +/* + * The asm code is generated with: + * + * gcc-2.95 -fvec -D__ALTIVEC__ -O9 -fomit-frame-pointer -mregnames -S + * idct_altivec.c + * + * awk '{args=""; len=split ($2, arg, ","); + * for (i=1; i<=len; i++) { a=arg[i]; if (i> 3) | ((j & 7) << 3); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = (j >> 3) | ((j & 7) << 3); + } +} + +#endif /* ARCH_PPC */ + +#else /* __ALTIVEC__ */ + +#define vector_s16_t vector signed short +#define vector_u16_t vector unsigned short +#define vector_s8_t vector signed char +#define vector_u8_t vector unsigned char +#define vector_s32_t vector signed int +#define vector_u32_t vector unsigned int + +#define IDCT_HALF \ + /* 1st stage */ \ + t1 = vec_mradds (a1, vx7, vx1 ); \ + t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ + t7 = vec_mradds (a2, vx5, vx3); \ + t3 = vec_mradds (ma2, vx3, vx5); \ + \ + /* 2nd stage */ \ + t5 = vec_adds (vx0, vx4); \ + t0 = vec_subs (vx0, vx4); \ + t2 = vec_mradds (a0, vx6, vx2); \ + t4 = vec_mradds (a0, vx2, vec_subs (zero, vx6)); \ + t6 = vec_adds (t8, t3); \ + t3 = vec_subs (t8, t3); \ + t8 = vec_subs (t1, t7); \ + t1 = vec_adds (t1, t7); \ + \ + /* 3rd stage */ \ + t7 = vec_adds (t5, t2); \ + t2 = vec_subs (t5, t2); \ + t5 = vec_adds (t0, t4); \ + t0 = vec_subs (t0, t4); \ + t4 = vec_subs (t8, t3); \ + t3 = vec_adds (t8, t3); \ + \ + /* 4th stage */ \ + vy0 = vec_adds (t7, t1); \ + vy7 = vec_subs (t7, t1); \ + vy1 = vec_mradds (c4, t3, t5); \ + vy6 = vec_mradds (mc4, t3, t5); \ + vy2 = vec_mradds (c4, t4, t0); \ + vy5 = vec_mradds (mc4, t4, t0); \ + vy3 = vec_adds (t2, t6); \ + vy4 = vec_subs (t2, t6); + +#define IDCT \ + vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ + vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ + vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias; \ + vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8; \ + vector_u16_t shift; \ + \ + c4 = vec_splat (constants[0], 0); \ + a0 = vec_splat (constants[0], 1); \ + a1 = vec_splat (constants[0], 2); \ + a2 = vec_splat (constants[0], 3); \ + mc4 = vec_splat (constants[0], 4); \ + ma2 = vec_splat (constants[0], 5); \ + bias = (vector_s16_t)vec_splat ((vector_s32_t)constants[0], 3); \ + \ + zero = vec_splat_s16 (0); \ + shift = vec_splat_u16 (4); \ + \ + vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero); \ + vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero); \ + vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero); \ + vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero); \ + vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero); \ + vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero); \ + vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero); \ + vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero); \ + \ + IDCT_HALF \ + \ + vx0 = vec_mergeh (vy0, vy4); \ + vx1 = vec_mergel (vy0, vy4); \ + vx2 = vec_mergeh (vy1, vy5); \ + vx3 = vec_mergel (vy1, vy5); \ + vx4 = vec_mergeh (vy2, vy6); \ + vx5 = vec_mergel (vy2, vy6); \ + vx6 = vec_mergeh (vy3, vy7); \ + vx7 = vec_mergel (vy3, vy7); \ + \ + vy0 = vec_mergeh (vx0, vx4); \ + vy1 = vec_mergel (vx0, vx4); \ + vy2 = vec_mergeh (vx1, vx5); \ + vy3 = vec_mergel (vx1, vx5); \ + vy4 = vec_mergeh (vx2, vx6); \ + vy5 = vec_mergel (vx2, vx6); \ + vy6 = vec_mergeh (vx3, vx7); \ + vy7 = vec_mergel (vx3, vx7); \ + \ + vx0 = vec_adds (vec_mergeh (vy0, vy4), bias); \ + vx1 = vec_mergel (vy0, vy4); \ + vx2 = vec_mergeh (vy1, vy5); \ + vx3 = vec_mergel (vy1, vy5); \ + vx4 = vec_mergeh (vy2, vy6); \ + vx5 = vec_mergel (vy2, vy6); \ + vx6 = vec_mergeh (vy3, vy7); \ + vx7 = vec_mergel (vy3, vy7); \ + \ + IDCT_HALF \ + \ + shift = vec_splat_u16 (6); \ + vx0 = vec_sra (vy0, shift); \ + vx1 = vec_sra (vy1, shift); \ + vx2 = vec_sra (vy2, shift); \ + vx3 = vec_sra (vy3, shift); \ + vx4 = vec_sra (vy4, shift); \ + vx5 = vec_sra (vy5, shift); \ + vx6 = vec_sra (vy6, shift); \ + vx7 = vec_sra (vy7, shift); + +static const vector_s16_t constants[5] = { + (vector_s16_t)(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), + (vector_s16_t)(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), + (vector_s16_t)(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), + (vector_s16_t)(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), + (vector_s16_t)(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) +}; + +void mpeg2_idct_copy_altivec (vector_s16_t * const block, unsigned char * dest, + const int stride) +{ + vector_u8_t tmp; + + IDCT + +#define COPY(dest,src) \ + tmp = vec_packsu (src, src); \ + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + + COPY (dest, vx0) dest += stride; + COPY (dest, vx1) dest += stride; + COPY (dest, vx2) dest += stride; + COPY (dest, vx3) dest += stride; + COPY (dest, vx4) dest += stride; + COPY (dest, vx5) dest += stride; + COPY (dest, vx6) dest += stride; + COPY (dest, vx7) + + memset (block, 0, 64 * sizeof (signed short)); +} + +void mpeg2_idct_add_altivec (const int last, vector_s16_t * const block, + unsigned char * dest, const int stride) +{ + vector_u8_t tmp; + vector_s16_t tmp2, tmp3; + vector_u8_t perm0; + vector_u8_t perm1; + vector_u8_t p0, p1, p; + + IDCT + + p0 = vec_lvsl (0, dest); + p1 = vec_lvsl (stride, dest); + p = vec_splat_u8 (-1); + perm0 = vec_mergeh (p, p0); + perm1 = vec_mergeh (p, p1); + +#define ADD(dest,src,perm) \ + /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ + tmp = vec_ld (0, dest); \ + tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm); \ + tmp3 = vec_adds (tmp2, src); \ + tmp = vec_packsu (tmp3, tmp3); \ + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + + ADD (dest, vx0, perm0) dest += stride; + ADD (dest, vx1, perm1) dest += stride; + ADD (dest, vx2, perm0) dest += stride; + ADD (dest, vx3, perm1) dest += stride; + ADD (dest, vx4, perm0) dest += stride; + ADD (dest, vx5, perm1) dest += stride; + ADD (dest, vx6, perm0) dest += stride; + ADD (dest, vx7, perm1) + + memset (block, 0, 64 * sizeof (signed short)); +} + +#endif /* __ALTIVEC__ */ diff --git a/vldp2/libmpeg2/idct_mlib.c b/vldp2/libmpeg2/idct_mlib.c new file mode 100644 index 000000000..eae2a2f1b --- /dev/null +++ b/vldp2/libmpeg2/idct_mlib.c @@ -0,0 +1,60 @@ +/* + * idct_mlib.c + * Copyright (C) 1999-2002 Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBMPEG2_MLIB + +#include +#include +#include +#include +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" + +void mpeg2_idct_add_mlib (const int last, int16_t * const block, + uint8_t * const dest, const int stride) +{ + mlib_VideoIDCT_IEEE_S16_S16 (block, block); + mlib_VideoAddBlock_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +void mpeg2_idct_copy_mlib_non_ieee (int16_t * const block, + uint8_t * const dest, const int stride) +{ + mlib_VideoIDCT8x8_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +void mpeg2_idct_add_mlib_non_ieee (const int last, int16_t * const block, + uint8_t * const dest, const int stride) +{ + mlib_VideoIDCT8x8_S16_S16 (block, block); + mlib_VideoAddBlock_U8_S16 (dest, block, stride); + memset (block, 0, 64 * sizeof (uint16_t)); +} + +#endif diff --git a/vldp2/libmpeg2/idct_mmx.c b/vldp2/libmpeg2/idct_mmx.c new file mode 100644 index 000000000..4915b9375 --- /dev/null +++ b/vldp2/libmpeg2/idct_mmx.c @@ -0,0 +1,814 @@ +/* + * idct_mmx.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef ARCH_X86 + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" +#include "mmx.h" + +#define ROW_SHIFT 11 +#define COL_SHIFT 6 + +#define round(bias) ((int)(((bias)+0.5) * (1<> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; +} +#endif + + +/* MMXEXT row IDCT */ + +#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ + c4, c6, c4, c6, \ + c1, c3, -c1, -c5, \ + c5, c7, c3, -c7, \ + c4, -c6, c4, -c6, \ + -c4, c2, c4, -c2, \ + c5, -c1, c3, -c1, \ + c7, c3, c7, -c5 } + +static inline void mmxext_row_head (int16_t * const row, const int offset, + const int16_t * const table) +{ + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ + + movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ + + movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ + + pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ +} + +static inline void mmxext_row (const int16_t * const table, + const int32_t * const rounder) +{ + movq_m2r (*(table+8), mm1); /* mm1 = -C5 -C1 C3 C1 */ + pmaddwd_r2r (mm2, mm4); /* mm4 = C4*x0+C6*x2 C4*x4+C6*x6 */ + + pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x4-C6*x6 C4*x0-C6*x2 */ + pshufw_r2r (mm6, mm6, 0x4e); /* mm6 = x3 x1 x7 x5 */ + + movq_m2r (*(table+12), mm7); /* mm7 = -C7 C3 C7 C5 */ + pmaddwd_r2r (mm5, mm1); /* mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 */ + + paddd_m2r (*rounder, mm3); /* mm3 += rounder */ + pmaddwd_r2r (mm6, mm7); /* mm7 = C3*x1-C7*x3 C5*x5+C7*x7 */ + + pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 */ + paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ + + pmaddwd_m2r (*(table+24), mm5); /* mm5 = C3*x5-C1*x7 C5*x1-C1*x3 */ + movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ + + pmaddwd_m2r (*(table+28), mm6); /* mm6 = C7*x1-C5*x3 C7*x5+C3*x7 */ + paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ + + paddd_m2r (*rounder, mm0); /* mm0 += rounder */ + psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ + + psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ + paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ + + paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ + psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ + + paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ + movq_r2r (mm0, mm4); /* mm4 = a3 a2 + rounder */ + + paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ + psubd_r2r (mm5, mm4); /* mm4 = a3-b3 a2-b2 + rounder */ +} + +static inline void mmxext_row_tail (int16_t * const row, const int store) +{ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ + + psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ + + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + + packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ + + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ + + /* slot */ + + movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ +} + +static inline void mmxext_row_mid (int16_t * const row, const int store, + const int offset, + const int16_t * const table) +{ + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ + + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ + + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ + + packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ + + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ + + movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ + movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ + + pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ + + movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ + pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ +} + + +/* MMX row IDCT */ + +#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ + c4, c6, -c4, -c2, \ + c1, c3, c3, -c7, \ + c5, c7, -c1, -c5, \ + c4, -c6, c4, -c2, \ + -c4, c2, c4, -c6, \ + c5, -c1, c7, -c5, \ + c7, c3, c3, -c1 } + +static inline void mmx_row_head (int16_t * const row, const int offset, + const int16_t * const table) +{ + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ + + movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ + + punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ + + movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ + + movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ + punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ +} + +static inline void mmx_row (const int16_t * const table, + const int32_t * const rounder) +{ + pmaddwd_r2r (mm2, mm4); /* mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 */ + punpckldq_r2r (mm5, mm5); /* mm5 = x3 x1 x3 x1 */ + + pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x0-C2*x2 C4*x0-C6*x2 */ + punpckhdq_r2r (mm6, mm6); /* mm6 = x7 x5 x7 x5 */ + + movq_m2r (*(table+12), mm7); /* mm7 = -C5 -C1 C7 C5 */ + pmaddwd_r2r (mm5, mm1); /* mm1 = C3*x1-C7*x3 C1*x1+C3*x3 */ + + paddd_m2r (*rounder, mm3); /* mm3 += rounder */ + pmaddwd_r2r (mm6, mm7); /* mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 */ + + pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 */ + paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ + + pmaddwd_m2r (*(table+24), mm5); /* mm5 = C7*x1-C5*x3 C5*x1-C1*x3 */ + movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ + + pmaddwd_m2r (*(table+28), mm6); /* mm6 = C3*x5-C1*x7 C7*x5+C3*x7 */ + paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ + + paddd_m2r (*rounder, mm0); /* mm0 += rounder */ + psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ + + psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ + paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ + + paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ + psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ + + paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ + movq_r2r (mm0, mm7); /* mm7 = a3 a2 + rounder */ + + paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ + psubd_r2r (mm5, mm7); /* mm7 = a3-b3 a2-b2 + rounder */ +} + +static inline void mmx_row_tail (int16_t * const row, const int store) +{ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ + + psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ + + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + + packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ + + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + movq_r2r (mm7, mm4); /* mm4 = y6 y7 y4 y5 */ + + pslld_i2r (16, mm7); /* mm7 = y7 0 y5 0 */ + + psrld_i2r (16, mm4); /* mm4 = 0 y6 0 y4 */ + + por_r2r (mm4, mm7); /* mm7 = y7 y6 y5 y4 */ + + /* slot */ + + movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ +} + +static inline void mmx_row_mid (int16_t * const row, const int store, + const int offset, const int16_t * const table) +{ + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ + + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ + + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ + + packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ + + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + movq_r2r (mm7, mm1); /* mm1 = y6 y7 y4 y5 */ + + punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ + psrld_i2r (16, mm7); /* mm7 = 0 y6 0 y4 */ + + movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ + pslld_i2r (16, mm1); /* mm1 = y7 0 y5 0 */ + + movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ + por_r2r (mm1, mm7); /* mm7 = y7 y6 y5 y4 */ + + movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ + punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ + + movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ +} + + +#if 0 +/* C column IDCT - its just here to document the MMXEXT and MMX versions */ +static inline void idct_col (int16_t * col, int offset) +{ +/* multiplication - as implemented on mmx */ +#define F(c,x) (((c) * (x)) >> 16) + +/* saturation - it helps us handle torture test cases */ +#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) + + int16_t x0, x1, x2, x3, x4, x5, x6, x7; + int16_t y0, y1, y2, y3, y4, y5, y6, y7; + int16_t a0, a1, a2, a3, b0, b1, b2, b3; + int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; + + col += offset; + + x0 = col[0*8]; + x1 = col[1*8]; + x2 = col[2*8]; + x3 = col[3*8]; + x4 = col[4*8]; + x5 = col[5*8]; + x6 = col[6*8]; + x7 = col[7*8]; + + u04 = S (x0 + x4); + v04 = S (x0 - x4); + u26 = S (F (T2, x6) + x2); + v26 = S (F (T2, x2) - x6); + + a0 = S (u04 + u26); + a1 = S (v04 + v26); + a2 = S (v04 - v26); + a3 = S (u04 - u26); + + u17 = S (F (T1, x7) + x1); + v17 = S (F (T1, x1) - x7); + u35 = S (F (T3, x5) + x3); + v35 = S (F (T3, x3) - x5); + + b0 = S (u17 + u35); + b3 = S (v17 - v35); + u12 = S (u17 - u35); + v12 = S (v17 + v35); + u12 = S (2 * F (C4, u12)); + v12 = S (2 * F (C4, v12)); + b1 = S (u12 + v12); + b2 = S (u12 - v12); + + y0 = S (a0 + b0) >> COL_SHIFT; + y1 = S (a1 + b1) >> COL_SHIFT; + y2 = S (a2 + b2) >> COL_SHIFT; + y3 = S (a3 + b3) >> COL_SHIFT; + + y4 = S (a3 - b3) >> COL_SHIFT; + y5 = S (a2 - b2) >> COL_SHIFT; + y6 = S (a1 - b1) >> COL_SHIFT; + y7 = S (a0 - b0) >> COL_SHIFT; + + col[0*8] = y0; + col[1*8] = y1; + col[2*8] = y2; + col[3*8] = y3; + col[4*8] = y4; + col[5*8] = y5; + col[6*8] = y6; + col[7*8] = y7; +} +#endif + + +/* MMX column IDCT */ +static inline void idct_col (int16_t * const col, const int offset) +{ +#define T1 13036 +#define T2 27146 +#define T3 43790 +#define C4 23170 + + static const short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; + static const short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; + static const short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; + static const short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; + + /* column code adapted from peter gubanov */ + /* http://www.elecard.com/peter/idct.shtml */ + + movq_m2r (*_T1, mm0); /* mm0 = T1 */ + + movq_m2r (*(col+offset+1*8), mm1); /* mm1 = x1 */ + movq_r2r (mm0, mm2); /* mm2 = T1 */ + + movq_m2r (*(col+offset+7*8), mm4); /* mm4 = x7 */ + pmulhw_r2r (mm1, mm0); /* mm0 = T1*x1 */ + + movq_m2r (*_T3, mm5); /* mm5 = T3 */ + pmulhw_r2r (mm4, mm2); /* mm2 = T1*x7 */ + + movq_m2r (*(col+offset+5*8), mm6); /* mm6 = x5 */ + movq_r2r (mm5, mm7); /* mm7 = T3-1 */ + + movq_m2r (*(col+offset+3*8), mm3); /* mm3 = x3 */ + psubsw_r2r (mm4, mm0); /* mm0 = v17 */ + + movq_m2r (*_T2, mm4); /* mm4 = T2 */ + pmulhw_r2r (mm3, mm5); /* mm5 = (T3-1)*x3 */ + + paddsw_r2r (mm2, mm1); /* mm1 = u17 */ + pmulhw_r2r (mm6, mm7); /* mm7 = (T3-1)*x5 */ + + /* slot */ + + movq_r2r (mm4, mm2); /* mm2 = T2 */ + paddsw_r2r (mm3, mm5); /* mm5 = T3*x3 */ + + pmulhw_m2r (*(col+offset+2*8), mm4);/* mm4 = T2*x2 */ + paddsw_r2r (mm6, mm7); /* mm7 = T3*x5 */ + + psubsw_r2r (mm6, mm5); /* mm5 = v35 */ + paddsw_r2r (mm3, mm7); /* mm7 = u35 */ + + movq_m2r (*(col+offset+6*8), mm3); /* mm3 = x6 */ + movq_r2r (mm0, mm6); /* mm6 = v17 */ + + pmulhw_r2r (mm3, mm2); /* mm2 = T2*x6 */ + psubsw_r2r (mm5, mm0); /* mm0 = b3 */ + + psubsw_r2r (mm3, mm4); /* mm4 = v26 */ + paddsw_r2r (mm6, mm5); /* mm5 = v12 */ + + movq_r2m (mm0, *(col+offset+3*8)); /* save b3 in scratch0 */ + movq_r2r (mm1, mm6); /* mm6 = u17 */ + + paddsw_m2r (*(col+offset+2*8), mm2);/* mm2 = u26 */ + paddsw_r2r (mm7, mm6); /* mm6 = b0 */ + + psubsw_r2r (mm7, mm1); /* mm1 = u12 */ + movq_r2r (mm1, mm7); /* mm7 = u12 */ + + movq_m2r (*(col+offset+0*8), mm3); /* mm3 = x0 */ + paddsw_r2r (mm5, mm1); /* mm1 = u12+v12 */ + + movq_m2r (*_C4, mm0); /* mm0 = C4/2 */ + psubsw_r2r (mm5, mm7); /* mm7 = u12-v12 */ + + movq_r2m (mm6, *(col+offset+5*8)); /* save b0 in scratch1 */ + pmulhw_r2r (mm0, mm1); /* mm1 = b1/2 */ + + movq_r2r (mm4, mm6); /* mm6 = v26 */ + pmulhw_r2r (mm0, mm7); /* mm7 = b2/2 */ + + movq_m2r (*(col+offset+4*8), mm5); /* mm5 = x4 */ + movq_r2r (mm3, mm0); /* mm0 = x0 */ + + psubsw_r2r (mm5, mm3); /* mm3 = v04 */ + paddsw_r2r (mm5, mm0); /* mm0 = u04 */ + + paddsw_r2r (mm3, mm4); /* mm4 = a1 */ + movq_r2r (mm0, mm5); /* mm5 = u04 */ + + psubsw_r2r (mm6, mm3); /* mm3 = a2 */ + paddsw_r2r (mm2, mm5); /* mm5 = a0 */ + + paddsw_r2r (mm1, mm1); /* mm1 = b1 */ + psubsw_r2r (mm2, mm0); /* mm0 = a3 */ + + paddsw_r2r (mm7, mm7); /* mm7 = b2 */ + movq_r2r (mm3, mm2); /* mm2 = a2 */ + + movq_r2r (mm4, mm6); /* mm6 = a1 */ + paddsw_r2r (mm7, mm3); /* mm3 = a2+b2 */ + + psraw_i2r (COL_SHIFT, mm3); /* mm3 = y2 */ + paddsw_r2r (mm1, mm4); /* mm4 = a1+b1 */ + + psraw_i2r (COL_SHIFT, mm4); /* mm4 = y1 */ + psubsw_r2r (mm1, mm6); /* mm6 = a1-b1 */ + + movq_m2r (*(col+offset+5*8), mm1); /* mm1 = b0 */ + psubsw_r2r (mm7, mm2); /* mm2 = a2-b2 */ + + psraw_i2r (COL_SHIFT, mm6); /* mm6 = y6 */ + movq_r2r (mm5, mm7); /* mm7 = a0 */ + + movq_r2m (mm4, *(col+offset+1*8)); /* save y1 */ + psraw_i2r (COL_SHIFT, mm2); /* mm2 = y5 */ + + movq_r2m (mm3, *(col+offset+2*8)); /* save y2 */ + paddsw_r2r (mm1, mm5); /* mm5 = a0+b0 */ + + movq_m2r (*(col+offset+3*8), mm4); /* mm4 = b3 */ + psubsw_r2r (mm1, mm7); /* mm7 = a0-b0 */ + + psraw_i2r (COL_SHIFT, mm5); /* mm5 = y0 */ + movq_r2r (mm0, mm3); /* mm3 = a3 */ + + movq_r2m (mm2, *(col+offset+5*8)); /* save y5 */ + psubsw_r2r (mm4, mm3); /* mm3 = a3-b3 */ + + psraw_i2r (COL_SHIFT, mm7); /* mm7 = y7 */ + paddsw_r2r (mm0, mm4); /* mm4 = a3+b3 */ + + movq_r2m (mm5, *(col+offset+0*8)); /* save y0 */ + psraw_i2r (COL_SHIFT, mm3); /* mm3 = y4 */ + + movq_r2m (mm6, *(col+offset+6*8)); /* save y6 */ + psraw_i2r (COL_SHIFT, mm4); /* mm4 = y3 */ + + movq_r2m (mm7, *(col+offset+7*8)); /* save y7 */ + + movq_r2m (mm3, *(col+offset+4*8)); /* save y4 */ + + movq_r2m (mm4, *(col+offset+3*8)); /* save y3 */ +} + + +static const int32_t rounder0[] ATTR_ALIGN(8) = + rounder ((1 << (COL_SHIFT - 1)) - 0.5); +static const int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); +static const int32_t rounder1[] ATTR_ALIGN(8) = + rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ +static const int32_t rounder7[] ATTR_ALIGN(8) = + rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ +static const int32_t rounder2[] ATTR_ALIGN(8) = + rounder (0.60355339059); /* C2 * (C6+C2)/2 */ +static const int32_t rounder6[] ATTR_ALIGN(8) = + rounder (-0.25); /* C2 * (C6-C2)/2 */ +static const int32_t rounder3[] ATTR_ALIGN(8) = + rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ +static const int32_t rounder5[] ATTR_ALIGN(8) = + rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ + + +#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ +static inline void idct (int16_t * const block) \ +{ \ + static const int16_t table04[] ATTR_ALIGN(16) = \ + table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ + static const int16_t table17[] ATTR_ALIGN(16) = \ + table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ + static const int16_t table26[] ATTR_ALIGN(16) = \ + table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ + static const int16_t table35[] ATTR_ALIGN(16) = \ + table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ + \ + idct_row_head (block, 0*8, table04); \ + idct_row (table04, rounder0); \ + idct_row_mid (block, 0*8, 4*8, table04); \ + idct_row (table04, rounder4); \ + idct_row_mid (block, 4*8, 1*8, table17); \ + idct_row (table17, rounder1); \ + idct_row_mid (block, 1*8, 7*8, table17); \ + idct_row (table17, rounder7); \ + idct_row_mid (block, 7*8, 2*8, table26); \ + idct_row (table26, rounder2); \ + idct_row_mid (block, 2*8, 6*8, table26); \ + idct_row (table26, rounder6); \ + idct_row_mid (block, 6*8, 3*8, table35); \ + idct_row (table35, rounder3); \ + idct_row_mid (block, 3*8, 5*8, table35); \ + idct_row (table35, rounder5); \ + idct_row_tail (block, 5*8); \ + \ + idct_col (block, 0); \ + idct_col (block, 4); \ +} + + +#define COPY_MMX(offset,r0,r1,r2) \ +do { \ + movq_m2r (*(block+offset), r0); \ + dest += stride; \ + movq_m2r (*(block+offset+4), r1); \ + movq_r2m (r2, *dest); \ + packuswb_r2r (r1, r0); \ +} while (0) + +static inline void block_copy (int16_t * const block, uint8_t * dest, + const int stride) +{ + movq_m2r (*(block+0*8), mm0); + movq_m2r (*(block+0*8+4), mm1); + movq_m2r (*(block+1*8), mm2); + packuswb_r2r (mm1, mm0); + movq_m2r (*(block+1*8+4), mm3); + movq_r2m (mm0, *dest); + packuswb_r2r (mm3, mm2); + COPY_MMX (2*8, mm0, mm1, mm2); + COPY_MMX (3*8, mm2, mm3, mm0); + COPY_MMX (4*8, mm0, mm1, mm2); + COPY_MMX (5*8, mm2, mm3, mm0); + COPY_MMX (6*8, mm0, mm1, mm2); + COPY_MMX (7*8, mm2, mm3, mm0); + movq_r2m (mm2, *(dest+stride)); +} + + +#define ADD_MMX(offset,r1,r2,r3,r4) \ +do { \ + movq_m2r (*(dest+2*stride), r1); \ + packuswb_r2r (r4, r3); \ + movq_r2r (r1, r2); \ + dest += stride; \ + movq_r2m (r3, *dest); \ + punpcklbw_r2r (mm0, r1); \ + paddsw_m2r (*(block+offset), r1); \ + punpckhbw_r2r (mm0, r2); \ + paddsw_m2r (*(block+offset+4), r2); \ +} while (0) + +static inline void block_add (int16_t * const block, uint8_t * dest, + const int stride) +{ + movq_m2r (*dest, mm1); + pxor_r2r (mm0, mm0); + movq_m2r (*(dest+stride), mm3); + movq_r2r (mm1, mm2); + punpcklbw_r2r (mm0, mm1); + movq_r2r (mm3, mm4); + paddsw_m2r (*(block+0*8), mm1); + punpckhbw_r2r (mm0, mm2); + paddsw_m2r (*(block+0*8+4), mm2); + punpcklbw_r2r (mm0, mm3); + paddsw_m2r (*(block+1*8), mm3); + packuswb_r2r (mm2, mm1); + punpckhbw_r2r (mm0, mm4); + movq_r2m (mm1, *dest); + paddsw_m2r (*(block+1*8+4), mm4); + ADD_MMX (2*8, mm1, mm2, mm3, mm4); + ADD_MMX (3*8, mm3, mm4, mm1, mm2); + ADD_MMX (4*8, mm1, mm2, mm3, mm4); + ADD_MMX (5*8, mm3, mm4, mm1, mm2); + ADD_MMX (6*8, mm1, mm2, mm3, mm4); + ADD_MMX (7*8, mm3, mm4, mm1, mm2); + packuswb_r2r (mm4, mm3); + movq_r2m (mm3, *(dest+stride)); +} + + +static inline void block_zero (int16_t * const block) +{ + pxor_r2r (mm0, mm0); + movq_r2m (mm0, *(block+0*4)); + movq_r2m (mm0, *(block+1*4)); + movq_r2m (mm0, *(block+2*4)); + movq_r2m (mm0, *(block+3*4)); + movq_r2m (mm0, *(block+4*4)); + movq_r2m (mm0, *(block+5*4)); + movq_r2m (mm0, *(block+6*4)); + movq_r2m (mm0, *(block+7*4)); + movq_r2m (mm0, *(block+8*4)); + movq_r2m (mm0, *(block+9*4)); + movq_r2m (mm0, *(block+10*4)); + movq_r2m (mm0, *(block+11*4)); + movq_r2m (mm0, *(block+12*4)); + movq_r2m (mm0, *(block+13*4)); + movq_r2m (mm0, *(block+14*4)); + movq_r2m (mm0, *(block+15*4)); +} + + +#define CPU_MMXEXT 0 +#define CPU_MMX 1 + +#define dup4(reg) \ +do { \ + if (cpu != CPU_MMXEXT) { \ + punpcklwd_r2r (reg, reg); \ + punpckldq_r2r (reg, reg); \ + } else \ + pshufw_r2r (reg, reg, 0x00); \ +} while (0) + +static inline void block_add_DC (int16_t * const block, uint8_t * dest, + const int stride, const int cpu) +{ + movd_v2r ((block[0] + 4) >> 3, mm0); + pxor_r2r (mm1, mm1); + movq_m2r (*dest, mm2); + dup4 (mm0); + psubsw_r2r (mm0, mm1); + packuswb_r2r (mm0, mm0); + paddusb_r2r (mm0, mm2); + packuswb_r2r (mm1, mm1); + movq_m2r (*(dest + stride), mm3); + psubusb_r2r (mm1, mm2); + block[0] = 0; + paddusb_r2r (mm0, mm3); + movq_r2m (mm2, *dest); + psubusb_r2r (mm1, mm3); + movq_m2r (*(dest + 2*stride), mm2); + dest += stride; + movq_r2m (mm3, *dest); + paddusb_r2r (mm0, mm2); + movq_m2r (*(dest + 2*stride), mm3); + psubusb_r2r (mm1, mm2); + dest += stride; + paddusb_r2r (mm0, mm3); + movq_r2m (mm2, *dest); + psubusb_r2r (mm1, mm3); + movq_m2r (*(dest + 2*stride), mm2); + dest += stride; + movq_r2m (mm3, *dest); + paddusb_r2r (mm0, mm2); + movq_m2r (*(dest + 2*stride), mm3); + psubusb_r2r (mm1, mm2); + dest += stride; + paddusb_r2r (mm0, mm3); + movq_r2m (mm2, *dest); + psubusb_r2r (mm1, mm3); + movq_m2r (*(dest + 2*stride), mm2); + dest += stride; + movq_r2m (mm3, *dest); + paddusb_r2r (mm0, mm2); + movq_m2r (*(dest + 2*stride), mm3); + psubusb_r2r (mm1, mm2); + block[63] = 0; + paddusb_r2r (mm0, mm3); + movq_r2m (mm2, *(dest + stride)); + psubusb_r2r (mm1, mm3); + movq_r2m (mm3, *(dest + 2*stride)); +} + + +declare_idct (mmxext_idct, mmxext_table, + mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) + +void mpeg2_idct_copy_mmxext (int16_t * const block, uint8_t * const dest, + const int stride) +{ + mmxext_idct (block); + block_copy (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_add_mmxext (const int last, int16_t * const block, + uint8_t * const dest, const int stride) +{ + if (last != 129 || (block[0] & 7) == 4) { + mmxext_idct (block); + block_add (block, dest, stride); + block_zero (block); + } else + block_add_DC (block, dest, stride, CPU_MMXEXT); +} + + +declare_idct (mmx_idct, mmx_table, + mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) + +void mpeg2_idct_copy_mmx (int16_t * const block, uint8_t * const dest, + const int stride) +{ + mmx_idct (block); + block_copy (block, dest, stride); + block_zero (block); +} + +void mpeg2_idct_add_mmx (const int last, int16_t * const block, + uint8_t * const dest, const int stride) +{ + if (last != 129 || (block[0] & 7) == 4) { + mmx_idct (block); + block_add (block, dest, stride); + block_zero (block); + } else + block_add_DC (block, dest, stride, CPU_MMX); +} + + +void mpeg2_idct_mmx_init (void) +{ + extern uint8_t mpeg2_scan_norm[64]; + extern uint8_t mpeg2_scan_alt[64]; + int i, j; + + /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ + + for (i = 0; i < 64; i++) { + j = mpeg2_scan_norm[i]; + mpeg2_scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); + j = mpeg2_scan_alt[i]; + mpeg2_scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); + } +} + +#endif diff --git a/vldp2/libmpeg2/libmpeg2.pc.in b/vldp2/libmpeg2/libmpeg2.pc.in new file mode 100644 index 000000000..d54500b0e --- /dev/null +++ b/vldp2/libmpeg2/libmpeg2.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libmpeg2 +Description: A decoding library for MPEG-1 and MPEG-2 streams. +Version: @VERSION@ +Libs: -L${libdir} -lmpeg2 +Cflags: -I${includedir}/@PACKAGE@ diff --git a/vldp2/libmpeg2/motion_comp.c b/vldp2/libmpeg2/motion_comp.c new file mode 100644 index 000000000..25c001584 --- /dev/null +++ b/vldp2/libmpeg2/motion_comp.c @@ -0,0 +1,129 @@ +/* + * motion_comp.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" + +mpeg2_mc_t mpeg2_mc; + +void mpeg2_mc_init (uint32_t accel) +{ +#ifdef ARCH_X86 + if (accel & MPEG2_ACCEL_X86_MMXEXT) + mpeg2_mc = mpeg2_mc_mmxext; + else if (accel & MPEG2_ACCEL_X86_3DNOW) + mpeg2_mc = mpeg2_mc_3dnow; + else if (accel & MPEG2_ACCEL_X86_MMX) + mpeg2_mc = mpeg2_mc_mmx; + else +#endif +#ifdef ARCH_PPC + if (accel & MPEG2_ACCEL_PPC_ALTIVEC) + mpeg2_mc = mpeg2_mc_altivec; + else +#endif +#ifdef ARCH_ALPHA + if (accel & MPEG2_ACCEL_ALPHA) + mpeg2_mc = mpeg2_mc_alpha; + else +#endif +#ifdef LIBMPEG2_MLIB + if (accel & MPEG2_ACCEL_MLIB) + mpeg2_mc = mpeg2_mc_mlib; + else +#endif + mpeg2_mc = mpeg2_mc_c; +} + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +#define predict_o(i) (ref[i]) +#define predict_x(i) (avg2 (ref[i], ref[i+1])) +#define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) +#define predict_xy(i) (avg4 (ref[i], ref[i+1], \ + (ref+stride)[i], (ref+stride)[i+1])) + +#define put(predictor,i) dest[i] = predictor (i) +#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) + +/* mc function template */ + +#define MC_FUNC(op,xy) \ +static void MC_##op##_##xy##_16_c (uint8_t * dest, const uint8_t * ref, \ + const int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + op (predict_##xy, 8); \ + op (predict_##xy, 9); \ + op (predict_##xy, 10); \ + op (predict_##xy, 11); \ + op (predict_##xy, 12); \ + op (predict_##xy, 13); \ + op (predict_##xy, 14); \ + op (predict_##xy, 15); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} \ +static void MC_##op##_##xy##_8_c (uint8_t * dest, const uint8_t * ref, \ + const int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} + +/* definitions of the actual mc functions */ + +MC_FUNC (put,o) +MC_FUNC (avg,o) +MC_FUNC (put,x) +MC_FUNC (avg,x) +MC_FUNC (put,y) +MC_FUNC (avg,y) +MC_FUNC (put,xy) +MC_FUNC (avg,xy) + +MPEG2_MC_EXTERN (c) diff --git a/vldp2/libmpeg2/motion_comp_alpha.c b/vldp2/libmpeg2/motion_comp_alpha.c new file mode 100644 index 000000000..86deb33fc --- /dev/null +++ b/vldp2/libmpeg2/motion_comp_alpha.c @@ -0,0 +1,253 @@ +/* + * motion_comp_alpha.c + * Copyright (C) 2002 Falk Hueffner + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef ARCH_ALPHA + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "alpha_asm.h" + +static inline uint64_t avg2(uint64_t a, uint64_t b) +{ + return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1); +} + +// Load two unaligned quadwords from addr. This macro only works if +// addr is actually unaligned. +#define ULOAD16(ret_l, ret_r, addr) \ + do { \ + uint64_t _l = ldq_u(addr + 0); \ + uint64_t _m = ldq_u(addr + 8); \ + uint64_t _r = ldq_u(addr + 16); \ + ret_l = extql(_l, addr) | extqh(_m, addr); \ + ret_r = extql(_m, addr) | extqh(_r, addr); \ + } while (0) + +// Load two aligned quadwords from addr. +#define ALOAD16(ret_l, ret_r, addr) \ + do { \ + ret_l = ldq(addr); \ + ret_r = ldq(addr + 8); \ + } while (0) + +#define OP8(LOAD, LOAD16, STORE) \ + do { \ + STORE(LOAD(pixels), block); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP16(LOAD, LOAD16, STORE) \ + do { \ + uint64_t l, r; \ + LOAD16(l, r, pixels); \ + STORE(l, block); \ + STORE(r, block + 8); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP8_X2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t p0, p1; \ + \ + p0 = LOAD(pixels); \ + p1 = p0 >> 8 | ((uint64_t) pixels[8] << 56); \ + STORE(avg2(p0, p1), block); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP16_X2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t p0, p1; \ + \ + LOAD16(p0, p1, pixels); \ + STORE(avg2(p0, p0 >> 8 | p1 << 56), block); \ + STORE(avg2(p1, p1 >> 8 | (uint64_t) pixels[16] << 56), \ + block + 8); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP8_Y2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t p0, p1; \ + p0 = LOAD(pixels); \ + pixels += line_size; \ + p1 = LOAD(pixels); \ + do { \ + uint64_t av = avg2(p0, p1); \ + if (--h == 0) line_size = 0; \ + pixels += line_size; \ + p0 = p1; \ + p1 = LOAD(pixels); \ + STORE(av, block); \ + block += line_size; \ + } while (h); \ + } while (0) + +#define OP16_Y2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t p0l, p0r, p1l, p1r; \ + LOAD16(p0l, p0r, pixels); \ + pixels += line_size; \ + LOAD16(p1l, p1r, pixels); \ + do { \ + uint64_t avl, avr; \ + if (--h == 0) line_size = 0; \ + avl = avg2(p0l, p1l); \ + avr = avg2(p0r, p1r); \ + p0l = p1l; \ + p0r = p1r; \ + pixels += line_size; \ + LOAD16(p1l, p1r, pixels); \ + STORE(avl, block); \ + STORE(avr, block + 8); \ + block += line_size; \ + } while (h); \ + } while (0) + +#define OP8_XY2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t pl, ph; \ + uint64_t p1 = LOAD(pixels); \ + uint64_t p2 = p1 >> 8 | ((uint64_t) pixels[8] << 56); \ + \ + ph = ((p1 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p2 & ~BYTE_VEC(0x03)) >> 2); \ + pl = (p1 & BYTE_VEC(0x03)) \ + + (p2 & BYTE_VEC(0x03)); \ + \ + do { \ + uint64_t npl, nph; \ + \ + pixels += line_size; \ + p1 = LOAD(pixels); \ + p2 = (p1 >> 8) | ((uint64_t) pixels[8] << 56); \ + nph = ((p1 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p2 & ~BYTE_VEC(0x03)) >> 2); \ + npl = (p1 & BYTE_VEC(0x03)) \ + + (p2 & BYTE_VEC(0x03)); \ + \ + STORE(ph + nph \ + + (((pl + npl + BYTE_VEC(0x02)) >> 2) \ + & BYTE_VEC(0x03)), block); \ + \ + block += line_size; \ + pl = npl; \ + ph = nph; \ + } while (--h); \ + } while (0) + +#define OP16_XY2(LOAD, LOAD16, STORE) \ + do { \ + uint64_t p0, p1, p2, p3, pl_l, ph_l, pl_r, ph_r; \ + LOAD16(p0, p2, pixels); \ + p1 = p0 >> 8 | (p2 << 56); \ + p3 = p2 >> 8 | ((uint64_t) pixels[16] << 56); \ + \ + ph_l = ((p0 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p1 & ~BYTE_VEC(0x03)) >> 2); \ + pl_l = (p0 & BYTE_VEC(0x03)) \ + + (p1 & BYTE_VEC(0x03)); \ + ph_r = ((p2 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p3 & ~BYTE_VEC(0x03)) >> 2); \ + pl_r = (p2 & BYTE_VEC(0x03)) \ + + (p3 & BYTE_VEC(0x03)); \ + \ + do { \ + uint64_t npl_l, nph_l, npl_r, nph_r; \ + \ + pixels += line_size; \ + LOAD16(p0, p2, pixels); \ + p1 = p0 >> 8 | (p2 << 56); \ + p3 = p2 >> 8 | ((uint64_t) pixels[16] << 56); \ + nph_l = ((p0 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p1 & ~BYTE_VEC(0x03)) >> 2); \ + npl_l = (p0 & BYTE_VEC(0x03)) \ + + (p1 & BYTE_VEC(0x03)); \ + nph_r = ((p2 & ~BYTE_VEC(0x03)) >> 2) \ + + ((p3 & ~BYTE_VEC(0x03)) >> 2); \ + npl_r = (p2 & BYTE_VEC(0x03)) \ + + (p3 & BYTE_VEC(0x03)); \ + \ + STORE(ph_l + nph_l \ + + (((pl_l + npl_l + BYTE_VEC(0x02)) >> 2) \ + & BYTE_VEC(0x03)), block); \ + STORE(ph_r + nph_r \ + + (((pl_r + npl_r + BYTE_VEC(0x02)) >> 2) \ + & BYTE_VEC(0x03)), block + 8); \ + \ + block += line_size; \ + pl_l = npl_l; \ + ph_l = nph_l; \ + pl_r = npl_r; \ + ph_r = nph_r; \ + } while (--h); \ + } while (0) + +#define MAKE_OP(OPNAME, SIZE, SUFF, OPKIND, STORE) \ +static void MC_ ## OPNAME ## _ ## SUFF ## _ ## SIZE ## _alpha \ + (uint8_t *restrict block, const uint8_t *restrict pixels, \ + int line_size, int h) \ +{ \ + if ((uint64_t) pixels & 0x7) { \ + OPKIND(uldq, ULOAD16, STORE); \ + } else { \ + OPKIND(ldq, ALOAD16, STORE); \ + } \ +} + +#define PIXOP(OPNAME, STORE) \ + MAKE_OP(OPNAME, 8, o, OP8, STORE); \ + MAKE_OP(OPNAME, 8, x, OP8_X2, STORE); \ + MAKE_OP(OPNAME, 8, y, OP8_Y2, STORE); \ + MAKE_OP(OPNAME, 8, xy, OP8_XY2, STORE); \ + MAKE_OP(OPNAME, 16, o, OP16, STORE); \ + MAKE_OP(OPNAME, 16, x, OP16_X2, STORE); \ + MAKE_OP(OPNAME, 16, y, OP16_Y2, STORE); \ + MAKE_OP(OPNAME, 16, xy, OP16_XY2, STORE); + +#define STORE(l, b) stq(l, b) +PIXOP(put, STORE); + +#undef STORE +#define STORE(l, b) stq(avg2(l, ldq(b)), b); +PIXOP(avg, STORE); + +mpeg2_mc_t mpeg2_mc_alpha = { + { MC_put_o_16_alpha, MC_put_x_16_alpha, + MC_put_y_16_alpha, MC_put_xy_16_alpha, + MC_put_o_8_alpha, MC_put_x_8_alpha, + MC_put_y_8_alpha, MC_put_xy_8_alpha }, + { MC_avg_o_16_alpha, MC_avg_x_16_alpha, + MC_avg_y_16_alpha, MC_avg_xy_16_alpha, + MC_avg_o_8_alpha, MC_avg_x_8_alpha, + MC_avg_y_8_alpha, MC_avg_xy_8_alpha } +}; + +#endif diff --git a/vldp2/libmpeg2/motion_comp_altivec.c b/vldp2/libmpeg2/motion_comp_altivec.c new file mode 100644 index 000000000..998e2720f --- /dev/null +++ b/vldp2/libmpeg2/motion_comp_altivec.c @@ -0,0 +1,2019 @@ +/* + * motion_comp_altivec.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ALTIVEC__ + +#include "config.h" + +#ifdef ARCH_PPC + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" + +/* + * The asm code is generated with: + * + * gcc-2.95 -fvec -D__ALTIVEC__ -O9 -fomit-frame-pointer -mregnames -S + * motion_comp_altivec.c + * + * sed 's/.L/._L/g' motion_comp_altivec.s | + * awk '{args=""; len=split ($2, arg, ","); + * for (i=1; i<=len; i++) { a=arg[i]; if (i> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp = vec_perm (ref0, ref1, perm); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp = vec_perm (ref0, ref1, perm); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_perm (ref0, ref1, perm); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + vec_st (tmp, 0, dest); + tmp = vec_perm (ref0, ref1, perm); + vec_st (tmp, stride, dest); +} + +void MC_put_o_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_put_x_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, tmp; + + permA = vec_lvsl (0, ref); + permB = vec_add (permA, vec_splat_u8 (1)); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + vec_st (tmp, 0, dest); + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + vec_st (tmp, stride, dest); +} + +void MC_put_x_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; + + ones = vec_splat_u8 (1); + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + perm0B = vec_add (perm0A, ones); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B)); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_put_y_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (tmp0, tmp1); + vec_st (tmp, stride, dest); +} + +void MC_put_y_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (tmp0, tmp1); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (tmp0, tmp1); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (tmp0, tmp1); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (tmp0, tmp1); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +void MC_put_xy_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; + vector_u8_t ones; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + vec_st (tmp, stride, dest); + dest += 2*stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + vec_st (tmp, stride, dest); +} + +void MC_put_xy_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; + vector_u8_t avg0, avg1, xor0, xor1, tmp, ones; + + ones = vec_splat_u8 (1); + perm0A = vec_lvsl (0, ref); + perm0A = vec_mergeh (perm0A, perm0A); + perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); + perm0B = vec_add (perm0A, ones); + perm1A = vec_lvsl (stride, ref); + perm1A = vec_mergeh (perm1A, perm1A); + perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1))); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +#if 0 +void MC_put_xy_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, C, D, tmp, zero, ones; + vector_u16_t splat2, temp; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + zero = vec_splat_u8 (0); + splat2 = vec_splat_u16 (2); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + C = vec_perm (ref0, ref1, permA); + D = vec_perm (ref0, ref1, permB); + + temp = vec_add (vec_add ((vector_u16_t)vec_mergeh (zero, A), + (vector_u16_t)vec_mergeh (zero, B)), + vec_add ((vector_u16_t)vec_mergeh (zero, C), + (vector_u16_t)vec_mergeh (zero, D))); + temp = vec_sr (vec_add (temp, splat2), splat2); + tmp = vec_pack (temp, temp); + + vec_st (tmp, 0, dest); + dest += stride; + tmp = vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB)); + } while (--height); +} +#endif + +void MC_avg_o_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp, prev; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); + vec_st (tmp, stride, dest); +} + +void MC_avg_o_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1, prev; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_avg_x_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, tmp, prev; + + permA = vec_lvsl (0, ref); + permB = vec_add (permA, vec_splat_u8 (1)); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (0, dest); + ref += stride; + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), + vec_perm (ref0, ref1, permB))); + vec_st (tmp, stride, dest); +} + +void MC_avg_x_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; + vector_u8_t prev; + + ones = vec_splat_u8 (1); + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + perm0B = vec_add (perm0A, ones); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + prev = vec_ld (0, dest); + ref += stride; + tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), + vec_perm (ref0, ref1, perm0B))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), + vec_perm (ref0, ref1, perm1B))); + vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); +} + +void MC_avg_y_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp, prev; + + perm = vec_lvsl (0, ref); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + tmp1 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (15, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + tmp0 = vec_perm (ref0, ref1, perm); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + vec_st (tmp, stride, dest); +} + +void MC_avg_y_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1, prev; + + tmp0 = vec_lvsl (0, ref); + tmp0 = vec_mergeh (tmp0, tmp0); + perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); + tmp1 = vec_lvsl (stride, ref); + tmp1 = vec_mergeh (tmp1, tmp1); + perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (0, dest); + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp1 = vec_perm (ref0, ref1, perm1); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (7, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + tmp0 = vec_perm (ref0, ref1, perm0); + tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +void MC_avg_xy_16_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; + vector_u8_t ones, prev; + + ones = vec_splat_u8 (1); + permA = vec_lvsl (0, ref); + permB = vec_add (permA, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + ref += stride; + prev = vec_ld (2*stride, dest); + vec_st (tmp, stride, dest); + dest += 2*stride; + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (16, ref); + prev = vec_ld (stride, dest); + vec_st (tmp, 0, dest); + A = vec_perm (ref0, ref1, permA); + B = vec_perm (ref0, ref1, permB); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + vec_st (tmp, stride, dest); +} + +void MC_avg_xy_8_altivec (unsigned char * dest, const unsigned char * ref, + const int stride, int height) +{ + vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; + vector_u8_t avg0, avg1, xor0, xor1, tmp, ones, prev; + + ones = vec_splat_u8 (1); + perm0A = vec_lvsl (0, ref); + perm0A = vec_mergeh (perm0A, perm0A); + perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); + perm0B = vec_add (perm0A, ones); + perm1A = vec_lvsl (stride, ref); + perm1A = vec_mergeh (perm1A, perm1A); + perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); + perm1B = vec_add (perm1A, ones); + + height = (height >> 1) - 1; + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (0, dest); + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + do { + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + ref += stride; + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm1A); + B = vec_perm (ref0, ref1, perm1B); + avg1 = vec_avg (A, B); + xor1 = vec_xor (A, B); + tmp = vec_avg (prev, + vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + } while (--height); + + ref0 = vec_ld (0, ref); + ref1 = vec_ld (8, ref); + prev = vec_ld (stride, dest); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); + dest += stride; + A = vec_perm (ref0, ref1, perm0A); + B = vec_perm (ref0, ref1, perm0B); + avg0 = vec_avg (A, B); + xor0 = vec_xor (A, B); + tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), + vec_and (vec_and (ones, vec_or (xor0, xor1)), + vec_xor (avg0, avg1)))); + vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); + vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); +} + +#endif /* __ALTIVEC__ */ diff --git a/vldp2/libmpeg2/motion_comp_mlib.c b/vldp2/libmpeg2/motion_comp_mlib.c new file mode 100644 index 000000000..de181c065 --- /dev/null +++ b/vldp2/libmpeg2/motion_comp_mlib.c @@ -0,0 +1,190 @@ +/* + * motion_comp_mlib.c + * Copyright (C) 2000-2002 Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBMPEG2_MLIB + +#include +#include +#include +#include +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" + +static void MC_put_o_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoCopyRef_U8_U8_16x16 (dest, (uint8_t *) ref, stride); + else + mlib_VideoCopyRef_U8_U8_16x8 (dest, (uint8_t *) ref, stride); +} + +static void MC_put_x_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpX_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpX_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_put_y_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_put_xy_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpXY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpXY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_put_o_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoCopyRef_U8_U8_8x8 (dest, (uint8_t *) ref, stride); + else + mlib_VideoCopyRef_U8_U8_8x4 (dest, (uint8_t *) ref, stride); +} + +static void MC_put_x_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpX_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpX_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_put_y_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_put_xy_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpXY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpXY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_avg_o_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoCopyRefAve_U8_U8_16x16 (dest, (uint8_t *) ref, stride); + else + mlib_VideoCopyRefAve_U8_U8_16x8 (dest, (uint8_t *) ref, stride); +} + +static void MC_avg_x_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveX_U8_U8_16x16 (dest, (uint8_t *) ref, + stride, stride); + else + mlib_VideoInterpAveX_U8_U8_16x8 (dest, (uint8_t *) ref, + stride, stride); +} + +static void MC_avg_y_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveY_U8_U8_16x16 (dest, (uint8_t *) ref, + stride, stride); + else + mlib_VideoInterpAveY_U8_U8_16x8 (dest, (uint8_t *) ref, + stride, stride); +} + +static void MC_avg_xy_16_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 16) + mlib_VideoInterpAveXY_U8_U8_16x16 (dest, (uint8_t *) ref, + stride, stride); + else + mlib_VideoInterpAveXY_U8_U8_16x8 (dest, (uint8_t *) ref, + stride, stride); +} + +static void MC_avg_o_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoCopyRefAve_U8_U8_8x8 (dest, (uint8_t *) ref, stride); + else + mlib_VideoCopyRefAve_U8_U8_8x4 (dest, (uint8_t *) ref, stride); +} + +static void MC_avg_x_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveX_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpAveX_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_avg_y_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); + else + mlib_VideoInterpAveY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); +} + +static void MC_avg_xy_8_mlib (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + if (height == 8) + mlib_VideoInterpAveXY_U8_U8_8x8 (dest, (uint8_t *) ref, + stride, stride); + else + mlib_VideoInterpAveXY_U8_U8_8x4 (dest, (uint8_t *) ref, + stride, stride); +} + +MPEG2_MC_EXTERN (mlib) + +#endif diff --git a/vldp2/libmpeg2/motion_comp_mmx.c b/vldp2/libmpeg2/motion_comp_mmx.c new file mode 100644 index 000000000..33103e173 --- /dev/null +++ b/vldp2/libmpeg2/motion_comp_mmx.c @@ -0,0 +1,1005 @@ +/* + * motion_comp_mmx.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef ARCH_X86 + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" +#include "mmx.h" + +#define CPU_MMXEXT 0 +#define CPU_3DNOW 1 + + +/* MMX code - needs a rewrite */ + +/* + * Motion Compensation frequently needs to average values using the + * formula (x+y+1)>>1. Both MMXEXT and 3Dnow include one instruction + * to compute this, but it's been left out of classic MMX. + * + * We need to be careful of overflows when doing this computation. + * Rather than unpacking data to 16-bits, which reduces parallelism, + * we use the following formulas: + * + * (x+y)>>1 == (x&y)+((x^y)>>1) + * (x+y+1)>>1 == (x|y)-((x^y)>>1) + */ + +/* some rounding constants */ +static mmx_t mask1 = {0xfefefefefefefefeLL}; +static mmx_t round4 = {0x0002000200020002LL}; + +/* + * This code should probably be compiled with loop unrolling + * (ie, -funroll-loops in gcc)becuase some of the loops + * use a small static number of iterations. This was written + * with the assumption the compiler knows best about when + * unrolling will help + */ + +static inline void mmx_zero_reg () +{ + /* load 0 into mm0 */ + pxor_r2r (mm0, mm0); +} + +static inline void mmx_average_2_U8 (uint8_t * dest, const uint8_t * src1, + const uint8_t * src2) +{ + /* *dest = (*src1 + *src2 + 1)/ 2; */ + + movq_m2r (*src1, mm1); /* load 8 src1 bytes */ + movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ + + movq_m2r (*src2, mm3); /* load 8 src2 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ + + pxor_r2r (mm1, mm3); /* xor src1 and src2 */ + pand_m2r (mask1, mm3); /* mask lower bits */ + psrlq_i2r (1, mm3); /* /2 */ + por_r2r (mm2, mm4); /* or src1 and src2 */ + psubb_r2r (mm3, mm4); /* subtract subresults */ + movq_r2m (mm4, *dest); /* store result in dest */ +} + +static inline void mmx_interp_average_2_U8 (uint8_t * dest, + const uint8_t * src1, + const uint8_t * src2) +{ + /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */ + + movq_m2r (*dest, mm1); /* load 8 dest bytes */ + movq_r2r (mm1, mm2); /* copy 8 dest bytes */ + + movq_m2r (*src1, mm3); /* load 8 src1 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src1 bytes */ + + movq_m2r (*src2, mm5); /* load 8 src2 bytes */ + movq_r2r (mm5, mm6); /* copy 8 src2 bytes */ + + pxor_r2r (mm3, mm5); /* xor src1 and src2 */ + pand_m2r (mask1, mm5); /* mask lower bits */ + psrlq_i2r (1, mm5); /* /2 */ + por_r2r (mm4, mm6); /* or src1 and src2 */ + psubb_r2r (mm5, mm6); /* subtract subresults */ + movq_r2r (mm6, mm5); /* copy subresult */ + + pxor_r2r (mm1, mm5); /* xor srcavg and dest */ + pand_m2r (mask1, mm5); /* mask lower bits */ + psrlq_i2r (1, mm5); /* /2 */ + por_r2r (mm2, mm6); /* or srcavg and dest */ + psubb_r2r (mm5, mm6); /* subtract subresults */ + movq_r2m (mm6, *dest); /* store result in dest */ +} + +static inline void mmx_average_4_U8 (uint8_t * dest, const uint8_t * src1, + const uint8_t * src2, + const uint8_t * src3, + const uint8_t * src4) +{ + /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */ + + movq_m2r (*src1, mm1); /* load 8 src1 bytes */ + movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ + + punpcklbw_r2r (mm0, mm1); /* unpack low src1 bytes */ + punpckhbw_r2r (mm0, mm2); /* unpack high src1 bytes */ + + movq_m2r (*src2, mm3); /* load 8 src2 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ + + punpcklbw_r2r (mm0, mm3); /* unpack low src2 bytes */ + punpckhbw_r2r (mm0, mm4); /* unpack high src2 bytes */ + + paddw_r2r (mm3, mm1); /* add lows */ + paddw_r2r (mm4, mm2); /* add highs */ + + /* now have partials in mm1 and mm2 */ + + movq_m2r (*src3, mm3); /* load 8 src3 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src3 bytes */ + + punpcklbw_r2r (mm0, mm3); /* unpack low src3 bytes */ + punpckhbw_r2r (mm0, mm4); /* unpack high src3 bytes */ + + paddw_r2r (mm3, mm1); /* add lows */ + paddw_r2r (mm4, mm2); /* add highs */ + + movq_m2r (*src4, mm5); /* load 8 src4 bytes */ + movq_r2r (mm5, mm6); /* copy 8 src4 bytes */ + + punpcklbw_r2r (mm0, mm5); /* unpack low src4 bytes */ + punpckhbw_r2r (mm0, mm6); /* unpack high src4 bytes */ + + paddw_r2r (mm5, mm1); /* add lows */ + paddw_r2r (mm6, mm2); /* add highs */ + + /* now have subtotal in mm1 and mm2 */ + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); /* /4 */ + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); /* /4 */ + + packuswb_r2r (mm2, mm1); /* pack (w/ saturation) */ + movq_r2m (mm1, *dest); /* store result in dest */ +} + +static inline void mmx_interp_average_4_U8 (uint8_t * dest, + const uint8_t * src1, + const uint8_t * src2, + const uint8_t * src3, + const uint8_t * src4) +{ + /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */ + + movq_m2r (*src1, mm1); /* load 8 src1 bytes */ + movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ + + punpcklbw_r2r (mm0, mm1); /* unpack low src1 bytes */ + punpckhbw_r2r (mm0, mm2); /* unpack high src1 bytes */ + + movq_m2r (*src2, mm3); /* load 8 src2 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ + + punpcklbw_r2r (mm0, mm3); /* unpack low src2 bytes */ + punpckhbw_r2r (mm0, mm4); /* unpack high src2 bytes */ + + paddw_r2r (mm3, mm1); /* add lows */ + paddw_r2r (mm4, mm2); /* add highs */ + + /* now have partials in mm1 and mm2 */ + + movq_m2r (*src3, mm3); /* load 8 src3 bytes */ + movq_r2r (mm3, mm4); /* copy 8 src3 bytes */ + + punpcklbw_r2r (mm0, mm3); /* unpack low src3 bytes */ + punpckhbw_r2r (mm0, mm4); /* unpack high src3 bytes */ + + paddw_r2r (mm3, mm1); /* add lows */ + paddw_r2r (mm4, mm2); /* add highs */ + + movq_m2r (*src4, mm5); /* load 8 src4 bytes */ + movq_r2r (mm5, mm6); /* copy 8 src4 bytes */ + + punpcklbw_r2r (mm0, mm5); /* unpack low src4 bytes */ + punpckhbw_r2r (mm0, mm6); /* unpack high src4 bytes */ + + paddw_r2r (mm5, mm1); /* add lows */ + paddw_r2r (mm6, mm2); /* add highs */ + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); /* /4 */ + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); /* /4 */ + + /* now have subtotal/4 in mm1 and mm2 */ + + movq_m2r (*dest, mm3); /* load 8 dest bytes */ + movq_r2r (mm3, mm4); /* copy 8 dest bytes */ + + packuswb_r2r (mm2, mm1); /* pack (w/ saturation) */ + movq_r2r (mm1,mm2); /* copy subresult */ + + pxor_r2r (mm1, mm3); /* xor srcavg and dest */ + pand_m2r (mask1, mm3); /* mask lower bits */ + psrlq_i2r (1, mm3); /* /2 */ + por_r2r (mm2, mm4); /* or srcavg and dest */ + psubb_r2r (mm3, mm4); /* subtract subresults */ + movq_r2m (mm4, *dest); /* store result in dest */ +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, dest, ref); + + if (width == 16) + mmx_average_2_U8 (dest+8, dest+8, ref+8); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_o_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_o_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + mmx_zero_reg (); + + do { + movq_m2r (* ref, mm1); /* load 8 ref bytes */ + movq_r2m (mm1,* dest); /* store 8 bytes at curr */ + + if (width == 16) + { + movq_m2r (* (ref+8), mm1); /* load 8 ref bytes */ + movq_r2m (mm1,* (dest+8)); /* store 8 bytes at curr */ + } + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_o_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_mmx (16, height, dest, ref, stride); +} + +static void MC_put_o_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +/* Half pixel interpolation in the x direction */ +static inline void MC_avg_x_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_x_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_x_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_x_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_x_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_x_mmx (16, height, dest, ref, stride); +} + +static void MC_put_x_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_x_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_xy_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + const uint8_t * ref_next = ref + stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, + ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_xy_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_xy_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_xy_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + const uint8_t * ref_next = ref + stride; + + mmx_zero_reg (); + + do { + mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_xy_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_put_xy_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_avg_y_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + const uint8_t * ref_next = ref + stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_y_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_y_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (8, height, dest, ref, stride); +} + +/*-----------------------------------------------------------------------*/ + +static inline void MC_put_y_mmx (const int width, int height, uint8_t * dest, + const uint8_t * ref, const int stride) +{ + const uint8_t * ref_next = ref + stride; + + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_y_16_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_y_mmx (16, height, dest, ref, stride); +} + +static void MC_put_y_8_mmx (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put_y_mmx (8, height, dest, ref, stride); +} + + +MPEG2_MC_EXTERN (mmx) + + + + + + + +/* CPU_MMXEXT/CPU_3DNOW adaptation layer */ + +#define pavg_r2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_r2r (src, dest); \ + else \ + pavgusb_r2r (src, dest); \ +} while (0) + +#define pavg_m2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_m2r (src, dest); \ + else \ + pavgusb_m2r (src, dest); \ +} while (0) + + +/* CPU_MMXEXT code */ + + +static inline void MC_put1_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_r2m (mm0, *dest); + ref += stride; + dest += stride; + } while (--height); +} + +static inline void MC_put1_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg1_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg1_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_put2_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int offset, + const int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_put2_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int offset, + const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg2_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int offset, + const int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg2_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int offset, + const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static mmx_t mask_one = {0x0101010101010101LL}; + +static inline void MC_put4_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + movq_m2r (*ref, mm0); + movq_m2r (*(ref+1), mm1); + movq_r2r (mm0, mm7); + pxor_r2r (mm1, mm7); + pavg_r2r (mm1, mm0); + ref += stride; + + do { + movq_m2r (*ref, mm2); + movq_r2r (mm0, mm5); + + movq_m2r (*(ref+1), mm3); + movq_r2r (mm2, mm6); + + pxor_r2r (mm3, mm6); + pavg_r2r (mm3, mm2); + + por_r2r (mm6, mm7); + pxor_r2r (mm2, mm5); + + pand_r2r (mm5, mm7); + pavg_r2r (mm2, mm0); + + pand_m2r (mask_one, mm7); + + psubusb_r2r (mm7, mm0); + + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + + movq_r2r (mm6, mm7); /* unroll ! */ + movq_r2r (mm2, mm0); /* unroll ! */ + } while (--height); +} + +static inline void MC_put4_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static inline void MC_avg4_8 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static inline void MC_avg4_16 (int height, uint8_t * dest, const uint8_t * ref, + const int stride, const int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*(dest+8), mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static void MC_avg_o_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_o_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_o_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_o_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_x_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_y_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_y_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_xy_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_xy_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy_16_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy_8_mmxext (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + + +MPEG2_MC_EXTERN (mmxext) + + + +static void MC_avg_o_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_o_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_o_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_o_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_x_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_y_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_y_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_xy_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_xy_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy_16_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy_8_3dnow (uint8_t * dest, const uint8_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); +} + + +MPEG2_MC_EXTERN (3dnow) + +#endif diff --git a/vldp2/libmpeg2/mpeg2_internal.h b/vldp2/libmpeg2/mpeg2_internal.h new file mode 100644 index 000000000..0e364cbf4 --- /dev/null +++ b/vldp2/libmpeg2/mpeg2_internal.h @@ -0,0 +1,296 @@ +/* + * mpeg2_internal.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +/* macroblock modes */ +#define MACROBLOCK_INTRA 1 +#define MACROBLOCK_PATTERN 2 +#define MACROBLOCK_MOTION_BACKWARD 4 +#define MACROBLOCK_MOTION_FORWARD 8 +#define MACROBLOCK_QUANT 16 +#define DCT_TYPE_INTERLACED 32 +/* motion_type */ +#define MOTION_TYPE_MASK (3*64) +#define MOTION_TYPE_BASE 64 +#define MC_FIELD (1*64) +#define MC_FRAME (2*64) +#define MC_16X8 (2*64) +#define MC_DMV (3*64) + +/* picture structure */ +#define TOP_FIELD 1 +#define BOTTOM_FIELD 2 +#define FRAME_PICTURE 3 + +/* picture coding type */ +#define I_TYPE 1 +#define P_TYPE 2 +#define B_TYPE 3 +#define D_TYPE 4 + +typedef struct { + uint8_t * ref[2][3]; + uint8_t ** ref2[2]; + int pmv[2][2]; + int f_code[2]; +} motion_t; + +struct decoder_s { + /* first, state that carries information from one macroblock to the */ + /* next inside a slice, and is never used outside of mpeg2_slice() */ + + /* DCT coefficients - should be kept aligned ! */ + int16_t DCTblock[64]; + + /* bit parsing stuff */ + uint32_t bitstream_buf; /* current 32 bit working set */ + int bitstream_bits; /* used bits in working set */ + const uint8_t * bitstream_ptr; /* buffer with stream data */ + + uint8_t * dest[3]; + uint8_t * picture_dest[3]; + void (* convert) (void * fbuf_id, uint8_t * const * src, + unsigned int v_offset); + void * fbuf_id; + + int offset; + int stride; + int uv_stride; + unsigned int limit_x; + unsigned int limit_y_16; + unsigned int limit_y_8; + unsigned int limit_y; + + /* Motion vectors */ + /* The f_ and b_ correspond to the forward and backward motion */ + /* predictors */ + motion_t b_motion; + motion_t f_motion; + + /* predictor for DC coefficients in intra blocks */ + int16_t dc_dct_pred[3]; + + int quantizer_scale; /* remove */ + int dmv_offset; /* remove */ + unsigned int v_offset; /* remove */ + + /* now non-slice-specific information */ + + /* sequence header stuff */ + uint8_t intra_quantizer_matrix [64]; + uint8_t non_intra_quantizer_matrix [64]; + + /* The width and height of the picture snapped to macroblock units */ + int width; + int height; + int vertical_position_extension; + + /* picture header stuff */ + + /* what type of picture this is (I, P, B, D) */ + int coding_type; + + /* picture coding extension stuff */ + + /* quantization factor for intra dc coefficients */ + int intra_dc_precision; + /* top/bottom/both fields */ + int picture_structure; + /* bool to indicate all predictions are frame based */ + int frame_pred_frame_dct; + /* bool to indicate whether intra blocks have motion vectors */ + /* (for concealment) */ + int concealment_motion_vectors; + /* bit to indicate which quantization table to use */ + int q_scale_type; + /* bool to use different vlc tables */ + int intra_vlc_format; + /* used for DMV MC */ + int top_field_first; + + /* stuff derived from bitstream */ + + /* pointer to the zigzag scan we're supposed to be using */ + const uint8_t * scan; + + int second_field; + + int mpeg1; +}; + +typedef struct { + fbuf_t fbuf; +} fbuf_alloc_t; + +struct mpeg2dec_s { + decoder_t decoder; + + mpeg2_info_t info; + + uint32_t shift; + int is_display_initialized; + int (* action) (struct mpeg2dec_s * mpeg2dec); + int state; + uint32_t ext_state; + + /* allocated in init - gcc has problems allocating such big structures */ + uint8_t * chunk_buffer; + /* pointer to start of the current chunk */ + uint8_t * chunk_start; + /* pointer to current position in chunk_buffer */ + uint8_t * chunk_ptr; + /* last start code ? */ + uint8_t code; + + /* PTS */ + uint32_t pts_current, pts_previous; + int num_pts; + int bytes_since_pts; + + int first; + int alloc_index_user; + int alloc_index; + uint8_t first_decode_slice; + uint8_t nb_decode_slices; + + sequence_t new_sequence; + sequence_t sequence; + picture_t pictures[4]; + picture_t * picture; + /*const*/ fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */ + + fbuf_alloc_t fbuf_alloc[3]; + int custom_fbuf; + + uint8_t * yuv_buf[3][3]; + int yuv_index; + void * convert_id; + int convert_size[3]; + void (* convert_start) (void * id, uint8_t * const * dest, int flags); + void (* convert_copy) (void * id, uint8_t * const * src, + unsigned int v_offset); + + uint8_t * buf_start; + uint8_t * buf_end; + + int16_t display_offset_x, display_offset_y; +}; + +typedef struct { +#ifdef ARCH_PPC + uint8_t regv[12*16]; +#endif + int dummy; +} cpu_state_t; + +/* alloc.c */ +#define ALLOC_MPEG2DEC 0 +#define ALLOC_CHUNK 1 +#define ALLOC_YUV 2 +#define ALLOC_CONVERT_ID 3 +#define ALLOC_CONVERTED 4 +void * mpeg2_malloc (int size, int reason); +void mpeg2_free (void * buf); + +/* cpu_accel.c */ +uint32_t mpeg2_detect_accel (void); + +/* cpu_state.c */ +void mpeg2_cpu_state_init (uint32_t accel); + +/* decode.c */ +int mpeg2_seek_sequence (mpeg2dec_t * mpeg2dec); +int mpeg2_seek_header (mpeg2dec_t * mpeg2dec); +int mpeg2_parse_header (mpeg2dec_t * mpeg2dec); + +/* header.c */ +void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec); +int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec); +int mpeg2_header_gop (mpeg2dec_t * mpeg2dec); +int mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec); +int mpeg2_header_picture (mpeg2dec_t * mpeg2dec); +int mpeg2_header_extension (mpeg2dec_t * mpeg2dec); +int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec); +void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec); +int mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec); +int mpeg2_header_end (mpeg2dec_t * mpeg2dec); +void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int coding_type); + +/* idct.c */ +void mpeg2_idct_init (uint32_t accel); + +/* idct_mlib.c */ +void mpeg2_idct_add_mlib (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, + int stride); +void mpeg2_idct_add_mlib_non_ieee (int last, int16_t * block, + uint8_t * dest, int stride); + +/* idct_mmx.c */ +void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_mmxext (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_mmx (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_mmx_init (void); + +/* idct_altivec.c */ +void mpeg2_idct_copy_altivec (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_altivec (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_altivec_init (void); + +/* idct_alpha.c */ +void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_mvi (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, int stride); +void mpeg2_idct_add_alpha (int last, int16_t * block, + uint8_t * dest, int stride); +void mpeg2_idct_alpha_init(int no_mvi); + +/* motion_comp.c */ +void mpeg2_mc_init (uint32_t accel); + +typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int); + +typedef struct { + mpeg2_mc_fct * put [8]; + mpeg2_mc_fct * avg [8]; +} mpeg2_mc_t; + +#define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \ + {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \ + MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \ + {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \ + MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \ +}; + +extern mpeg2_mc_t mpeg2_mc_c; +extern mpeg2_mc_t mpeg2_mc_mmx; +extern mpeg2_mc_t mpeg2_mc_mmxext; +extern mpeg2_mc_t mpeg2_mc_3dnow; +extern mpeg2_mc_t mpeg2_mc_altivec; +extern mpeg2_mc_t mpeg2_mc_alpha; +extern mpeg2_mc_t mpeg2_mc_mlib; diff --git a/vldp2/libmpeg2/slice.c b/vldp2/libmpeg2/slice.c new file mode 100644 index 000000000..7f6a2ed05 --- /dev/null +++ b/vldp2/libmpeg2/slice.c @@ -0,0 +1,1796 @@ +/* + * slice.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include + +#include "mpeg2.h" +#include "mpeg2_internal.h" +#include "attributes.h" + +extern mpeg2_mc_t mpeg2_mc; +extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); +extern void (* mpeg2_idct_add) (int last, int16_t * block, + uint8_t * dest, int stride); +extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); +extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); + +#include "vlc.h" + +static int non_linear_quantizer_scale [] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112 +}; + +static inline int get_macroblock_modes (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int macroblock_modes; + const MBtab * tab; + + switch (decoder->coding_type) { + case I_TYPE: + + tab = MB_I + UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if ((! (decoder->frame_pred_frame_dct)) && + (decoder->picture_structure == FRAME_PICTURE)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + + return macroblock_modes; + + case P_TYPE: + + tab = MB_P + UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (decoder->picture_structure != FRAME_PICTURE) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (decoder->frame_pred_frame_dct) { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case B_TYPE: + + tab = MB_B + UBITS (bit_buf, 6); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (decoder->picture_structure != FRAME_PICTURE) { + if (! (macroblock_modes & MACROBLOCK_INTRA)) { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } else if (decoder->frame_pred_frame_dct) { + /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } else { + if (macroblock_modes & MACROBLOCK_INTRA) + goto intra; + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { + intra: + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case D_TYPE: + + DUMPBITS (bit_buf, bits, 1); + return MACROBLOCK_INTRA; + + default: + return 0; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_quantizer_scale (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + + int quantizer_scale_code; + + quantizer_scale_code = UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, 5); + + if (decoder->q_scale_type) + return non_linear_quantizer_scale [quantizer_scale_code]; + else + return quantizer_scale_code << 1; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_motion_delta (decoder_t * const decoder, + const int f_code) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + + int delta; + int sign; + const MVtab * tab; + + if (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 1); + return 0; + } else if (bit_buf >= 0x0c000000) { + + tab = MV_4 + UBITS (bit_buf, 4); + delta = (tab->delta << f_code) + 1; + bits += tab->len + f_code + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) + delta += UBITS (bit_buf, f_code); + bit_buf <<= f_code; + + return (delta ^ sign) - sign; + + } else { + + tab = MV_10 + UBITS (bit_buf, 10); + delta = (tab->delta << f_code) + 1; + bits += tab->len + 1; + bit_buf <<= tab->len; + + sign = SBITS (bit_buf, 1); + bit_buf <<= 1; + + if (f_code) { + NEEDBITS (bit_buf, bits, bit_ptr); + delta += UBITS (bit_buf, f_code); + DUMPBITS (bit_buf, bits, f_code); + } + + return (delta ^ sign) - sign; + + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int bound_motion_vector (const int vector, const int f_code) +{ +#if 0 + unsigned int limit; + int sign; + + limit = 16 << f_code; + + if ((unsigned int)(vector + limit) < 2 * limit) + return vector; + else { + sign = ((int32_t)vector) >> 31; + return vector - ((2 * limit) ^ sign) + sign; + } +#else + return ((int32_t)vector << (27 - f_code)) >> (27 - f_code); +#endif +} + +static inline int get_dmv (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + + const DMVtab * tab; + + tab = DMV_2 + UBITS (bit_buf, 2); + DUMPBITS (bit_buf, bits, tab->len); + return tab->dmv; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_coded_block_pattern (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + + const CBPtab * tab; + + NEEDBITS (bit_buf, bits, bit_ptr); + + if (bit_buf >= 0x20000000) { + + tab = CBP_7 + (UBITS (bit_buf, 7) - 16); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + + } else { + + tab = CBP_9 + UBITS (bit_buf, 9); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + } + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_luma_dc_dct_diff (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_lum_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 3); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline int get_chroma_dc_dct_diff (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + const DCtab * tab; + int size; + int dc_diff; + + if (bit_buf < 0xf8000000) { + tab = DC_chrom_5 + UBITS (bit_buf, 5); + size = tab->size; + if (size) { + bits += tab->len + size; + bit_buf <<= tab->len; + dc_diff = + UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + bit_buf <<= size; + return dc_diff; + } else { + DUMPBITS (bit_buf, bits, 2); + return 0; + } + } else { + tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len + 1); + NEEDBITS (bit_buf, bits, bit_ptr); + dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); + DUMPBITS (bit_buf, bits, size); + return dc_diff; + } +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define SATURATE(val) \ +do { \ + if (unlikely ((uint32_t)(val + 2048) > 4095)) \ + val = SBITS (val, 1) ^ 2047; \ +} while (0) + +static void get_intra_block_B14 (decoder_t * const decoder) +{ + int i; + int j; + int val; + const uint8_t * scan = decoder->scan; + const uint8_t * quant_matrix = decoder->intra_quantizer_matrix; + int quantizer_scale = decoder->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + const uint8_t * bit_ptr; + int16_t * dest; + + dest = decoder->DCTblock; + i = 0; + mismatch = ~dest[0]; + + bit_buf = decoder->bitstream_buf; + bits = decoder->bitstream_bits; + bit_ptr = decoder->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[j]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static void get_intra_block_B15 (decoder_t * const decoder) +{ + int i; + int j; + int val; + const uint8_t * scan = decoder->scan; + const uint8_t * quant_matrix = decoder->intra_quantizer_matrix; + int quantizer_scale = decoder->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + const uint8_t * bit_ptr; + int16_t * dest; + + dest = decoder->DCTblock; + i = 0; + mismatch = ~dest[0]; + + bit_buf = decoder->bitstream_buf; + bits = decoder->bitstream_bits; + bit_ptr = decoder->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x04000000) { + + tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) { + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else { + + /* end of block. I commented out this code because if we */ + /* dont exit here we will still exit at the later test :) */ + + /* if (i >= 128) break; */ /* end of block */ + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check against buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = (SBITS (bit_buf, 12) * + quantizer_scale * quant_matrix[j]) / 16; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + } else if (bit_buf >= 0x02000000) { + tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static int get_non_intra_block (decoder_t * const decoder) +{ + int i; + int j; + int val; + const uint8_t * scan = decoder->scan; + const uint8_t * quant_matrix = decoder->non_intra_quantizer_matrix; + int quantizer_scale = decoder->quantizer_scale; + int mismatch; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + const uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + mismatch = 1; + dest = decoder->DCTblock; + + bit_buf = decoder->bitstream_buf; + bits = decoder->bitstream_bits; + bit_ptr = decoder->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[j]) / 32; + + SATURATE (val); + dest[j] = val; + mismatch ^= val; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + dest[63] ^= mismatch & 1; + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; + return i; +} + +static void get_mpeg1_intra_block (decoder_t * const decoder) +{ + int i; + int j; + int val; + const uint8_t * scan = decoder->scan; + const uint8_t * quant_matrix = decoder->intra_quantizer_matrix; + int quantizer_scale = decoder->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + const uint8_t * bit_ptr; + int16_t * dest; + + i = 0; + dest = decoder->DCTblock; + + bit_buf = decoder->bitstream_buf; + bits = decoder->bitstream_bits; + bit_ptr = decoder->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = (val * quantizer_scale * quant_matrix[j]) / 16; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static int get_mpeg1_non_intra_block (decoder_t * const decoder) +{ + int i; + int j; + int val; + const uint8_t * scan = decoder->scan; + const uint8_t * quant_matrix = decoder->non_intra_quantizer_matrix; + int quantizer_scale = decoder->quantizer_scale; + const DCTtab * tab; + uint32_t bit_buf; + int bits; + const uint8_t * bit_ptr; + int16_t * dest; + + i = -1; + dest = decoder->DCTblock; + + bit_buf = decoder->bitstream_buf; + bits = decoder->bitstream_bits; + bit_ptr = decoder->bitstream_ptr; + + NEEDBITS (bit_buf, bits, bit_ptr); + if (bit_buf >= 0x28000000) { + tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); + goto entry_1; + } else + goto entry_2; + + while (1) { + if (bit_buf >= 0x28000000) { + + tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ + + normal_code: + j = scan[i]; + bit_buf <<= tab->len; + bits += tab->len + 1; + val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; + + /* oddification */ + val = (val - 1) | 1; + + /* if (bitstream_get (1)) val = -val; */ + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + + SATURATE (val); + dest[j] = val; + + bit_buf <<= 1; + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } + + entry_2: + if (bit_buf >= 0x04000000) { + + tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); + + i += tab->run; + if (i < 64) + goto normal_code; + + /* escape code */ + + i += UBITS (bit_buf << 6, 6) - 64; + if (i >= 64) + break; /* illegal, check needed to avoid buffer overflow */ + + j = scan[i]; + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + val = SBITS (bit_buf, 8); + if (! (val & 0x7f)) { + DUMPBITS (bit_buf, bits, 8); + val = UBITS (bit_buf, 8) + 2 * val; + } + val = 2 * (val + SBITS (val, 1)) + 1; + val = (val * quantizer_scale * quant_matrix[j]) / 32; + + /* oddification */ + val = (val + ~SBITS (val, 1)) | 1; + + SATURATE (val); + dest[j] = val; + + DUMPBITS (bit_buf, bits, 8); + NEEDBITS (bit_buf, bits, bit_ptr); + + continue; + + } else if (bit_buf >= 0x02000000) { + tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00800000) { + tab = DCT_13 + (UBITS (bit_buf, 13) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else if (bit_buf >= 0x00200000) { + tab = DCT_15 + (UBITS (bit_buf, 15) - 16); + i += tab->run; + if (i < 64) + goto normal_code; + } else { + tab = DCT_16 + UBITS (bit_buf, 16); + bit_buf <<= 16; + GETWORD (bit_buf, bits + 16, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; + return i; +} + +static inline void slice_intra_DCT (decoder_t * const decoder, const int cc, + uint8_t * const dest, const int stride) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + NEEDBITS (bit_buf, bits, bit_ptr); + /* Get the intra DC coefficient and inverse quantize it */ + if (cc == 0) + decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder); + else + decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder); + decoder->DCTblock[0] = + decoder->dc_dct_pred[cc] << (3 - decoder->intra_dc_precision); + + if (decoder->mpeg1) { + if (decoder->coding_type != D_TYPE) + get_mpeg1_intra_block (decoder); + } else if (decoder->intra_vlc_format) + get_intra_block_B15 (decoder); + else + get_intra_block_B14 (decoder); + mpeg2_idct_copy (decoder->DCTblock, dest, stride); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline void slice_non_intra_DCT (decoder_t * const decoder, + uint8_t * const dest, const int stride) +{ + int last; + + if (decoder->mpeg1) + last = get_mpeg1_non_intra_block (decoder); + else + last = get_non_intra_block (decoder); + mpeg2_idct_add (last, decoder->DCTblock, dest, stride); +} + +#define MOTION(table,ref,motion_x,motion_y,size,y) \ + pos_x = 2 * decoder->offset + motion_x; \ + pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \ + if ((pos_x > decoder->limit_x) || (pos_y > decoder->limit_y_ ## size)) \ + return; \ + xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ + table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ + ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \ + decoder->stride, size); \ + motion_x /= 2; motion_y /= 2; \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + offset = (((decoder->offset + motion_x) >> 1) + \ + ((((decoder->v_offset + motion_y) >> 1) + y/2) * \ + decoder->uv_stride)); \ + table[4+xy_half] (decoder->dest[1] + y/2 * decoder->uv_stride + \ + (decoder->offset >> 1), ref[1] + offset, \ + decoder->uv_stride, size/2); \ + table[4+xy_half] (decoder->dest[2] + y/2 * decoder->uv_stride + \ + (decoder->offset >> 1), ref[2] + offset, \ + decoder->uv_stride, size/2) + +#define MOTION_FIELD(table,ref,motion_x,motion_y,dest_field,op,src_field) \ + pos_x = 2 * decoder->offset + motion_x; \ + pos_y = decoder->v_offset + motion_y; \ + if ((pos_x > decoder->limit_x) || (pos_y > decoder->limit_y)) \ + return; \ + xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ + table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \ + decoder->offset, \ + (ref[0] + (pos_x >> 1) + \ + ((pos_y op) + src_field) * decoder->stride), \ + 2 * decoder->stride, 8); \ + motion_x /= 2; motion_y /= 2; \ + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ + offset = (((decoder->offset + motion_x) >> 1) + \ + (((decoder->v_offset >> 1) + (motion_y op) + src_field) * \ + decoder->uv_stride)); \ + table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \ + (decoder->offset >> 1), ref[1] + offset, \ + 2 * decoder->uv_stride, 4); \ + table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \ + (decoder->offset >> 1), ref[2] + offset, \ + 2 * decoder->uv_stride, 4) + +static void motion_mp1 (decoder_t * const decoder, motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = (motion->pmv[0][0] + + (get_motion_delta (decoder, + motion->f_code[0]) << motion->f_code[1])); + motion_x = bound_motion_vector (motion_x, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] + + (get_motion_delta (decoder, + motion->f_code[0]) << motion->f_code[1])); + motion_y = bound_motion_vector (motion_y, + motion->f_code[0] + motion->f_code[1]); + motion->pmv[0][1] = motion_y; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_frame (decoder_t * const decoder, + motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (decoder, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_field (decoder_t * const decoder, + motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y, field; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (decoder, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[0][1] = motion_y << 1; + + MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); + + NEEDBITS (bit_buf, bits, bit_ptr); + field = UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (decoder, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion_y << 1; + + MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fr_dmv (decoder_t * const decoder, motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + dmv_x = get_dmv (decoder); + + motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (decoder, + motion->f_code[1]); + /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ + motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; + dmv_y = get_dmv (decoder); + + m = decoder->top_field_first ? 1 : 3; + other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; + other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; + MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); + + m = decoder->top_field_first ? 3 : 1; + other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; + other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; + MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0); + + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); + offset = (decoder->offset + (motion_x >> 1) + + (decoder->v_offset + (motion_y & ~1)) * decoder->stride); + mpeg2_mc.avg[xy_half] + (decoder->dest[0] + decoder->offset, + motion->ref[0][0] + offset, 2 * decoder->stride, 8); + mpeg2_mc.avg[xy_half] + (decoder->dest[0] + decoder->stride + decoder->offset, + motion->ref[0][0] + decoder->stride + offset, 2 * decoder->stride, 8); + motion_x /= 2; motion_y /= 2; + xy_half = ((motion_y & 1) << 1) | (motion_x & 1); + offset = (((decoder->offset + motion_x) >> 1) + + (((decoder->v_offset >> 1) + (motion_y & ~1)) * + decoder->uv_stride)); + mpeg2_mc.avg[4+xy_half] + (decoder->dest[1] + (decoder->offset >> 1), + motion->ref[0][1] + offset, 2 * decoder->uv_stride, 4); + mpeg2_mc.avg[4+xy_half] + (decoder->dest[1] + decoder->uv_stride + (decoder->offset >> 1), + motion->ref[0][1] + decoder->uv_stride + offset, + 2 * decoder->uv_stride, 4); + mpeg2_mc.avg[4+xy_half] + (decoder->dest[2] + (decoder->offset >> 1), + motion->ref[0][2] + offset, 2 * decoder->uv_stride, 4); + mpeg2_mc.avg[4+xy_half] + (decoder->dest[2] + decoder->uv_stride + (decoder->offset >> 1), + motion->ref[0][2] + decoder->uv_stride + offset, + 2 * decoder->uv_stride, 4); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static inline void motion_reuse (const decoder_t * const decoder, + const motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ + int motion_x, motion_y; + unsigned int pos_x, pos_y, xy_half, offset; + + motion_x = motion->pmv[0][0]; + motion_y = motion->pmv[0][1]; + + MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); +} + +static inline void motion_zero (const decoder_t * const decoder, + const motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ + unsigned int offset; + + table[0] (decoder->dest[0] + decoder->offset, + (motion->ref[0][0] + decoder->offset + + decoder->v_offset * decoder->stride), + decoder->stride, 16); + + offset = ((decoder->offset >> 1) + + (decoder->v_offset >> 1) * decoder->uv_stride); + table[4] (decoder->dest[1] + (decoder->offset >> 1), + motion->ref[0][1] + offset, decoder->uv_stride, 8); + table[4] (decoder->dest[2] + (decoder->offset >> 1), + motion->ref[0][2] + offset, decoder->uv_stride, 8); +} + +/* like motion_frame, but parsing without actual motion compensation */ +static void motion_fr_conceal (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (decoder->f_motion.pmv[0][0] + + get_motion_delta (decoder, decoder->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]); + decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (decoder->f_motion.pmv[0][1] + + get_motion_delta (decoder, decoder->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]); + decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_field (decoder_t * const decoder, + motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (decoder, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_16x8 (decoder_t * const decoder, motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y; + uint8_t ** ref_field; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[0][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[0][1] + get_motion_delta (decoder, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[0][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 8, 0); + + NEEDBITS (bit_buf, bits, bit_ptr); + ref_field = motion->ref2[UBITS (bit_buf, 1)]; + DUMPBITS (bit_buf, bits, 1); + + motion_x = motion->pmv[1][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion_x; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_y = motion->pmv[1][1] + get_motion_delta (decoder, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion_y; + + MOTION (table, ref_field, motion_x, motion_y, 8, 8); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_dmv (decoder_t * const decoder, motion_t * const motion, + mpeg2_mc_fct * const * const table) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int motion_x, motion_y, other_x, other_y; + unsigned int pos_x, pos_y, xy_half, offset; + + NEEDBITS (bit_buf, bits, bit_ptr); + motion_x = motion->pmv[0][0] + get_motion_delta (decoder, + motion->f_code[0]); + motion_x = bound_motion_vector (motion_x, motion->f_code[0]); + motion->pmv[1][0] = motion->pmv[0][0] = motion_x; + NEEDBITS (bit_buf, bits, bit_ptr); + other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (decoder); + + motion_y = motion->pmv[0][1] + get_motion_delta (decoder, + motion->f_code[1]); + motion_y = bound_motion_vector (motion_y, motion->f_code[1]); + motion->pmv[1][1] = motion->pmv[0][1] = motion_y; + other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (decoder) + + decoder->dmv_offset); + + MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); + MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void motion_fi_conceal (decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); /* remove field_select */ + + tmp = (decoder->f_motion.pmv[0][0] + + get_motion_delta (decoder, decoder->f_motion.f_code[0])); + tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]); + decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp; + + NEEDBITS (bit_buf, bits, bit_ptr); + tmp = (decoder->f_motion.pmv[0][1] + + get_motion_delta (decoder, decoder->f_motion.f_code[1])); + tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]); + decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp; + + DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ +#undef bit_buf +#undef bits +#undef bit_ptr +} + +#define MOTION_CALL(routine,direction) \ +do { \ + if ((direction) & MACROBLOCK_MOTION_FORWARD) \ + routine (decoder, &(decoder->f_motion), mpeg2_mc.put); \ + if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ + routine (decoder, &(decoder->b_motion), \ + ((direction) & MACROBLOCK_MOTION_FORWARD ? \ + mpeg2_mc.avg : mpeg2_mc.put)); \ +} while (0) + +#define NEXT_MACROBLOCK \ +do { \ + decoder->offset += 16; \ + if (decoder->offset == decoder->width) { \ + do { /* just so we can use the break statement */ \ + if (decoder->convert) { \ + decoder->convert (decoder->fbuf_id, decoder->dest, \ + decoder->v_offset); \ + if (decoder->coding_type == B_TYPE) \ + break; \ + } \ + decoder->dest[0] += 16 * decoder->stride; \ + decoder->dest[1] += 4 * decoder->stride; \ + decoder->dest[2] += 4 * decoder->stride; \ + } while (0); \ + decoder->v_offset += 16; \ + if (decoder->v_offset > decoder->limit_y) { \ + if (mpeg2_cpu_state_restore) \ + mpeg2_cpu_state_restore (&cpu_state); \ + return; \ + } \ + decoder->offset = 0; \ + } \ +} while (0) + +void mpeg2_init_fbuf (decoder_t * decoder, uint8_t * current_fbuf[3], + uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]) +{ + int offset, stride, height, bottom_field; + + stride = decoder->width; + bottom_field = (decoder->picture_structure == BOTTOM_FIELD); + offset = bottom_field ? stride : 0; + height = decoder->height; + + decoder->picture_dest[0] = current_fbuf[0] + offset; + decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1); + decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1); + + decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset; + decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1); + decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1); + + decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset; + decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1); + decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1); + + if (decoder->picture_structure != FRAME_PICTURE) { + decoder->dmv_offset = bottom_field ? 1 : -1; + decoder->f_motion.ref2[0] = decoder->f_motion.ref[bottom_field]; + decoder->f_motion.ref2[1] = decoder->f_motion.ref[!bottom_field]; + decoder->b_motion.ref2[0] = decoder->b_motion.ref[bottom_field]; + decoder->b_motion.ref2[1] = decoder->b_motion.ref[!bottom_field]; + offset = stride - offset; + + if (decoder->second_field && (decoder->coding_type != B_TYPE)) + forward_fbuf = current_fbuf; + + decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset; + decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1); + decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1); + + decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset; + decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1); + decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1); + + stride <<= 1; + height >>= 1; + } + + decoder->stride = stride; + decoder->uv_stride = stride >> 1; + decoder->limit_x = 2 * decoder->width - 32; + decoder->limit_y_16 = 2 * height - 32; + decoder->limit_y_8 = 2 * height - 16; + decoder->limit_y = height - 16; +} + +static inline int slice_init (decoder_t * const decoder, int code) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int offset; + const MBAtab * mba; + + decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = + decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision; + + decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; + decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; + decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0; + decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0; + + if (decoder->vertical_position_extension) { + code += UBITS (bit_buf, 3) << 7; + DUMPBITS (bit_buf, bits, 3); + } + decoder->v_offset = (code - 1) * 16; + offset = 0; + if (!(decoder->convert) || decoder->coding_type != B_TYPE) + offset = (code - 1) * decoder->stride * 4; + + decoder->dest[0] = decoder->picture_dest[0] + offset * 4; + decoder->dest[1] = decoder->picture_dest[1] + offset; + decoder->dest[2] = decoder->picture_dest[2] + offset; + + decoder->quantizer_scale = get_quantizer_scale (decoder); + + /* ignore intra_slice and all the extra data */ + while (bit_buf & 0x80000000) { + DUMPBITS (bit_buf, bits, 9); + NEEDBITS (bit_buf, bits, bit_ptr); + } + + /* decode initial macroblock address increment */ + offset = 0; + while (1) { + if (bit_buf >= 0x08000000) { + mba = MBA_5 + (UBITS (bit_buf, 6) - 2); + break; + } else if (bit_buf >= 0x01800000) { + mba = MBA_11 + (UBITS (bit_buf, 12) - 24); + break; + } else switch (UBITS (bit_buf, 12)) { + case 8: /* macroblock_escape */ + offset += 33; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + case 15: /* macroblock_stuffing (MPEG1 only) */ + bit_buf &= 0xfffff; + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* error */ + return 1; + } + } + DUMPBITS (bit_buf, bits, mba->len + 1); + decoder->offset = (offset + mba->mba) << 4; + + while (decoder->offset - decoder->width >= 0) { + decoder->offset -= decoder->width; + if (!(decoder->convert) || decoder->coding_type != B_TYPE) { + decoder->dest[0] += 16 * decoder->stride; + decoder->dest[1] += 4 * decoder->stride; + decoder->dest[2] += 4 * decoder->stride; + } + decoder->v_offset += 16; + } + if (decoder->v_offset > decoder->limit_y) + return 1; + + return 0; +#undef bit_buf +#undef bits +#undef bit_ptr +} + +void mpeg2_slice (decoder_t * const decoder, const int code, + const uint8_t * const buffer) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + cpu_state_t cpu_state; + + bitstream_init (decoder, buffer); + + if (slice_init (decoder, code)) + return; + + if (mpeg2_cpu_state_save) + mpeg2_cpu_state_save (&cpu_state); + + while (1) { + int macroblock_modes; + int mba_inc; + const MBAtab * mba; + + NEEDBITS (bit_buf, bits, bit_ptr); + + macroblock_modes = get_macroblock_modes (decoder); + + /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */ + if (macroblock_modes & MACROBLOCK_QUANT) + decoder->quantizer_scale = get_quantizer_scale (decoder); + + if (macroblock_modes & MACROBLOCK_INTRA) { + + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (decoder->concealment_motion_vectors) { + if (decoder->picture_structure == FRAME_PICTURE) + motion_fr_conceal (decoder); + else + motion_fi_conceal (decoder); + } else { + decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; + decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; + decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0; + decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0; + } + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = decoder->stride; + DCT_stride = decoder->stride * 2; + } else { + DCT_offset = decoder->stride * 8; + DCT_stride = decoder->stride; + } + + offset = decoder->offset; + dest_y = decoder->dest[0] + offset; + slice_intra_DCT (decoder, 0, dest_y, DCT_stride); + slice_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); + slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); + slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); + slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), + decoder->uv_stride); + slice_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), + decoder->uv_stride); + + if (decoder->coding_type == D_TYPE) { + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); + } + } else { + + if (decoder->picture_structure == FRAME_PICTURE) + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FRAME: + if (decoder->mpeg1) + MOTION_CALL (motion_mp1, macroblock_modes); + else + MOTION_CALL (motion_fr_frame, macroblock_modes); + break; + + case MC_FIELD: + MOTION_CALL (motion_fr_field, macroblock_modes); + break; + + case MC_DMV: + MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + decoder->f_motion.pmv[0][0] = 0; + decoder->f_motion.pmv[0][1] = 0; + decoder->f_motion.pmv[1][0] = 0; + decoder->f_motion.pmv[1][1] = 0; + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + else + switch (macroblock_modes & MOTION_TYPE_MASK) { + case MC_FIELD: + MOTION_CALL (motion_fi_field, macroblock_modes); + break; + + case MC_16X8: + MOTION_CALL (motion_fi_16x8, macroblock_modes); + break; + + case MC_DMV: + MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); + break; + + case 0: + /* non-intra mb without forward mv in a P picture */ + decoder->f_motion.pmv[0][0] = 0; + decoder->f_motion.pmv[0][1] = 0; + decoder->f_motion.pmv[1][0] = 0; + decoder->f_motion.pmv[1][1] = 0; + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + break; + } + + if (macroblock_modes & MACROBLOCK_PATTERN) { + int coded_block_pattern; + int DCT_offset, DCT_stride; + int offset; + uint8_t * dest_y; + + if (macroblock_modes & DCT_TYPE_INTERLACED) { + DCT_offset = decoder->stride; + DCT_stride = decoder->stride * 2; + } else { + DCT_offset = decoder->stride * 8; + DCT_stride = decoder->stride; + } + + coded_block_pattern = get_coded_block_pattern (decoder); + + offset = decoder->offset; + dest_y = decoder->dest[0] + offset; + if (coded_block_pattern & 0x20) + slice_non_intra_DCT (decoder, dest_y, DCT_stride); + if (coded_block_pattern & 0x10) + slice_non_intra_DCT (decoder, dest_y + 8, DCT_stride); + if (coded_block_pattern & 0x08) + slice_non_intra_DCT (decoder, dest_y + DCT_offset, + DCT_stride); + if (coded_block_pattern & 0x04) + slice_non_intra_DCT (decoder, dest_y + DCT_offset + 8, + DCT_stride); + if (coded_block_pattern & 0x2) + slice_non_intra_DCT (decoder, + decoder->dest[1] + (offset >> 1), + decoder->uv_stride); + if (coded_block_pattern & 0x1) + slice_non_intra_DCT (decoder, + decoder->dest[2] + (offset >> 1), + decoder->uv_stride); + } + + decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = + decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision; + } + + NEXT_MACROBLOCK; + + NEEDBITS (bit_buf, bits, bit_ptr); + mba_inc = 0; + while (1) { + if (bit_buf >= 0x10000000) { + mba = MBA_5 + (UBITS (bit_buf, 5) - 2); + break; + } else if (bit_buf >= 0x03000000) { + mba = MBA_11 + (UBITS (bit_buf, 11) - 24); + break; + } else switch (UBITS (bit_buf, 11)) { + case 8: /* macroblock_escape */ + mba_inc += 33; + /* pass through */ + case 15: /* macroblock_stuffing (MPEG1 only) */ + DUMPBITS (bit_buf, bits, 11); + NEEDBITS (bit_buf, bits, bit_ptr); + continue; + default: /* end of slice, or error */ + if (mpeg2_cpu_state_restore) + mpeg2_cpu_state_restore (&cpu_state); + return; + } + } + DUMPBITS (bit_buf, bits, mba->len); + mba_inc += mba->mba; + + if (mba_inc) { + decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = + decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision; + + if (decoder->coding_type == P_TYPE) { + decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; + decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; + + do { + MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); + NEXT_MACROBLOCK; + } while (--mba_inc); + } else { + do { + MOTION_CALL (motion_reuse, macroblock_modes); + NEXT_MACROBLOCK; + } while (--mba_inc); + } + } + } +#undef bit_buf +#undef bits +#undef bit_ptr +} diff --git a/vldp2/libmpeg2/vlc.h b/vldp2/libmpeg2/vlc.h new file mode 100644 index 000000000..aa3dfe184 --- /dev/null +++ b/vldp2/libmpeg2/vlc.h @@ -0,0 +1,428 @@ +/* + * vlc.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define GETWORD(bit_buf,shift,bit_ptr) \ +do { \ + bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ + bit_ptr += 2; \ +} while (0) + +static inline void bitstream_init (decoder_t * decoder, const uint8_t * start) +{ + decoder->bitstream_buf = + (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3]; + decoder->bitstream_ptr = start + 4; + decoder->bitstream_bits = -16; +} + +/* make sure that there are at least 16 valid bits in bit_buf */ +#define NEEDBITS(bit_buf,bits,bit_ptr) \ +do { \ + if (unlikely (bits > 0)) { \ + GETWORD (bit_buf, bits, bit_ptr); \ + bits -= 16; \ + } \ +} while (0) + +/* remove num valid bits from bit_buf */ +#define DUMPBITS(bit_buf,bits,num) \ +do { \ + bit_buf <<= (num); \ + bits += (num); \ +} while (0) + +/* take num bits from the high part of bit_buf and zero extend them */ +#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num))) + +/* take num bits from the high part of bit_buf and sign extend them */ +#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num))) + +typedef struct { + uint8_t modes; + uint8_t len; +} MBtab; + +typedef struct { + uint8_t delta; + uint8_t len; +} MVtab; + +typedef struct { + int8_t dmv; + uint8_t len; +} DMVtab; + +typedef struct { + uint8_t cbp; + uint8_t len; +} CBPtab; + +typedef struct { + uint8_t size; + uint8_t len; +} DCtab; + +typedef struct { + uint8_t run; + uint8_t level; + uint8_t len; +} DCTtab; + +typedef struct { + uint8_t mba; + uint8_t len; +} MBAtab; + + +#define INTRA MACROBLOCK_INTRA +#define QUANT MACROBLOCK_QUANT + +static const MBtab MB_I [] = { + {INTRA|QUANT, 2}, {INTRA, 1} +}; + +#define MC MACROBLOCK_MOTION_FORWARD +#define CODED MACROBLOCK_PATTERN + +static const MBtab MB_P [] = { + {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, + {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} +}; + +#define FWD MACROBLOCK_MOTION_FORWARD +#define BWD MACROBLOCK_MOTION_BACKWARD +#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD + +static const MBtab MB_B [] = { + {0, 0}, {INTRA|QUANT, 6}, + {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, + {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, + {INTRA, 5}, {INTRA, 5}, + {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, + {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} +}; + +#undef INTRA +#undef QUANT +#undef MC +#undef CODED +#undef FWD +#undef BWD +#undef INTER + + +static const MVtab MV_4 [] = { + { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} +}; + +static const MVtab MV_10 [] = { + { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, + { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, + {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, + { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, + { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, + { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} +}; + + +static const DMVtab DMV_2 [] = { + { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} +}; + + +static const CBPtab CBP_7 [] = { + {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7}, + {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7}, + {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6}, + {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6}, + {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, + {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, + {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, + {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, + {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, + {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, + {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, + {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, + {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, + {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, + {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, + {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3} +}; + +static const CBPtab CBP_9 [] = { + {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9}, + {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9}, + {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8}, + {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8}, + {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8}, + {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8}, + {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8}, + {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8}, + {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8}, + {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8}, + {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8}, + {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8}, + {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8}, + {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8}, + {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8}, + {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8} +}; + + +static const DCtab DC_lum_5 [] = { + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} +}; + +static const DCtab DC_chrom_5 [] = { + {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5} +}; + +static const DCtab DC_long [] = { + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, + {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} +}; + + +static const DCTtab DCT_16 [] = { + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, + { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0}, + { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0}, + { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0}, + { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0} +}; + +static const DCTtab DCT_15 [] = { + { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, + { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, + { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, + { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, + { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, + { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, + { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, + { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, + { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, + { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, + { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, + { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} +}; + +static const DCTtab DCT_13 [] = { + { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, + { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, + { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, + { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, + { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, + { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, + { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, + { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, + { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, + { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, + { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, + { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} +}; + +static const DCTtab DCT_B14_10 [] = { + { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, + { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} +}; + +static const DCTtab DCT_B14_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, + { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, + { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, + { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, + { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} +}; + +static const DCTtab DCT_B14AC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} +}; + +static const DCTtab DCT_B14DC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1} +}; + +static const DCTtab DCT_B15_10 [] = { + { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, + { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} +}; + +static const DCTtab DCT_B15_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, + { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, + { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, + { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, + { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, + { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, + { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, + { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} +}; + + +static const MBAtab MBA_5 [] = { + {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} +}; + +static const MBAtab MBA_11 [] = { + {32, 11}, {31, 11}, {30, 11}, {29, 11}, + {28, 11}, {27, 11}, {26, 11}, {25, 11}, + {24, 11}, {23, 11}, {22, 11}, {21, 11}, + {20, 10}, {20, 10}, {19, 10}, {19, 10}, + {18, 10}, {18, 10}, {17, 10}, {17, 10}, + {16, 10}, {16, 10}, {15, 10}, {15, 10}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7} +}; diff --git a/vldp2/libvo/Makefile.am b/vldp2/libvo/Makefile.am new file mode 100644 index 000000000..36213dd90 --- /dev/null +++ b/vldp2/libvo/Makefile.am @@ -0,0 +1,8 @@ +AM_CFLAGS = @LIBVO_CFLAGS@ + +noinst_LIBRARIES = libvo.a +libvo_a_SOURCES = video_out.c video_out_x11.c video_out_dx.c video_out_sdl.c \ + video_out_null.c video_out_pgm.c \ + yuv2rgb.c yuv2rgb_mlib.c yuv2rgb_mmx.c + +EXTRA_DIST = configure.incl convert_internal.h hw_bes.h diff --git a/vldp2/libvo/Makefile.in b/vldp2/libvo/Makefile.in new file mode 100644 index 000000000..7f51d24f3 --- /dev/null +++ b/vldp2/libvo/Makefile.in @@ -0,0 +1,433 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +AM_CFLAGS = @LIBVO_CFLAGS@ + +noinst_LIBRARIES = libvo.a +libvo_a_SOURCES = video_out.c video_out_x11.c video_out_dx.c video_out_sdl.c \ + video_out_null.c video_out_pgm.c \ + yuv2rgb.c yuv2rgb_mlib.c yuv2rgb_mmx.c + + +EXTRA_DIST = configure.incl convert_internal.h hw_bes.h +subdir = libvo +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +libvo_a_AR = $(AR) cru +libvo_a_LIBADD = +am_libvo_a_OBJECTS = video_out.$(OBJEXT) video_out_x11.$(OBJEXT) \ + video_out_dx.$(OBJEXT) video_out_sdl.$(OBJEXT) \ + video_out_null.$(OBJEXT) video_out_pgm.$(OBJEXT) \ + yuv2rgb.$(OBJEXT) yuv2rgb_mlib.$(OBJEXT) yuv2rgb_mmx.$(OBJEXT) +libvo_a_OBJECTS = $(am_libvo_a_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/video_out.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_out_dx.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_out_null.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_out_pgm.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_out_sdl.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_out_x11.Po ./$(DEPDIR)/yuv2rgb.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/yuv2rgb_mlib.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/yuv2rgb_mmx.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(libvo_a_SOURCES) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(libvo_a_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libvo/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +AR = ar + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libvo.a: $(libvo_a_OBJECTS) $(libvo_a_DEPENDENCIES) + -rm -f libvo.a + $(libvo_a_AR) libvo.a $(libvo_a_OBJECTS) $(libvo_a_LIBADD) + $(RANLIB) libvo.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_dx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_pgm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_sdl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_x11.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yuv2rgb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yuv2rgb_mlib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yuv2rgb_mmx.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/libvo/configure.incl b/vldp2/libvo/configure.incl new file mode 100644 index 000000000..59408e606 --- /dev/null +++ b/vldp2/libvo/configure.incl @@ -0,0 +1,59 @@ +AC_SUBST([LIBVO_CFLAGS]) +AC_SUBST([LIBVO_LIBS]) + +dnl check for X11 +AC_PATH_XTRA +if test x"$no_x" != x"yes"; then + dnl check for Xshm + AC_CHECK_LIB([Xext],[XShmCreateImage], + [AC_DEFINE([LIBVO_X11],,[libvo X11 support]) + LIBVO_CFLAGS="$LIBVO_CFLAGS $X_CFLAGS" + LIBVO_LIBS="$LIBVO_LIBS $X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext" + dnl check for Xv + AC_CHECK_LIB([Xv],[XvShmCreateImage], + [AC_DEFINE([LIBVO_XV],,[libvo Xv support]) + LIBVO_LIBS="$LIBVO_LIBS -lXv"],, + [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS -lXext])],, + [$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS]) +fi + +dnl check for DirectX +AC_ARG_ENABLE([directx], + [ --enable-directx=DIR use Win32 DirectX headers in DIR]) +case $enable_directx in + ""|yes) AC_CHECK_HEADERS([ddraw.h], + [AC_DEFINE([LIBVO_DX],,[libvo DirectX support]) + LIBVO_LIBS="$LIBVO_LIBS -lgdi32"]);; + no) ;; + *) if test -f "$enable_directx/ddraw.h"; then + AC_DEFINE([LIBVO_DX],,[libvo DirectX support]) + LIBVO_CFLAGS="$LIBVO_CFLAGS -I$enable_directx" + LIBVO_LIBS="$LIBVO_LIBS -lgdi32" + else + AC_MSG_ERROR([Cannot find $enable_directx/ddraw.h]) + fi;; +esac + +dnl check for mlib +AC_ARG_ENABLE([mlib], + [ --disable-mlib make a version not using mediaLib]) +if test x"$enable_mlib" != x"no"; then + cflags_save="$CFLAGS" + CFLAGS="$CFLAGS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib" + AC_CHECK_LIB([mlib],[mlib_VideoColorYUV2RGB420], + [AC_DEFINE([LIBVO_MLIB],,[libvo mediaLib support]) + LIBVO_CFLAGS="$LIBVO_CFLAGS -I/opt/SUNWmlib/include" + LIBVO_LIBS="$LIBVO_LIBS -L/opt/SUNWmlib/lib -R/opt/SUNWmlib/lib -lmlib"]) + CFLAGS="$cflags_save" +fi + +dnl check for SDL +AC_ARG_ENABLE([sdl],[ --disable-sdl make a version not using SDL]) +if test x"$enable_sdl" != x"no"; then + AC_CHECK_PROG([SDLCONFIG],[sdl-config],[yes]) + if test x"$SDLCONFIG" = x"yes"; then + AC_DEFINE([LIBVO_SDL],,[libvo SDL support]) + LIBVO_CFLAGS="$LIBVO_CFLAGS `sdl-config --cflags`" + LIBVO_LIBS="$LIBVO_LIBS `sdl-config --libs`" + fi +fi diff --git a/vldp2/libvo/convert_internal.h b/vldp2/libvo/convert_internal.h new file mode 100644 index 000000000..8cadc6a84 --- /dev/null +++ b/vldp2/libvo/convert_internal.h @@ -0,0 +1,38 @@ +/* + * convert_internal.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +typedef struct { + uint8_t * rgb_ptr; + int width; + int uv_stride, uv_stride_frame; + int rgb_stride, rgb_stride_frame; + void (* yuv2rgb) (uint8_t *, uint8_t *, uint8_t *, uint8_t *, + void *, void *, int); +} convert_rgb_t; + +typedef void yuv2rgb_copy (void * id, uint8_t * const * src, + unsigned int v_offset); + +yuv2rgb_copy * yuv2rgb_init_mmxext (int bpp, int mode); +yuv2rgb_copy * yuv2rgb_init_mmx (int bpp, int mode); +yuv2rgb_copy * yuv2rgb_init_mlib (int bpp, int mode); diff --git a/vldp2/libvo/hw_bes.h b/vldp2/libvo/hw_bes.h new file mode 100644 index 000000000..fbaf70131 --- /dev/null +++ b/vldp2/libvo/hw_bes.h @@ -0,0 +1,50 @@ +/* + * hw_bes.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_HW_BES_H +#define __LINUX_HW_BES_H + +typedef struct { + uint32_t card_type; + uint32_t ram_size; + uint32_t src_width; + uint32_t src_height; + uint32_t dest_width; + uint32_t dest_height; + uint32_t x_org; + uint32_t y_org; + uint8_t colkey_on; + uint8_t colkey_red; + uint8_t colkey_green; + uint8_t colkey_blue; +} mga_vid_config_t; + +#define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t) +#define MGA_VID_ON _IO ('J', 2) +#define MGA_VID_OFF _IO ('J', 3) +#define MGA_VID_FSEL _IOR('J', 4, int) + +#define MGA_G200 0x1234 +#define MGA_G400 0x5678 + +#endif diff --git a/vldp2/libvo/video_out.c b/vldp2/libvo/video_out.c new file mode 100644 index 000000000..b4cd589ec --- /dev/null +++ b/vldp2/libvo/video_out.c @@ -0,0 +1,54 @@ +/* + * video_out.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "video_out.h" + +/* Externally visible list of all vo drivers */ + +extern vo_open_t vo_xv_open; +extern vo_open_t vo_x11_open; +extern vo_open_t vo_dxrgb_open; +extern vo_open_t vo_dx_open; +extern vo_open_t vo_sdl_open; +extern vo_open_t vo_null_open; +extern vo_open_t vo_nullslice_open; +extern vo_open_t vo_nullrgb16_open; +extern vo_open_t vo_nullrgb32_open; +extern vo_open_t vo_pgm_open; +extern vo_open_t vo_pgmpipe_open; +extern vo_open_t vo_md5_open; + +static vo_driver_t video_out_drivers[] = { + {"null", vo_null_open}, + {NULL, NULL} +}; + +vo_driver_t * vo_drivers (void) +{ + return video_out_drivers; +} diff --git a/vldp2/libvo/video_out_dx.c b/vldp2/libvo/video_out_dx.c new file mode 100644 index 000000000..deddbaa80 --- /dev/null +++ b/vldp2/libvo/video_out_dx.c @@ -0,0 +1,520 @@ +/* + * video_out_dx.c + * Copyright (C) 2000-2002 Michel Lespinasse + * + * Contributed by Gildas Bazin + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBVO_DX + +#include +#include +#include +#include + +#include "video_out.h" +#include "convert.h" + +#include +#include + +#define USE_OVERLAY_TRIPLE_BUFFERING 0 + +/* + * DirectDraw GUIDs. + * Defining them here allows us to get rid of the dxguid library during link. + */ +DEFINE_GUID (IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56); +DEFINE_GUID (IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27); + +#define FOURCC_YV12 0x32315659 + +typedef struct { + vo_instance_t vo; + int width; + int height; + + HWND window; + RECT window_coords; + HINSTANCE hddraw_dll; + LPDIRECTDRAW2 ddraw; + LPDIRECTDRAWSURFACE2 display; + LPDIRECTDRAWCLIPPER clipper; + LPDIRECTDRAWSURFACE2 frame[3]; + int index; + + LPDIRECTDRAWSURFACE2 overlay; + uint8_t * yuv[3]; + int stride; +} dx_instance_t; + +static void update_overlay (dx_instance_t * instance) +{ + DDOVERLAYFX ddofx; + DWORD dwFlags; + + memset (&ddofx, 0, sizeof (DDOVERLAYFX)); + ddofx.dwSize = sizeof (DDOVERLAYFX); + dwFlags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE; + IDirectDrawSurface2_UpdateOverlay (instance->overlay, NULL, + instance->display, + &instance->window_coords, + dwFlags, &ddofx); +} + +static long FAR PASCAL event_procedure (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + RECT rect_window; + POINT point_window; + dx_instance_t * instance; + + switch (message) { + + case WM_WINDOWPOSCHANGED: + instance = (dx_instance_t *) GetWindowLong (hwnd, GWL_USERDATA); + + /* update the window position and size */ + point_window.x = 0; + point_window.y = 0; + ClientToScreen (hwnd, &point_window); + instance->window_coords.left = point_window.x; + instance->window_coords.top = point_window.y; + GetClientRect (hwnd, &rect_window); + instance->window_coords.right = rect_window.right + point_window.x; + instance->window_coords.bottom = rect_window.bottom + point_window.y; + + /* update the overlay */ + if (instance->overlay && instance->display) + update_overlay (instance); + + return 0; + + case WM_CLOSE: /* forbid the user to close the window */ + return 0; + + case WM_DESTROY: /* just destroy the window */ + PostQuitMessage (0); + return 0; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + +static void check_events (dx_instance_t * instance) +{ + MSG msg; + + while (PeekMessage (&msg, instance->window, 0, 0, PM_REMOVE)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} + +static int create_window (dx_instance_t * instance) +{ + RECT rect_window; + WNDCLASSEX wc; + + wc.cbSize = sizeof (WNDCLASSEX); + wc.style = CS_DBLCLKS; + wc.lpfnWndProc = (WNDPROC) event_procedure; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle (NULL); + wc.hIcon = NULL; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = CreateSolidBrush (RGB (0, 0, 0)); + wc.lpszMenuName = NULL; + wc.lpszClassName = "libvo_dx"; + wc.hIconSm = NULL; + if (!RegisterClassEx (&wc)) { + fprintf (stderr, "Can not register window class\n"); + return 1; + } + + rect_window.top = 10; + rect_window.left = 10; + rect_window.right = rect_window.left + instance->width; + rect_window.bottom = rect_window.top + instance->height; + AdjustWindowRect (&rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0); + + instance->window = CreateWindow ("libvo_dx", "mpeg2dec", + WS_OVERLAPPEDWINDOW | WS_SIZEBOX, + CW_USEDEFAULT, 0, + rect_window.right - rect_window.left, + rect_window.bottom - rect_window.top, + NULL, NULL, GetModuleHandle (NULL), NULL); + if (instance->window == NULL) { + fprintf (stderr, "Can not create window\n"); + return 1; + } + + /* store a directx_instance pointer into the window local storage + * (for later use in event_handler). + * We need to use SetWindowLongPtr when it is available in mingw */ + SetWindowLong (instance->window, GWL_USERDATA, (LONG) instance); + + ShowWindow (instance->window, SW_SHOW); + + return 0; +} + +static LPDIRECTDRAWSURFACE2 alloc_surface (dx_instance_t * instance, + DDSURFACEDESC * ddsd) +{ + LPDIRECTDRAWSURFACE surface; + LPDIRECTDRAWSURFACE2 surface2; + + if (DD_OK != IDirectDraw2_CreateSurface (instance->ddraw, ddsd, + &surface, NULL) || + DD_OK != IDirectDrawSurface_QueryInterface (surface, + &IID_IDirectDrawSurface2, + (LPVOID *) &surface2)) { + fprintf (stderr, "Can not create directDraw frame surface\n"); + return NULL; + } + IDirectDrawSurface_Release (surface); + + return surface2; +} + +static int dx_init (dx_instance_t *instance) +{ + HRESULT (WINAPI * OurDirectDrawCreate) (GUID *, LPDIRECTDRAW *, + IUnknown *); + LPDIRECTDRAW ddraw; + DDSURFACEDESC ddsd; + + /* load direct draw DLL */ + instance->hddraw_dll = LoadLibrary ("DDRAW.DLL"); + if (instance->hddraw_dll == NULL) { + fprintf (stderr, "Can not load DDRAW.DLL\n"); + return 1; + } + + ddraw = NULL; + OurDirectDrawCreate = (void *) GetProcAddress (instance->hddraw_dll, + "DirectDrawCreate"); + if (OurDirectDrawCreate == NULL || + DD_OK != OurDirectDrawCreate (NULL, &ddraw, NULL) || + DD_OK != IDirectDraw_QueryInterface (ddraw, &IID_IDirectDraw2, + (LPVOID *) &instance->ddraw) || + DD_OK != IDirectDraw_SetCooperativeLevel (instance->ddraw, + instance->window, + DDSCL_NORMAL)) { + fprintf (stderr, "Can not initialize directDraw interface\n"); + return 1; + } + IDirectDraw_Release (ddraw); + + memset (&ddsd, 0, sizeof (DDSURFACEDESC)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + instance->display = alloc_surface (instance, &ddsd); + if (instance->display == NULL) { + fprintf (stderr, "Can not create directDraw display surface\n"); + return 1; + } + + if (DD_OK != IDirectDraw2_CreateClipper (instance->ddraw, 0, + &instance->clipper, NULL) || + DD_OK != IDirectDrawClipper_SetHWnd (instance->clipper, 0, + instance->window) || + DD_OK != IDirectDrawSurface_SetClipper (instance->display, + instance->clipper)) { + fprintf (stderr, "Can not initialize directDraw clipper\n"); + return 1; + } + + return 0; +} + +static int common_setup (dx_instance_t * instance, int width, int height) +{ + instance->width = width; + instance->height = height; + instance->index = 0; + + if (create_window (instance) || dx_init (instance)) + return 1; + return 0; +} + +static int dxrgb_setup (vo_instance_t * _instance, int width, int height, + vo_setup_result_t * result) +{ + dx_instance_t * instance = (dx_instance_t *) _instance; + HDC hdc; + int bpp; + + if (common_setup (instance, width, height)) + return 1; + + hdc = GetDC (NULL); + bpp = GetDeviceCaps (hdc, BITSPIXEL); + ReleaseDC (NULL, hdc); + + result->convert = convert_rgb (CONVERT_RGB, bpp); + return 0; +} + +static LPDIRECTDRAWSURFACE2 alloc_frame (dx_instance_t * instance) +{ + DDSURFACEDESC ddsd; + LPDIRECTDRAWSURFACE2 surface; + + memset (&ddsd, 0, sizeof (DDSURFACEDESC)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); + ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; + ddsd.dwHeight = instance->height; + ddsd.dwWidth = instance->width; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + + surface = alloc_surface (instance, &ddsd); + if (surface == NULL) + fprintf (stderr, "Can not create directDraw frame surface\n"); + return surface; +} + +static void * surface_addr (LPDIRECTDRAWSURFACE2 surface, int * stride) +{ + DDSURFACEDESC ddsd; + + memset (&ddsd, 0, sizeof (DDSURFACEDESC)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + IDirectDrawSurface2_Lock (surface, NULL, &ddsd, + DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); + IDirectDrawSurface2_Unlock (surface, NULL); + *stride = ddsd.lPitch; + return ddsd.lpSurface; +} + +static void dx_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + dx_instance_t * instance = (dx_instance_t *) _instance; + int stride; + + *id = instance->frame[instance->index++] = alloc_frame (instance); + buf[0] = surface_addr (*id, &stride); + buf[1] = NULL; buf[2] = NULL; +} + +static void dxrgb_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + dx_instance_t * instance = (dx_instance_t *) _instance; + LPDIRECTDRAWSURFACE2 surface = (LPDIRECTDRAWSURFACE2) id; + DDBLTFX ddbltfx; + + check_events (instance); + + memset (&ddbltfx, 0, sizeof (DDBLTFX)); + ddbltfx.dwSize = sizeof (DDBLTFX); + ddbltfx.dwDDFX = DDBLTFX_NOTEARING; + if (DDERR_SURFACELOST == + IDirectDrawSurface2_Blt (instance->display, &instance->window_coords, + surface, NULL, DDBLT_WAIT, &ddbltfx)) { + /* restore surface and try again */ + IDirectDrawSurface2_Restore (instance->display); + IDirectDrawSurface2_Blt (instance->display, &instance->window_coords, + surface, NULL, DDBLT_WAIT, &ddbltfx); + } +} + +static vo_instance_t * common_open (int (* setup) (vo_instance_t *, int, int, + vo_setup_result_t *), + void (* setup_fbuf) (vo_instance_t *, + uint8_t **, void **), + void (* draw) (vo_instance_t *, + uint8_t * const *, + void * id)) +{ + dx_instance_t * instance; + + instance = malloc (sizeof (dx_instance_t)); + if (instance == NULL) + return NULL; + + memset (instance, 0, sizeof (dx_instance_t)); + instance->vo.setup = setup; + instance->vo.setup_fbuf = setup_fbuf; + instance->vo.set_fbuf = NULL; + instance->vo.start_fbuf = NULL; + instance->vo.draw = draw; + instance->vo.discard = NULL; + instance->vo.close = NULL; //dx_close; + + return (vo_instance_t *) instance; +} + +vo_instance_t * vo_dxrgb_open (void) +{ + return common_open (dxrgb_setup, dx_setup_fbuf, dxrgb_draw_frame); +} + +static LPDIRECTDRAWSURFACE2 alloc_overlay (dx_instance_t * instance) +{ + DDSURFACEDESC ddsd; + LPDIRECTDRAWSURFACE2 surface; + + memset (&ddsd, 0, sizeof (DDSURFACEDESC)); + ddsd.dwSize = sizeof (DDSURFACEDESC); + ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); + ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS; + ddsd.dwHeight = instance->height; + ddsd.dwWidth = instance->width; + ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; + ddsd.ddpfPixelFormat.dwFourCC = FOURCC_YV12; + ddsd.dwFlags |= DDSD_PIXELFORMAT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; +#if USE_OVERLAY_TRIPLE_BUFFERING + ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; +#endif + ddsd.dwBackBufferCount = 2; + + surface = alloc_surface (instance, &ddsd); + if (surface == NULL) + fprintf (stderr, "Can not create directDraw frame surface\n"); + return surface; +} + +static int dx_setup (vo_instance_t * _instance, int width, int height, + vo_setup_result_t * result) +{ + dx_instance_t * instance = (dx_instance_t *) _instance; + LPDIRECTDRAWSURFACE2 surface; + DDSURFACEDESC ddsd; + + if (common_setup (instance, width, height)) + return 1; + + instance->overlay = alloc_overlay (instance); + if (!instance->overlay) + return 1; + update_overlay (instance); + + surface = instance->overlay; + + /* Get the back buffer */ + memset (&ddsd.ddsCaps, 0, sizeof (DDSCAPS)); + ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; + if (DD_OK != IDirectDrawSurface2_GetAttachedSurface (instance->overlay, + &ddsd.ddsCaps, + &surface)) + surface = instance->overlay; + + instance->yuv[0] = surface_addr (surface, &instance->stride); + instance->yuv[2] = instance->yuv[0] + instance->stride * instance->height; + instance->yuv[1] = + instance->yuv[2] + (instance->stride * instance->height >> 2); + + result->convert = NULL; + return 0; +} + +static void copy_yuv_picture (dx_instance_t * instance, + uint8_t * const * buf, void * id) +{ + uint8_t * dest[3]; + int width, i; + + dest[0] = instance->yuv[0]; + dest[1] = instance->yuv[1]; + dest[2] = instance->yuv[2]; + + width = instance->width; + for (i = 0; i < instance->height >> 1; i++) { + memcpy (dest[0], buf[0] + 2 * i * width, width); + dest[0] += instance->stride; + memcpy (dest[0], buf[0] + (2 * i + 1) * width, width); + dest[0] += instance->stride; + memcpy (dest[1], buf[1] + i * (width >> 1), width >> 1); + dest[1] += instance->stride >> 1; + memcpy (dest[2], buf[2] + i * (width >> 1), width >> 1); + dest[2] += instance->stride >> 1; + } +} + +static void dx_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + dx_instance_t * instance = (dx_instance_t *) _instance; + + check_events (instance); + + copy_yuv_picture (instance, buf, id); + + if (DDERR_SURFACELOST == + IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT)) { + /* restore surfaces and try again */ + IDirectDrawSurface2_Restore (instance->display); + IDirectDrawSurface2_Restore (instance->overlay); + IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT); + } +} + +vo_instance_t * vo_dx_open (void) +{ + return common_open (dx_setup, NULL, dx_draw_frame); +} + +#if 0 +static void dx_close (vo_instance_t * _instance) +{ + dx_instance_t * instance; + int i; + + instance = (dx_instance_t *) _instance; + + if (instance->using_overlay && instance->overlay) { + IDirectDrawSurface2_Release (instance->overlay); + instance->overlay = NULL; + } else + for (i = 0; i < 3; i++) { + if (instance->frame[i].p_surface != NULL) + IDirectDrawSurface2_Release (instance->frame[i].p_surface); + instance->frame[i].p_surface = NULL; + } + + if (instance->clipper != NULL) + IDirectDrawClipper_Release (instance->clipper); + + if (instance->display != NULL) + IDirectDrawSurface2_Release (instance->display); + + if (instance->ddraw != NULL) + IDirectDraw2_Release (instance->ddraw); + + if (instance->hddraw_dll != NULL) + FreeLibrary (instance->hddraw_dll); + + if (instance->window != NULL) + DestroyWindow (instance->window); +} + +#endif +#endif diff --git a/vldp2/libvo/video_out_null.c b/vldp2/libvo/video_out_null.c new file mode 100644 index 000000000..aa09cf69d --- /dev/null +++ b/vldp2/libvo/video_out_null.c @@ -0,0 +1,359 @@ +/* + * video_out_null.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include + +#include "video_out.h" +#include "convert.h" + +// start MPO + +#include // for memset +#include "../vldp/vldp_common.h" // to get access to g_in_info struct and the yuv_buf struct +#include "../vldp/vldp_internal.h" // for access to s_ variables from vldp_internal + +#define YUV_BUF_COUNT 3 // libmpeg2 needs 3 buffers to do its thing ... +struct yuv_buf g_yuv_buf[YUV_BUF_COUNT]; + +//// + +static void null_draw_frame (vo_instance_t *instance, uint8_t * const * buf, void *id) +{ + Sint32 correct_elapsed_ms = 0; // we want this signed since we compare against actual_elapsed_ms + Sint32 actual_elapsed_ms = 0; // we want this signed because it could be negative + unsigned int uStallFrames = 0; // how many frames we have to stall during the loop (for multi-speed playback) + + // if we don't need to skip any frames + if (!(s_frames_to_skip | s_skip_all)) + { + // loop once, or more than once if we are paused + do + { + VLDP_BOOL bFrameNotShownDueToCmd = VLDP_FALSE; + +#ifndef VLDP_BENCHMARK + // PERFORMANCE WARNING: + // We need to use 64-bit math here because otherwise, we will overflow a little after 2 minutes, + // using 32-bit math. + // If you want to assume that you will never be playing video longer than 2 minutes, then you can change this back + // to 32-bit integer math. + // Also, you can use floating point math here, but some CPU's (gp2x) don't have floating point units, which drastically + // hurts performance. On a fast modern PC, you probably won't notice a difference either way. + Sint64 s64Ms = s_uFramesShownSinceTimer; + s64Ms = (s64Ms * 1000000) / g_out_info.uFpks; + + // compute how much time ought to have elapsed based on our frame count + correct_elapsed_ms = (Sint32) (s64Ms) + + // add on any extra delay that has been requested (simulated seek delay) + s_extra_delay_ms; + actual_elapsed_ms = g_in_info->uMsTimer - s_timer; + + // the extra delay should only be 'used' once, so for safety reasons we reset + // it here, where we can guarantee that it only will be used once. + s_extra_delay_ms = 0; + + // if we are caught up enough that we don't need to skip any frames, then display the frame + if (actual_elapsed_ms < (correct_elapsed_ms + g_out_info.u2milDivFpks)) + { +#endif + // this is the potentially expensive callback that gets the hardware overlay + // ready to be displayed, so we do this before we sleep + // NOTE : if this callback fails, we don't want to display the frame due to double buffering considerations + if (g_in_info->prepare_frame(&g_yuv_buf[(int) id])) + { +#ifndef VLDP_BENCHMARK + + // stall if we are playing too quickly and if we don't have a command waiting for us + while (((Sint32) (g_in_info->uMsTimer - s_timer) < correct_elapsed_ms) + && (!bFrameNotShownDueToCmd)) + { + // IMPORTANT: this delay should come before the check for ivldp_got_new_command, + // so that if we get a new command, we exit the loop immediately without + // delaying, so that we don't have to check a second time for a new command. + SDL_Delay(1); // note, if this is set to 0, we don't get commands as quickly + + // Breaking when getting a new commend before our frame has expired + // will shorten 1 frame's length. However, it could speed skips up, + // so I am leaving it in. + // Also, if we get a new command, uMsTimer may not advance until + // we acknowledge the new command. + if (ivldp_got_new_command()) + { + // strip off count and examine command + switch(g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_PAUSE: + case VLDP_REQ_STEP_FORWARD: + ivldp_respond_req_pause_or_step(); + break; + case VLDP_REQ_SPEEDCHANGE: + ivldp_respond_req_speedchange(); + break; + case VLDP_REQ_NONE: + break; + + // Anything else, we will not show the next frame and will + // immediately exit this loop in order to handle the command + // elsewhere. + default: + bFrameNotShownDueToCmd = VLDP_TRUE; + break; + } + } + } + + // If a command comes in at the last second, + // we don't want to render the next frame that we were going to because it could cause overrun + // so we only display the frame if we haven't received a command + if (!bFrameNotShownDueToCmd) + { +#endif + // draw the frame + // we are using the pointer 'id' as an index, kind of risky, but convenient :) + g_in_info->display_frame(&g_yuv_buf[(int) id]); +#ifndef VLDP_BENCHMARK + } // end if we didn't get a new command to interrupt the frame being displayed +#endif + } // end if the frame was prepared properly +#ifndef VLDP_BENCHMARK + // else maybe we couldn't get a lock on the buffer fast enough, so we'll have to wait ... + + } // end if we don't drop any frames + + /* + // else we're too far beyond so we're gonna have to drop some this frame to catch up (doh!) + else + { + fprintf(stderr, "NOTE : dropped frame %u! Expected %u but got %u\n", + g_out_info.current_frame, correct_elapsed_ms, actual_elapsed_ms); + } + */ + +#endif + // if the frame was either displayed or dropped (due to lag) ... + if (!bFrameNotShownDueToCmd) + { + // now that the frame has either been displayed or dropped, we can update the counter to reflect + // NOTE : this should come before play_handler() is called, because if we become paused, + // we change the value of s_uFramesShownSinceTimer. + ++s_uFramesShownSinceTimer; + } + + // if the frame is to be paused, then stall + if (s_paused) + { + paused_handler(); + } + // else if we are supposed to be playing + else + { + play_handler(); + + // We only want to advance the current frame if we didn't receive a pause request in the play handler. + // NOTE : this should come after the handlers in case the state of s_paused changes + if (!s_paused) + { + // If we aren't going to stall on any frames ... + // NOTE : I think this should be toward the outside of this loop, because + // if we are skipping while playing at a slower speed, I would think that + // the skip should be slower too. I could be wrong though ... + // We DO want to make sure that if we are stalling, that the current frame + // is not incremented. + if (uStallFrames == 0) + { + // if we have no pending frame, then the frame we've just displayed is the proceeding frame + if (s_uPendingSkipFrame == 0) + { + // only advance frame # if we've displayed/dropped a frame + if (!bFrameNotShownDueToCmd) + { + ++g_out_info.current_frame; + + // if we have to stall one or more frames per frame (multi-speed playback) + if (s_stall_per_frame > 0) + { + uStallFrames = s_stall_per_frame; + } + + // if we are skipping one or more frames per frame that is displayed + // (multi-speed playback) + if (s_skip_per_frame > 0) + { + s_frames_to_skip = s_frames_to_skip_with_inc = s_skip_per_frame; + } + // else don't adjust the frameskip variables + } + // else don't advance the frame number + } + // else we just skipped, so update current frame to reflect that ... + else + { + g_out_info.current_frame = s_uPendingSkipFrame; + s_uPendingSkipFrame = 0; + } + } // end if we aren't going to stall on the currently rendered frame + // else don't increment the frame, but decrement the uStallFrames counter + else + { + --uStallFrames; + } + } + } + + } while ((s_paused || uStallFrames > 0) && !s_skip_all && !s_step_forward); + // loop while we are paused OR while we are stalling so video overlay gets redrawn + + s_step_forward = 0; // clear this in case it was set (since we have now stepped forward) + + } // end if we don't have frames to skip + + // if we have frames to skip + else + { + // we could skip frames for another reason + if (s_frames_to_skip > 0) + { + --s_frames_to_skip; // we've skipped a frame, so decrease the count + + // if we need to also increase the frame number (multi-speed playback) + if (s_frames_to_skip_with_inc > 0) + { + --s_frames_to_skip_with_inc; + ++g_out_info.current_frame; + } + } + } + +#ifdef VLDP_DEBUG + // if we're dropping all frames, log it + if (s_skip_all) + { + s_uSkipAllCount++; + } +#endif // VLDP_DEBUG + +#ifndef VLDP_BENCHMARK + // WARNING : by putting this delay here, we are slowing down seek speed (s_skip_all and s_frames_to_skip!!!) + // Maybe it would be better to remove this??? What would be impacted? Why did I put this here in the first place? + // My comment wasn't very informative :) + + // UPDATE : this SDL_Delay seems harmful to me and doesn't seem to help, so I've commented it out to see if anything + // bad happens as a result :) +// SDL_Delay(0); +#endif + + // end MATT +} + +static void null_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + static buffer_index = 0; + *id = (int *) buffer_index; // THIS IS A LITTLE TRICKY + // We are setting an integer value to a pointer ... + // Because it is convenient to let the pointer hold the value of this integer for us + // Hopefully it doesn't cause any trouble later ;) + + buf[0] = g_yuv_buf[buffer_index].Y; + buf[1] = g_yuv_buf[buffer_index].U; + buf[2] = g_yuv_buf[buffer_index].V; + + buffer_index++; + + // we are operating under a (safe?) assumption that this function is called in sets of YUV_BUF_COUNT + // so it should be safe to wraparound ... if our assumption is wrong, major havoc will ensure :) + if (buffer_index >= YUV_BUF_COUNT) + { + buffer_index = 0; + } + +} + +static int null_setup (vo_instance_t * instance, int width, int height, + vo_setup_result_t * result) +{ + int i = 0; + + // UPDATE : I believe these functions are no longer necessary because we do them in + // idle_handler_open() now instead. + /* + g_in_info->report_mpeg_dimensions(width, height); // alert parent-thread + g_out_info.w = width; + g_out_info.h = height; + */ + + for (i = 0; i < YUV_BUF_COUNT; i++) + { + // allocate buffer according to size of picture + // We do not re-allocate these buffers if they have already been previous allocated, as a safety measure + g_yuv_buf[i].Y_size = width * height; + g_yuv_buf[i].UV_size = g_yuv_buf[i].Y_size >> 2; + if (!g_yuv_buf[i].Y) g_yuv_buf[i].Y = malloc(g_yuv_buf[i].Y_size); + if (!g_yuv_buf[i].U) g_yuv_buf[i].U = malloc(g_yuv_buf[i].UV_size); + if (!g_yuv_buf[i].V) g_yuv_buf[i].V = malloc(g_yuv_buf[i].UV_size); + } + + result->convert = NULL; + return 0; +} + +static void null_close (vo_instance_t *instance) +{ + int i = 0; + + for (i = 0; i < YUV_BUF_COUNT; i++) + { + // NOTE : it's ok to call free(NULL) so we do not need to do safety checking here! + free(g_yuv_buf[i].Y); + g_yuv_buf[i].Y = NULL; + free(g_yuv_buf[i].U); + g_yuv_buf[i].U = NULL; + free(g_yuv_buf[i].V); + g_yuv_buf[i].V = NULL; + } +} + +vo_instance_t * vo_null_open () +{ + vo_instance_t * instance; + + instance = (vo_instance_t *) malloc (sizeof (vo_instance_t)); + if (instance == NULL) + return NULL; + + instance->setup = null_setup; // MPO + instance->setup_fbuf = null_setup_fbuf; // MPO + instance->set_fbuf = NULL; + instance->start_fbuf = NULL; + instance->draw = null_draw_frame; + instance->discard = NULL; + instance->close = null_close; // MPO + memset(g_yuv_buf, 0, sizeof(g_yuv_buf)); // MPO, fill this struct with 0's so that we can track whether mem has been allocated or not + + return instance; +} + +// end MPO diff --git a/vldp2/libvo/video_out_pgm.c b/vldp2/libvo/video_out_pgm.c new file mode 100644 index 000000000..0076a0375 --- /dev/null +++ b/vldp2/libvo/video_out_pgm.c @@ -0,0 +1,142 @@ +/* + * video_out_pgm.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "video_out.h" + +typedef struct { + vo_instance_t vo; + int framenum; + int width; + int height; + char header[1024]; + char filename[128]; +} pgm_instance_t; + +static void internal_draw_frame (pgm_instance_t * instance, + FILE * file, uint8_t * const * buf) +{ + int i; + + fwrite (instance->header, strlen (instance->header), 1, file); + fwrite (buf[0], instance->width, instance->height, file); + for (i = 0; i < instance->height >> 1; i++) { + fwrite (buf[1] + i * (instance->width >> 1), instance->width >> 1, 1, + file); + fwrite (buf[2] + i * (instance->width >> 1), instance->width >> 1, 1, + file); + } +} + +static void pgm_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + pgm_instance_t * instance; + FILE * file; + + instance = (pgm_instance_t *) _instance; + sprintf (instance->filename, "%d.pgm", instance->framenum++); + file = fopen (instance->filename, "wb"); + if (!file) + return; + internal_draw_frame (instance, file, buf); + fclose (file); +} + +static int pgm_setup (vo_instance_t * _instance, int width, int height, + vo_setup_result_t * result) +{ + pgm_instance_t * instance; + + instance = (pgm_instance_t *) _instance; + + instance->width = width; + instance->height = height; + sprintf (instance->header, "P5\n%d %d\n255\n", width, height * 3 / 2); + result->convert = NULL; + return 0; +} + +static vo_instance_t * internal_open (void draw (vo_instance_t *, + uint8_t * const *, void *)) +{ + pgm_instance_t * instance; + + instance = (pgm_instance_t *) malloc (sizeof (pgm_instance_t)); + if (instance == NULL) + return NULL; + + instance->vo.setup = pgm_setup; + instance->vo.setup_fbuf = NULL; + instance->vo.set_fbuf = NULL; + instance->vo.start_fbuf = NULL; + instance->vo.draw = draw; + instance->vo.discard = NULL; + instance->vo.close = NULL; + instance->framenum = 0; + + return (vo_instance_t *) instance; +} + +vo_instance_t * vo_pgm_open (void) +{ + return internal_open (pgm_draw_frame); +} + +static void pgmpipe_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + pgm_instance_t * instance; + + instance = (pgm_instance_t *) _instance; + internal_draw_frame (instance, stdout, buf); +} + +vo_instance_t * vo_pgmpipe_open (void) +{ + return internal_open (pgmpipe_draw_frame); +} + +static void md5_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + pgm_instance_t * instance; + char command[100]; + + instance = (pgm_instance_t *) _instance; + pgm_draw_frame (_instance, buf, id); + sprintf (command, "md5sum -b %s", instance->filename); + system (command); + remove (instance->filename); +} + +vo_instance_t * vo_md5_open (void) +{ + return internal_open (md5_draw_frame); +} diff --git a/vldp2/libvo/video_out_sdl.c b/vldp2/libvo/video_out_sdl.c new file mode 100644 index 000000000..9b72d586d --- /dev/null +++ b/vldp2/libvo/video_out_sdl.c @@ -0,0 +1,165 @@ +/* + * video_out_sdl.c + * + * Copyright (C) 2000-2002 Ryan C. Gordon and + * Dominik Schnitzer + * + * SDL info, source, and binaries can be found at http://www.libsdl.org/ + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBVO_SDL + +#include +#include +#include +#include +#include + +#include "video_out.h" + +typedef struct { + vo_instance_t vo; + int width; + int height; + SDL_Surface * surface; + Uint32 sdlflags; + Uint8 bpp; +} sdl_instance_t; + +static void sdl_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + sdl_instance_t * instance = (sdl_instance_t *) _instance; + SDL_Overlay * overlay; + + *id = overlay = SDL_CreateYUVOverlay (instance->width, instance->height, + SDL_YV12_OVERLAY, instance->surface); + buf[0] = overlay->pixels[0]; + buf[1] = overlay->pixels[2]; + buf[2] = overlay->pixels[1]; +} + +static void sdl_start_fbuf (vo_instance_t * instance, + uint8_t * const * buf, void * id) +{ + SDL_LockYUVOverlay ((SDL_Overlay *) id); +} + +static void sdl_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + sdl_instance_t * instance = (sdl_instance_t *) _instance; + SDL_Overlay * overlay = (SDL_Overlay *) id; + SDL_Event event; + + while (SDL_PollEvent (&event)) + if (event.type == SDL_VIDEORESIZE) + instance->surface = + SDL_SetVideoMode (event.resize.w, event.resize.h, + instance->bpp, instance->sdlflags); + SDL_DisplayYUVOverlay (overlay, &(instance->surface->clip_rect)); +} + +static void sdl_discard (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + SDL_UnlockYUVOverlay ((SDL_Overlay *) id); +} + +#if 0 +static void sdl_close (vo_instance_t * _instance) +{ + sdl_instance_t * instance; + int i; + + instance = (sdl_instance_t *) _instance; + for (i = 0; i < 3; i++) + SDL_FreeYUVOverlay (instance->frame[i].overlay); + SDL_FreeSurface (instance->surface); + SDL_QuitSubSystem (SDL_INIT_VIDEO); +} +#endif + +static int sdl_setup (vo_instance_t * _instance, int width, int height, + vo_setup_result_t * result) +{ + sdl_instance_t * instance; + + instance = (sdl_instance_t *) _instance; + + instance->width = width; + instance->height = height; + instance->surface = SDL_SetVideoMode (width, height, instance->bpp, + instance->sdlflags); + if (! (instance->surface)) { + fprintf (stderr, "sdl could not set the desired video mode\n"); + return 1; + } + + result->convert = NULL; + return 0; +} + +vo_instance_t * vo_sdl_open (void) +{ + sdl_instance_t * instance; + const SDL_VideoInfo * vidInfo; + + instance = (sdl_instance_t *) malloc (sizeof (sdl_instance_t)); + if (instance == NULL) + return NULL; + + instance->vo.setup = sdl_setup; + instance->vo.setup_fbuf = sdl_setup_fbuf; + instance->vo.set_fbuf = NULL; + instance->vo.start_fbuf = sdl_start_fbuf; + instance->vo.discard = sdl_discard; + instance->vo.draw = sdl_draw_frame; + instance->vo.close = NULL; /* sdl_close; */ + instance->sdlflags = SDL_HWSURFACE | SDL_RESIZABLE; + + putenv("SDL_VIDEO_YUV_HWACCEL=1"); + putenv("SDL_VIDEO_X11_NODIRECTCOLOR=1"); + + if (SDL_Init (SDL_INIT_VIDEO)) { + fprintf (stderr, "sdl video initialization failed.\n"); + return NULL; + } + + vidInfo = SDL_GetVideoInfo (); + if (!SDL_ListModes (vidInfo->vfmt, SDL_HWSURFACE | SDL_RESIZABLE)) { + instance->sdlflags = SDL_RESIZABLE; + if (!SDL_ListModes (vidInfo->vfmt, SDL_RESIZABLE)) { + fprintf (stderr, "sdl couldn't get any acceptable video mode\n"); + return NULL; + } + } + instance->bpp = vidInfo->vfmt->BitsPerPixel; + if (instance->bpp < 16) { + fprintf(stderr, "sdl has to emulate a 16 bit surfaces, " + "that will slow things down.\n"); + instance->bpp = 16; + } + + return (vo_instance_t *) instance; +} +#endif diff --git a/vldp2/libvo/video_out_x11.c b/vldp2/libvo/video_out_x11.c new file mode 100644 index 000000000..d8793bf20 --- /dev/null +++ b/vldp2/libvo/video_out_x11.c @@ -0,0 +1,540 @@ +/* + * video_out_x11.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBVO_X11 + +#include +#include +#include +#include +#include +#include +#include +#include +/* since it doesn't seem to be defined on some platforms */ +int XShmGetEventBase (Display *); + +#ifdef LIBVO_XV +#include /* strcmp */ +#include +#define FOURCC_YV12 0x32315659 +#endif + +#include "video_out.h" +#include "convert.h" + +typedef struct { + void * data; + int wait_completion; + XImage * ximage; +#ifdef LIBVO_XV + XvImage * xvimage; +#endif +} x11_frame_t; + +typedef struct { + vo_instance_t vo; + x11_frame_t frame[3]; + int index; + int width; + int height; + Display * display; + Window window; + GC gc; + XVisualInfo vinfo; + XShmSegmentInfo shminfo; + int completion_type; +#ifdef LIBVO_XV + XvPortID port; +#endif +} x11_instance_t; + +static int open_display (x11_instance_t * instance) +{ + int major; + int minor; + Bool pixmaps; + XVisualInfo visualTemplate; + XVisualInfo * XvisualInfoTable; + XVisualInfo * XvisualInfo; + int number; + int i; + XSetWindowAttributes attr; + XGCValues gcValues; + + instance->display = XOpenDisplay (NULL); + if (! (instance->display)) { + fprintf (stderr, "Can not open display\n"); + return 1; + } + + if ((XShmQueryVersion (instance->display, &major, &minor, + &pixmaps) == 0) || + (major < 1) || ((major == 1) && (minor < 1))) { + fprintf (stderr, "No xshm extension\n"); + return 1; + } + + instance->completion_type = + XShmGetEventBase (instance->display) + ShmCompletion; + + /* list truecolor visuals for the default screen */ +#ifdef __cplusplus + visualTemplate.c_class = TrueColor; +#else + visualTemplate.class = TrueColor; +#endif + visualTemplate.screen = DefaultScreen (instance->display); + XvisualInfoTable = XGetVisualInfo (instance->display, + VisualScreenMask | VisualClassMask, + &visualTemplate, &number); + if (XvisualInfoTable == NULL) { + fprintf (stderr, "No truecolor visual\n"); + return 1; + } + + /* find the visual with the highest depth */ + XvisualInfo = XvisualInfoTable; + for (i = 1; i < number; i++) + if (XvisualInfoTable[i].depth > XvisualInfo->depth) + XvisualInfo = XvisualInfoTable + i; + + instance->vinfo = *XvisualInfo; + XFree (XvisualInfoTable); + + attr.background_pixmap = None; + attr.backing_store = NotUseful; + attr.border_pixel = 0; + attr.event_mask = 0; + /* fucking sun blows me - you have to create a colormap there... */ + attr.colormap = XCreateColormap (instance->display, + RootWindow (instance->display, + instance->vinfo.screen), + instance->vinfo.visual, AllocNone); + instance->window = + XCreateWindow (instance->display, + DefaultRootWindow (instance->display), + 0 /* x */, 0 /* y */, instance->width, instance->height, + 0 /* border_width */, instance->vinfo.depth, + InputOutput, instance->vinfo.visual, + (CWBackPixmap | CWBackingStore | CWBorderPixel | + CWEventMask | CWColormap), &attr); + + instance->gc = XCreateGC (instance->display, instance->window, 0, + &gcValues); + + return 0; +} + +static int shmerror = 0; + +static int handle_error (Display * display, XErrorEvent * error) +{ + shmerror = 1; + return 0; +} + +static void * create_shm (x11_instance_t * instance, int size) +{ + instance->shminfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); + if (instance->shminfo.shmid == -1) + goto error; + + instance->shminfo.shmaddr = (char *) shmat (instance->shminfo.shmid, 0, 0); + if (instance->shminfo.shmaddr == (char *)-1) + goto error; + + /* on linux the IPC_RMID only kicks off once everyone detaches the shm */ + /* doing this early avoids shm leaks when we are interrupted. */ + /* this would break the solaris port though :-/ */ + /* shmctl (instance->shminfo.shmid, IPC_RMID, 0); */ + + /* XShmAttach fails on remote displays, so we have to catch this event */ + + XSync (instance->display, False); + XSetErrorHandler (handle_error); + + instance->shminfo.readOnly = True; + if (! (XShmAttach (instance->display, &(instance->shminfo)))) + shmerror = 1; + + XSync (instance->display, False); + XSetErrorHandler (NULL); + if (shmerror) { + error: + fprintf (stderr, "cannot create shared memory\n"); + return NULL; + } + + return instance->shminfo.shmaddr; +} + +static void destroy_shm (x11_instance_t * instance) +{ + XShmDetach (instance->display, &(instance->shminfo)); + shmdt (instance->shminfo.shmaddr); + shmctl (instance->shminfo.shmid, IPC_RMID, 0); +} + +static void x11_event (x11_instance_t * instance) /* XXXXXXXXXXX */ +{ + XEvent event; + char * addr; + int i; + + XNextEvent (instance->display, &event); + if (event.type == instance->completion_type) { + addr = (instance->shminfo.shmaddr + + ((XShmCompletionEvent *)&event)->offset); + for (i = 0; i < 3; i++) + if (addr == instance->frame[i].data) + instance->frame[i].wait_completion = 0; + } +} + +static void x11_start_fbuf (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + x11_instance_t * instance = (x11_instance_t *) _instance; + x11_frame_t * frame = (x11_frame_t *) id; + + while (frame->wait_completion) + x11_event (instance); +} + +static void x11_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + x11_instance_t * instance = (x11_instance_t *) _instance; + + buf[0] = (uint8_t *) instance->frame[instance->index].data; + buf[1] = buf[2] = NULL; + *id = instance->frame + instance->index++; +} + +static void x11_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + x11_frame_t * frame; + x11_instance_t * instance; + + frame = (x11_frame_t *) id; + instance = (x11_instance_t *) _instance; + + XShmPutImage (instance->display, instance->window, instance->gc, + frame->ximage, 0, 0, 0, 0, instance->width, instance->height, + True); + XFlush (instance->display); + frame->wait_completion = 1; +} + +static int x11_alloc_frames (x11_instance_t * instance) +{ + int size; + char * alloc; + int i; + + size = 0; + alloc = NULL; + for (i = 0; i < 3; i++) { + instance->frame[i].wait_completion = 0; + instance->frame[i].ximage = + XShmCreateImage (instance->display, instance->vinfo.visual, + instance->vinfo.depth, ZPixmap, NULL /* data */, + &(instance->shminfo), + instance->width, instance->height); + if (instance->frame[i].ximage == NULL) { + fprintf (stderr, "Cannot create ximage\n"); + return 1; + } else if (i == 0) { + size = (instance->frame[0].ximage->bytes_per_line * + instance->frame[0].ximage->height); + alloc = (char *) create_shm (instance, 3 * size); + if (alloc == NULL) + return 1; + } else if (size != (instance->frame[0].ximage->bytes_per_line * + instance->frame[0].ximage->height)) { + fprintf (stderr, "unexpected ximage data size\n"); + return 1; + } + + instance->frame[i].data = instance->frame[i].ximage->data = alloc; + alloc += size; + } + instance->index = 0; + return 0; +} + +static void x11_close (vo_instance_t * _instance) +{ + x11_instance_t * instance = (x11_instance_t *) _instance; + int i; + + for (i = 0; i < 3; i++) { + while (instance->frame[i].wait_completion) + x11_event (instance); + XDestroyImage (instance->frame[i].ximage); + } + destroy_shm (instance); + XFreeGC (instance->display, instance->gc); + XDestroyWindow (instance->display, instance->window); + XCloseDisplay (instance->display); +} + +#ifdef LIBVO_XV +static void xv_setup_fbuf (vo_instance_t * _instance, + uint8_t ** buf, void ** id) +{ + x11_instance_t * instance = (x11_instance_t *) _instance; + uint8_t * data; + + data = (uint8_t *) instance->frame[instance->index].xvimage->data; + buf[0] = data + instance->frame[instance->index].xvimage->offsets[0]; + buf[1] = data + instance->frame[instance->index].xvimage->offsets[2]; + buf[2] = data + instance->frame[instance->index].xvimage->offsets[1]; + *id = instance->frame + instance->index++; +} + +static void xv_draw_frame (vo_instance_t * _instance, + uint8_t * const * buf, void * id) +{ + x11_frame_t * frame = (x11_frame_t *) id; + x11_instance_t * instance = (x11_instance_t *) _instance; + + XvShmPutImage (instance->display, instance->port, instance->window, + instance->gc, frame->xvimage, 0, 0, + instance->width, instance->height, 0, 0, + instance->width, instance->height, True); + XFlush (instance->display); + frame->wait_completion = 1; +} + +static int xv_check_yv12 (x11_instance_t * instance, XvPortID port) +{ + XvImageFormatValues * formatValues; + int formats; + int i; + + formatValues = XvListImageFormats (instance->display, port, &formats); + for (i = 0; i < formats; i++) + if ((formatValues[i].id == FOURCC_YV12) && + (! (strcmp (formatValues[i].guid, "YV12")))) { + XFree (formatValues); + return 0; + } + XFree (formatValues); + return 1; +} + +static int xv_check_extension (x11_instance_t * instance) +{ + unsigned int version; + unsigned int release; + unsigned int dummy; + unsigned int adaptors; + unsigned int i; + unsigned long j; + XvAdaptorInfo * adaptorInfo; + + if ((XvQueryExtension (instance->display, &version, &release, + &dummy, &dummy, &dummy) != Success) || + (version < 2) || ((version == 2) && (release < 2))) { + fprintf (stderr, "No xv extension\n"); + return 1; + } + + XvQueryAdaptors (instance->display, instance->window, &adaptors, + &adaptorInfo); + + for (i = 0; i < adaptors; i++) + if (adaptorInfo[i].type & XvImageMask) + for (j = 0; j < adaptorInfo[i].num_ports; j++) + if ((! (xv_check_yv12 (instance, + adaptorInfo[i].base_id + j))) && + (XvGrabPort (instance->display, adaptorInfo[i].base_id + j, + 0) == Success)) { + instance->port = adaptorInfo[i].base_id + j; + XvFreeAdaptorInfo (adaptorInfo); + return 0; + } + + XvFreeAdaptorInfo (adaptorInfo); + fprintf (stderr, "Cannot find xv port\n"); + return 1; +} + +static int xv_alloc_frames (x11_instance_t * instance) +{ + int size; + char * alloc; + int i; + + size = instance->width * instance->height / 4; + alloc = (char *) create_shm (instance, 18 * size); + if (alloc == NULL) + return 1; + + for (i = 0; i < 3; i++) { + instance->frame[i].wait_completion = 0; + instance->frame[i].xvimage = + XvShmCreateImage (instance->display, instance->port, FOURCC_YV12, + alloc, instance->width, instance->height, + &(instance->shminfo)); + if ((instance->frame[i].xvimage == NULL) || + (instance->frame[i].xvimage->data_size != 6 * size)) { /* FIXME */ + fprintf (stderr, "Cannot create xvimage\n"); + return 1; + } + instance->frame[i].data = alloc; + alloc += 6 * size; + } + + return 0; +} + +static void xv_close (vo_instance_t * _instance) +{ + x11_instance_t * instance = (x11_instance_t *) _instance; + int i; + + for (i = 0; i < 3; i++) { + while (instance->frame[i].wait_completion) + x11_event (instance); + XFree (instance->frame[i].xvimage); + } + destroy_shm (instance); + XvUngrabPort (instance->display, instance->port, 0); + XFreeGC (instance->display, instance->gc); + XDestroyWindow (instance->display, instance->window); + XCloseDisplay (instance->display); +} +#endif + +static int common_setup (x11_instance_t * instance, int width, int height, + vo_setup_result_t * result, int xv) +{ + instance->vo.set_fbuf = NULL; + instance->vo.discard = NULL; + instance->vo.start_fbuf = x11_start_fbuf; + instance->width = width; + instance->height = height; + + if (open_display (instance)) + return 1; + +#ifdef LIBVO_XV + if (xv && (! (xv_check_extension (instance)))) { + if (xv_alloc_frames (instance)) + return 1; + instance->vo.setup_fbuf = xv_setup_fbuf; + instance->vo.draw = xv_draw_frame; + instance->vo.close = xv_close; + result->convert = NULL; + } else +#endif + { + if (x11_alloc_frames (instance)) + return 1; + instance->vo.setup_fbuf = x11_setup_fbuf; + instance->vo.draw = x11_draw_frame; + instance->vo.close = x11_close; + +#ifdef WORDS_BIGENDIAN + if (instance->frame[0].ximage->byte_order != MSBFirst) { + fprintf (stderr, "No support for non-native byte order\n"); + return 1; + } +#else + if (instance->frame[0].ximage->byte_order != LSBFirst) { + fprintf (stderr, "No support for non-native byte order\n"); + return 1; + } +#endif + + /* + * depth in X11 terminology land is the number of bits used to + * actually represent the colour. + * + * bpp in X11 land means how many bits in the frame buffer per + * pixel. + * + * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit + * color is 24 bit depth, but can be 24 bpp or 32 bpp. + * + * If we have blue in the lowest bit then "obviously" RGB + * (the guy who wrote this convention never heard of endianness ?) + */ + + result->convert = + convert_rgb (((instance->frame[0].ximage->blue_mask & 1) ? + CONVERT_RGB : CONVERT_BGR), + ((instance->vinfo.depth == 24) ? + instance->frame[0].ximage->bits_per_pixel : + instance->vinfo.depth)); + } + + XMapWindow (instance->display, instance->window); + + return 0; +} + +static int x11_setup (vo_instance_t * instance, int width, int height, + vo_setup_result_t * result) +{ + return common_setup ((x11_instance_t *)instance, width, height, result, 0); +} + +vo_instance_t * vo_x11_open (void) +{ + x11_instance_t * instance; + + instance = (x11_instance_t *) malloc (sizeof (x11_instance_t)); + if (instance == NULL) + return NULL; + + instance->vo.setup = x11_setup; + return (vo_instance_t *) instance; +} + +#ifdef LIBVO_XV +static int xv_setup (vo_instance_t * instance, int width, int height, + vo_setup_result_t * result) +{ + return common_setup ((x11_instance_t *)instance, width, height, result, 1); +} + +vo_instance_t * vo_xv_open (void) +{ + x11_instance_t * instance; + + instance = (x11_instance_t *) malloc (sizeof (x11_instance_t)); + if (instance == NULL) + return NULL; + + instance->vo.setup = xv_setup; + return (vo_instance_t *) instance; +} +#endif +#endif diff --git a/vldp2/libvo/yuv2rgb.c b/vldp2/libvo/yuv2rgb.c new file mode 100644 index 000000000..808cda2ea --- /dev/null +++ b/vldp2/libvo/yuv2rgb.c @@ -0,0 +1,495 @@ +/* + * yuv2rgb.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include +#include + +#include "mpeg2.h" +#include "convert.h" +#include "convert_internal.h" + +static uint32_t matrix_coefficients = 6; + +const int32_t Inverse_Table_6_9[8][4] = { + {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ + {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ + {104597, 132201, 25675, 53279}, /* unspecified */ + {104597, 132201, 25675, 53279}, /* reserved */ + {104448, 132798, 24759, 53109}, /* FCC */ + {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ + {104597, 132201, 25675, 53279}, /* SMPTE 170M */ + {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ +}; + +typedef void yuv2rgb_c_internal (uint8_t *, uint8_t *, uint8_t *, uint8_t *, + void *, void *, int); + +void * table_rV[256]; +void * table_gU[256]; +int table_gV[256]; +void * table_bU[256]; + +#define RGB(type,i) \ + U = pu[i]; \ + V = pv[i]; \ + r = (type *) table_rV[V]; \ + g = (type *) (((uint8_t *)table_gU[U]) + table_gV[V]); \ + b = (type *) table_bU[U]; + +#define DST(py,dst,i) \ + Y = py[2*i]; \ + dst[2*i] = r[Y] + g[Y] + b[Y]; \ + Y = py[2*i+1]; \ + dst[2*i+1] = r[Y] + g[Y] + b[Y]; + +#define DSTRGB(py,dst,i) \ + Y = py[2*i]; \ + dst[6*i] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \ + Y = py[2*i+1]; \ + dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y]; + +#define DSTBGR(py,dst,i) \ + Y = py[2*i]; \ + dst[6*i] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \ + Y = py[2*i+1]; \ + dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y]; + +static void yuv2rgb_c_32 (uint8_t * py_1, uint8_t * py_2, + uint8_t * pu, uint8_t * pv, + void * _dst_1, void * _dst_2, int width) +{ + int U, V, Y; + uint32_t * r, * g, * b; + uint32_t * dst_1, * dst_2; + + width >>= 3; + dst_1 = (uint32_t *) _dst_1; + dst_2 = (uint32_t *) _dst_2; + + do { + RGB (uint32_t, 0); + DST (py_1, dst_1, 0); + DST (py_2, dst_2, 0); + + RGB (uint32_t, 1); + DST (py_2, dst_2, 1); + DST (py_1, dst_1, 1); + + RGB (uint32_t, 2); + DST (py_1, dst_1, 2); + DST (py_2, dst_2, 2); + + RGB (uint32_t, 3); + DST (py_2, dst_2, 3); + DST (py_1, dst_1, 3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); +} + +/* This is very near from the yuv2rgb_c_32 code */ +static void yuv2rgb_c_24_rgb (uint8_t * py_1, uint8_t * py_2, + uint8_t * pu, uint8_t * pv, + void * _dst_1, void * _dst_2, int width) +{ + int U, V, Y; + uint8_t * r, * g, * b; + uint8_t * dst_1, * dst_2; + + width >>= 3; + dst_1 = (uint8_t *) _dst_1; + dst_2 = (uint8_t *) _dst_2; + + do { + RGB (uint8_t, 0); + DSTRGB (py_1, dst_1, 0); + DSTRGB (py_2, dst_2, 0); + + RGB (uint8_t, 1); + DSTRGB (py_2, dst_2, 1); + DSTRGB (py_1, dst_1, 1); + + RGB (uint8_t, 2); + DSTRGB (py_1, dst_1, 2); + DSTRGB (py_2, dst_2, 2); + + RGB (uint8_t, 3); + DSTRGB (py_2, dst_2, 3); + DSTRGB (py_1, dst_1, 3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); +} + +/* only trivial mods from yuv2rgb_c_24_rgb */ +static void yuv2rgb_c_24_bgr (uint8_t * py_1, uint8_t * py_2, + uint8_t * pu, uint8_t * pv, + void * _dst_1, void * _dst_2, int width) +{ + int U, V, Y; + uint8_t * r, * g, * b; + uint8_t * dst_1, * dst_2; + + width >>= 3; + dst_1 = (uint8_t *) _dst_1; + dst_2 = (uint8_t *) _dst_2; + + do { + RGB (uint8_t, 0); + DSTBGR (py_1, dst_1, 0); + DSTBGR (py_2, dst_2, 0); + + RGB (uint8_t, 1); + DSTBGR (py_2, dst_2, 1); + DSTBGR (py_1, dst_1, 1); + + RGB (uint8_t, 2); + DSTBGR (py_1, dst_1, 2); + DSTBGR (py_2, dst_2, 2); + + RGB (uint8_t, 3); + DSTBGR (py_2, dst_2, 3); + DSTBGR (py_1, dst_1, 3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); +} + +/* This is exactly the same code as yuv2rgb_c_32 except for the types of */ +/* r, g, b, dst_1, dst_2 */ +static void yuv2rgb_c_16 (uint8_t * py_1, uint8_t * py_2, + uint8_t * pu, uint8_t * pv, + void * _dst_1, void * _dst_2, int width) +{ + int U, V, Y; + uint16_t * r, * g, * b; + uint16_t * dst_1, * dst_2; + + width >>= 3; + dst_1 = (uint16_t *) _dst_1; + dst_2 = (uint16_t *) _dst_2; + + do { + RGB (uint16_t, 0); + DST (py_1, dst_1, 0); + DST (py_2, dst_2, 0); + + RGB (uint16_t, 1); + DST (py_2, dst_2, 1); + DST (py_1, dst_1, 1); + + RGB (uint16_t, 2); + DST (py_1, dst_1, 2); + DST (py_2, dst_2, 2); + + RGB (uint16_t, 3); + DST (py_2, dst_2, 3); + DST (py_1, dst_1, 3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); +} + +static int div_round (int dividend, int divisor) +{ + if (dividend > 0) + return (dividend + (divisor>>1)) / divisor; + else + return -((-dividend + (divisor>>1)) / divisor); +} + +static yuv2rgb_c_internal * yuv2rgb_c_init (int order, int bpp) +{ + int i; + uint8_t table_Y[1024]; + uint32_t * table_32 = 0; + uint16_t * table_16 = 0; + uint8_t * table_8 = 0; + int entry_size = 0; + void * table_r = 0; + void * table_g = 0; + void * table_b = 0; + yuv2rgb_c_internal * yuv2rgb; + + int crv = Inverse_Table_6_9[matrix_coefficients][0]; + int cbu = Inverse_Table_6_9[matrix_coefficients][1]; + int cgu = -Inverse_Table_6_9[matrix_coefficients][2]; + int cgv = -Inverse_Table_6_9[matrix_coefficients][3]; + + for (i = 0; i < 1024; i++) { + int j; + + j = (76309 * (i - 384 - 16) + 32768) >> 16; + j = (j < 0) ? 0 : ((j > 255) ? 255 : j); + table_Y[i] = j; + } + + switch (bpp) { + case 32: + yuv2rgb = yuv2rgb_c_32; + + table_32 = (uint32_t *) malloc ((197 + 2*682 + 256 + 132) * + sizeof (uint32_t)); + + entry_size = sizeof (uint32_t); + table_r = table_32 + 197; + table_b = table_32 + 197 + 685; + table_g = table_32 + 197 + 2*682; + + for (i = -197; i < 256+197; i++) + ((uint32_t *) table_r)[i] = + table_Y[i+384] << ((order == CONVERT_RGB) ? 16 : 0); + for (i = -132; i < 256+132; i++) + ((uint32_t *) table_g)[i] = table_Y[i+384] << 8; + for (i = -232; i < 256+232; i++) + ((uint32_t *) table_b)[i] = + table_Y[i+384] << ((order == CONVERT_RGB) ? 0 : 16); + break; + + case 24: + yuv2rgb = (order == CONVERT_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr; + + table_8 = (uint8_t *) malloc ((256 + 2*232) * sizeof (uint8_t)); + + entry_size = sizeof (uint8_t); + table_r = table_g = table_b = table_8 + 232; + + for (i = -232; i < 256+232; i++) + ((uint8_t * )table_b)[i] = table_Y[i+384]; + break; + + case 15: + case 16: + yuv2rgb = yuv2rgb_c_16; + + table_16 = (uint16_t *) malloc ((197 + 2*682 + 256 + 132) * + sizeof (uint16_t)); + + entry_size = sizeof (uint16_t); + table_r = table_16 + 197; + table_b = table_16 + 197 + 685; + table_g = table_16 + 197 + 2*682; + + for (i = -197; i < 256+197; i++) { + int j = table_Y[i+384] >> 3; + + if (order == CONVERT_RGB) + j <<= ((bpp==16) ? 11 : 10); + + ((uint16_t *)table_r)[i] = j; + } + for (i = -132; i < 256+132; i++) { + int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3); + + ((uint16_t *)table_g)[i] = j << 5; + } + for (i = -232; i < 256+232; i++) { + int j = table_Y[i+384] >> 3; + + if (order == CONVERT_RGB) + j <<= ((bpp==16) ? 11 : 10); + + ((uint16_t *)table_b)[i] = j; + } + break; + + default: + fprintf (stderr, "%ibpp not supported by yuv2rgb\n", bpp); + exit (1); + } + + for (i = 0; i < 256; i++) { + table_rV[i] = (((uint8_t *)table_r) + + entry_size * div_round (crv * (i-128), 76309)); + table_gU[i] = (((uint8_t *)table_g) + + entry_size * div_round (cgu * (i-128), 76309)); + table_gV[i] = entry_size * div_round (cgv * (i-128), 76309); + table_bU[i] = (((uint8_t *)table_b) + + entry_size * div_round (cbu * (i-128), 76309)); + } + + return yuv2rgb; +} + +static void convert_yuv2rgb_c (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + uint8_t * dst; + uint8_t * py; + uint8_t * pu; + uint8_t * pv; + int loop; + + dst = id->rgb_ptr + id->rgb_stride * v_offset; + py = src[0]; pu = src[1]; pv = src[2]; + + loop = 8; + do { + id->yuv2rgb (py, py + (id->uv_stride << 1), pu, pv, + dst, dst + id->rgb_stride, id->width); + py += id->uv_stride << 2; + pu += id->uv_stride; + pv += id->uv_stride; + dst += 2 * id->rgb_stride; + } while (--loop); +} + +static void convert_start (void * _id, uint8_t * const * dest, int flags) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + id->rgb_ptr = dest[0]; + switch (flags) { + case CONVERT_BOTTOM_FIELD: + id->rgb_ptr += id->rgb_stride_frame; + /* break thru */ + case CONVERT_TOP_FIELD: + id->uv_stride = id->uv_stride_frame << 1; + id->rgb_stride = id->rgb_stride_frame << 1; + break; + default: + id->uv_stride = id->uv_stride_frame; + id->rgb_stride = id->rgb_stride_frame; + } +} + +static void convert_internal (int order, int bpp, int width, int height, + uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_rgb_t * id = (convert_rgb_t *) result->id; + + if (!id) { + result->id_size = sizeof (convert_rgb_t); + } else { + id->width = width; + id->uv_stride_frame = width >> 1; + id->rgb_stride_frame = ((bpp + 7) >> 3) * width; + + result->buf_size[0] = id->rgb_stride_frame * height; + result->buf_size[1] = result->buf_size[2] = 0; + result->start = convert_start; + + result->copy = NULL; +#ifdef ARCH_X86 + if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMXEXT)) { + result->copy = yuv2rgb_init_mmxext (order, bpp); + } + if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMX)) { + result->copy = yuv2rgb_init_mmx (order, bpp); + } +#endif +#ifdef LIBVO_MLIB + if ((result->copy == NULL) && (accel & MPEG2_ACCEL_MLIB)) { + result->copy = yuv2rgb_init_mlib (order, bpp); + } +#endif + if (result->copy == NULL) { + result->copy = convert_yuv2rgb_c; + id->yuv2rgb = yuv2rgb_c_init (order, bpp); + } + } +} + +void convert_rgb32 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_RGB, 32, width, height, accel, arg, result); +} + +void convert_rgb24 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_RGB, 24, width, height, accel, arg, result); +} + +void convert_rgb16 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_RGB, 16, width, height, accel, arg, result); +} + +void convert_rgb15 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_RGB, 15, width, height, accel, arg, result); +} + +void convert_bgr32 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_BGR, 32, width, height, accel, arg, result); +} + +void convert_bgr24 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_BGR, 24, width, height, accel, arg, result); +} + +void convert_bgr16 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_BGR, 16, width, height, accel, arg, result); +} + +void convert_bgr15 (int width, int height, uint32_t accel, void * arg, + convert_init_t * result) +{ + convert_internal (CONVERT_BGR, 15, width, height, accel, arg, result); +} + +convert_t * convert_rgb (int order, int bpp) +{ + if (order == CONVERT_RGB || order == CONVERT_BGR) + switch (bpp) { + case 32: return (order == CONVERT_RGB) ? convert_rgb32 : convert_bgr32; + case 24: return (order == CONVERT_RGB) ? convert_rgb24 : convert_bgr24; + case 16: return (order == CONVERT_RGB) ? convert_rgb16 : convert_bgr16; + case 15: return (order == CONVERT_RGB) ? convert_rgb15 : convert_bgr15; + } + return NULL; +} diff --git a/vldp2/libvo/yuv2rgb_mlib.c b/vldp2/libvo/yuv2rgb_mlib.c new file mode 100644 index 000000000..345a8ea26 --- /dev/null +++ b/vldp2/libvo/yuv2rgb_mlib.c @@ -0,0 +1,81 @@ +/* + * yuv2rgb_mlib.c + * Copyright (C) 2000-2002 Håkan Hjort + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef LIBVO_MLIB + +#include +#include +#include +#include +#include +#include + +#include "convert.h" +#include "convert_internal.h" + +static void mlib_YUV2ARGB420_32 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + mlib_VideoColorYUV2ARGB420 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], + id->width, 16, id->rgb_stride, + id->uv_stride << 1, id->uv_stride); +} + +static void mlib_YUV2ABGR420_32 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + mlib_VideoColorYUV2ABGR420 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], + id->width, 16, id->rgb_stride, + id->uv_stride << 1, id->uv_stride); +} + +static void mlib_YUV2RGB420_24 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + mlib_VideoColorYUV2RGB420 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], + id->width, 16, id->rgb_stride, + id->uv_stride << 1, id->uv_stride); +} + +yuv2rgb_copy * yuv2rgb_init_mlib (int order, int bpp) +{ + if ((order == CONVERT_RGB) && (bpp == 24)) + return mlib_YUV2RGB420_24; + else if ((order == CONVERT_RGB) && (bpp == 32)) + return mlib_YUV2ARGB420_32; + else if ((order == CONVERT_BGR) && (bpp == 32)) + return mlib_YUV2ABGR420_32; + return NULL; /* Fallback to C */ +} + +#endif diff --git a/vldp2/libvo/yuv2rgb_mmx.c b/vldp2/libvo/yuv2rgb_mmx.c new file mode 100644 index 000000000..ec1a7ea16 --- /dev/null +++ b/vldp2/libvo/yuv2rgb_mmx.c @@ -0,0 +1,325 @@ +/* + * yuv2rgb_mmx.c + * Copyright (C) 2000-2002 Silicon Integrated System Corp. + * All Rights Reserved. + * + * Author: Olie Lho + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#ifdef ARCH_X86 + +#include +#include +#include + +#include "convert.h" +#include "convert_internal.h" +#include "attributes.h" +#include "mmx.h" + +#define CPU_MMXEXT 0 +#define CPU_MMX 1 + +/* CPU_MMXEXT/CPU_MMX adaptation layer */ + +#define movntq(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + movntq_r2m (src, dest); \ + else \ + movq_r2m (src, dest); \ +} while (0) + +static inline void mmx_yuv2rgb (uint8_t * py, uint8_t * pu, uint8_t * pv) +{ + static mmx_t mmx_80w = {0x0080008000800080LL}; + static mmx_t mmx_U_green = {0xf37df37df37df37dLL}; + static mmx_t mmx_U_blue = {0x4093409340934093LL}; + static mmx_t mmx_V_red = {0x3312331233123312LL}; + static mmx_t mmx_V_green = {0xe5fce5fce5fce5fcLL}; + static mmx_t mmx_10w = {0x1010101010101010LL}; + static mmx_t mmx_00ffw = {0x00ff00ff00ff00ffLL}; + static mmx_t mmx_Y_coeff = {0x253f253f253f253fLL}; + + movd_m2r (*pu, mm0); /* mm0 = 00 00 00 00 u3 u2 u1 u0 */ + movd_m2r (*pv, mm1); /* mm1 = 00 00 00 00 v3 v2 v1 v0 */ + movq_m2r (*py, mm6); /* mm6 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ + pxor_r2r (mm4, mm4); /* mm4 = 0 */ + /* XXX might do cache preload for image here */ + + /* + * Do the multiply part of the conversion for even and odd pixels + * register usage: + * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels + * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels + * mm6 -> Y even, mm7 -> Y odd + */ + + punpcklbw_r2r (mm4, mm0); /* mm0 = u3 u2 u1 u0 */ + punpcklbw_r2r (mm4, mm1); /* mm1 = v3 v2 v1 v0 */ + psubsw_m2r (mmx_80w, mm0); /* u -= 128 */ + psubsw_m2r (mmx_80w, mm1); /* v -= 128 */ + psllw_i2r (3, mm0); /* promote precision */ + psllw_i2r (3, mm1); /* promote precision */ + movq_r2r (mm0, mm2); /* mm2 = u3 u2 u1 u0 */ + movq_r2r (mm1, mm3); /* mm3 = v3 v2 v1 v0 */ + pmulhw_m2r (mmx_U_green, mm2); /* mm2 = u * u_green */ + pmulhw_m2r (mmx_V_green, mm3); /* mm3 = v * v_green */ + pmulhw_m2r (mmx_U_blue, mm0); /* mm0 = chroma_b */ + pmulhw_m2r (mmx_V_red, mm1); /* mm1 = chroma_r */ + paddsw_r2r (mm3, mm2); /* mm2 = chroma_g */ + + psubusb_m2r (mmx_10w, mm6); /* Y -= 16 */ + movq_r2r (mm6, mm7); /* mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ + pand_m2r (mmx_00ffw, mm6); /* mm6 = Y6 Y4 Y2 Y0 */ + psrlw_i2r (8, mm7); /* mm7 = Y7 Y5 Y3 Y1 */ + psllw_i2r (3, mm6); /* promote precision */ + psllw_i2r (3, mm7); /* promote precision */ + pmulhw_m2r (mmx_Y_coeff, mm6); /* mm6 = luma_rgb even */ + pmulhw_m2r (mmx_Y_coeff, mm7); /* mm7 = luma_rgb odd */ + + /* + * Do the addition part of the conversion for even and odd pixels + * register usage: + * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels + * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels + * mm6 -> Y even, mm7 -> Y odd + */ + + movq_r2r (mm0, mm3); /* mm3 = chroma_b */ + movq_r2r (mm1, mm4); /* mm4 = chroma_r */ + movq_r2r (mm2, mm5); /* mm5 = chroma_g */ + paddsw_r2r (mm6, mm0); /* mm0 = B6 B4 B2 B0 */ + paddsw_r2r (mm7, mm3); /* mm3 = B7 B5 B3 B1 */ + paddsw_r2r (mm6, mm1); /* mm1 = R6 R4 R2 R0 */ + paddsw_r2r (mm7, mm4); /* mm4 = R7 R5 R3 R1 */ + paddsw_r2r (mm6, mm2); /* mm2 = G6 G4 G2 G0 */ + paddsw_r2r (mm7, mm5); /* mm5 = G7 G5 G3 G1 */ + packuswb_r2r (mm0, mm0); /* saturate to 0-255 */ + packuswb_r2r (mm1, mm1); /* saturate to 0-255 */ + packuswb_r2r (mm2, mm2); /* saturate to 0-255 */ + packuswb_r2r (mm3, mm3); /* saturate to 0-255 */ + packuswb_r2r (mm4, mm4); /* saturate to 0-255 */ + packuswb_r2r (mm5, mm5); /* saturate to 0-255 */ + punpcklbw_r2r (mm3, mm0); /* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */ + punpcklbw_r2r (mm4, mm1); /* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */ + punpcklbw_r2r (mm5, mm2); /* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */ +} + +static inline void mmx_unpack_16rgb (uint8_t * image, const int cpu) +{ + static mmx_t mmx_bluemask = {0xf8f8f8f8f8f8f8f8LL}; + static mmx_t mmx_greenmask = {0xfcfcfcfcfcfcfcfcLL}; + static mmx_t mmx_redmask = {0xf8f8f8f8f8f8f8f8LL}; + + /* + * convert RGB plane to RGB 16 bits + * mm0 -> B, mm1 -> R, mm2 -> G + * mm4 -> GB, mm5 -> AR pixel 4-7 + * mm6 -> GB, mm7 -> AR pixel 0-3 + */ + + pand_m2r (mmx_bluemask, mm0); /* mm0 = b7b6b5b4b3______ */ + pand_m2r (mmx_greenmask, mm2); /* mm2 = g7g6g5g4g3g2____ */ + pand_m2r (mmx_redmask, mm1); /* mm1 = r7r6r5r4r3______ */ + psrlq_i2r (3, mm0); /* mm0 = ______b7b6b5b4b3 */ + pxor_r2r (mm4, mm4); /* mm4 = 0 */ + movq_r2r (mm0, mm5); /* mm5 = ______b7b6b5b4b3 */ + movq_r2r (mm2, mm7); /* mm7 = g7g6g5g4g3g2____ */ + + punpcklbw_r2r (mm4, mm2); + punpcklbw_r2r (mm1, mm0); + psllq_i2r (3, mm2); + por_r2r (mm2, mm0); + movntq (mm0, *image); + + punpckhbw_r2r (mm4, mm7); + punpckhbw_r2r (mm1, mm5); + psllq_i2r (3, mm7); + por_r2r (mm7, mm5); + movntq (mm5, *(image+8)); +} + +static inline void mmx_unpack_32rgb (uint8_t * image, const int cpu) +{ + /* + * convert RGB plane to RGB packed format, + * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, + * mm4 -> GB, mm5 -> AR pixel 4-7, + * mm6 -> GB, mm7 -> AR pixel 0-3 + */ + + pxor_r2r (mm3, mm3); + movq_r2r (mm0, mm6); + movq_r2r (mm1, mm7); + movq_r2r (mm0, mm4); + movq_r2r (mm1, mm5); + punpcklbw_r2r (mm2, mm6); + punpcklbw_r2r (mm3, mm7); + punpcklwd_r2r (mm7, mm6); + movntq (mm6, *image); + movq_r2r (mm0, mm6); + punpcklbw_r2r (mm2, mm6); + punpckhwd_r2r (mm7, mm6); + movntq (mm6, *(image+8)); + punpckhbw_r2r (mm2, mm4); + punpckhbw_r2r (mm3, mm5); + punpcklwd_r2r (mm5, mm4); + movntq (mm4, *(image+16)); + movq_r2r (mm0, mm4); + punpckhbw_r2r (mm2, mm4); + punpckhwd_r2r (mm5, mm4); + movntq (mm4, *(image+24)); +} + +static inline void yuv420_rgb16 (uint8_t * image, + uint8_t * py, uint8_t * pu, uint8_t * pv, + int width, int height, + int rgb_stride, int y_stride, int uv_stride, + const int cpu) +{ + int i; + + rgb_stride -= 2 * width; + y_stride -= width; + uv_stride -= width >> 1; + width >>= 3; + + do { + i = width; + do { + mmx_yuv2rgb (py, pu, pv); + mmx_unpack_16rgb (image, cpu); + py += 8; + pu += 4; + pv += 4; + image += 16; + } while (--i); + + py += y_stride; + image += rgb_stride; + if (height & 1) { + pu += uv_stride; + pv += uv_stride; + } else { + pu -= 4 * width; + pv -= 4 * width; + } + } while (--height); +} + +static inline void yuv420_argb32 (uint8_t * image, uint8_t * py, + uint8_t * pu, uint8_t * pv, + int width, int height, + int rgb_stride, int y_stride, int uv_stride, + const int cpu) +{ + int i; + + rgb_stride -= 4 * width; + y_stride -= width; + uv_stride -= width >> 1; + width >>= 3; + + do { + i = width; + do { + mmx_yuv2rgb (py, pu, pv); + mmx_unpack_32rgb (image, cpu); + py += 8; + pu += 4; + pv += 4; + image += 32; + } while (--i); + + py += y_stride; + image += rgb_stride; + if (height & 1) { + pu += uv_stride; + pv += uv_stride; + } else { + pu -= 4 * width; + pv -= 4 * width; + } + } while (--height); +} + +static void mmxext_rgb16 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + yuv420_rgb16 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], id->width, 16, + id->rgb_stride, id->uv_stride << 1, id->uv_stride, + CPU_MMXEXT); +} + +static void mmxext_argb32 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + yuv420_argb32 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], id->width, 16, + id->rgb_stride, id->uv_stride << 1, id->uv_stride, + CPU_MMXEXT); +} + +static void mmx_rgb16 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + yuv420_rgb16 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], id->width, 16, + id->rgb_stride, id->uv_stride << 1, id->uv_stride, CPU_MMX); +} + +static void mmx_argb32 (void * _id, uint8_t * const * src, + unsigned int v_offset) +{ + convert_rgb_t * id = (convert_rgb_t *) _id; + + yuv420_argb32 (id->rgb_ptr + id->rgb_stride * v_offset, + src[0], src[1], src[2], id->width, 16, + id->rgb_stride, id->uv_stride << 1, id->uv_stride, CPU_MMX); +} + +yuv2rgb_copy * yuv2rgb_init_mmxext (int order, int bpp) +{ + if ((order == CONVERT_RGB) && (bpp == 16)) + return mmxext_rgb16; + else if ((order == CONVERT_RGB) && (bpp == 32)) + return mmxext_argb32; + return NULL; /* Fallback to C */ +} + +yuv2rgb_copy * yuv2rgb_init_mmx (int order, int bpp) +{ + if ((order == CONVERT_RGB) && (bpp == 16)) + return mmx_rgb16; + else if ((order == CONVERT_RGB) && (bpp == 32)) + return mmx_argb32; + return NULL; /* Fallback to C */ +} +#endif diff --git a/vldp2/src/Makefile.am b/vldp2/src/Makefile.am new file mode 100644 index 000000000..ef6096ad3 --- /dev/null +++ b/vldp2/src/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = mpeg2dec extract_mpeg2 +mpeg2dec_SOURCES = mpeg2dec.c getopt.c gettimeofday.c +mpeg2dec_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a @LIBVO_LIBS@ +extract_mpeg2_SOURCES = extract_mpeg2.c getopt.c + +man_MANS = mpeg2dec.1 extract_mpeg2.1 + +EXTRA_DIST = getopt.h gettimeofday.h $(man_MANS) diff --git a/vldp2/src/Makefile.in b/vldp2/src/Makefile.in new file mode 100644 index 000000000..41a61cd09 --- /dev/null +++ b/vldp2/src/Makefile.in @@ -0,0 +1,504 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +bin_PROGRAMS = mpeg2dec extract_mpeg2 +mpeg2dec_SOURCES = mpeg2dec.c getopt.c gettimeofday.c +mpeg2dec_LDADD = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a @LIBVO_LIBS@ + +extract_mpeg2_SOURCES = extract_mpeg2.c getopt.c + +man_MANS = mpeg2dec.1 extract_mpeg2.1 + +EXTRA_DIST = getopt.h gettimeofday.h $(man_MANS) +subdir = src +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +bin_PROGRAMS = mpeg2dec$(EXEEXT) extract_mpeg2$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am_extract_mpeg2_OBJECTS = extract_mpeg2.$(OBJEXT) getopt.$(OBJEXT) +extract_mpeg2_OBJECTS = $(am_extract_mpeg2_OBJECTS) +extract_mpeg2_LDADD = $(LDADD) +extract_mpeg2_DEPENDENCIES = +extract_mpeg2_LDFLAGS = +am_mpeg2dec_OBJECTS = mpeg2dec.$(OBJEXT) getopt.$(OBJEXT) \ + gettimeofday.$(OBJEXT) +mpeg2dec_OBJECTS = $(am_mpeg2dec_OBJECTS) +mpeg2dec_DEPENDENCIES = $(top_builddir)/libmpeg2/libmpeg2.la \ + $(top_builddir)/libvo/libvo.a +mpeg2dec_LDFLAGS = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/extract_mpeg2.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/getopt.Po ./$(DEPDIR)/gettimeofday.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/mpeg2dec.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(extract_mpeg2_SOURCES) $(mpeg2dec_SOURCES) + +NROFF = nroff +MANS = $(man_MANS) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(extract_mpeg2_SOURCES) $(mpeg2dec_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +extract_mpeg2$(EXEEXT): $(extract_mpeg2_OBJECTS) $(extract_mpeg2_DEPENDENCIES) + @rm -f extract_mpeg2$(EXEEXT) + $(LINK) $(extract_mpeg2_LDFLAGS) $(extract_mpeg2_OBJECTS) $(extract_mpeg2_LDADD) $(LIBS) +mpeg2dec$(EXEEXT): $(mpeg2dec_OBJECTS) $(mpeg2dec_DEPENDENCIES) + @rm -f mpeg2dec$(EXEEXT) + $(LINK) $(mpeg2dec_LDFLAGS) $(mpeg2dec_OBJECTS) $(mpeg2dec_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_mpeg2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpeg2dec.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +man1dir = $(mandir)/man1 +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-exec-am: install-binPROGRAMS + +install-info: install-info-am + +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man + +uninstall-man: uninstall-man1 + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-depend distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am info info-am install \ + install-am install-binPROGRAMS install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-man1 install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am uninstall-man uninstall-man1 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/src/extract_mpeg2.1 b/vldp2/src/extract_mpeg2.1 new file mode 100644 index 000000000..bd11bd2fb --- /dev/null +++ b/vldp2/src/extract_mpeg2.1 @@ -0,0 +1,35 @@ +.TH mpeg2dec "1" "extract_mpeg2" +.SH NAME +extract_mpeg2 \- extract MPEG video streams from a multiplexed stream. +.SH SYNOPSIS +.B extract_mpeg2 +[\fI-h\fR] [\fI-s [track]\fR] [\fI-t pid\fR] [\fIfile\fR] +.SH DESCRIPTION +`extract_mpeg2' extracts MPEG video streams from a multiplexed stream. +Input is from stdin if no file is given. +.TP +\fB\-h\fR +display help +.TP +\fB\-s track\fR +set track number (0-0xf or 0xe0-0xef) +.TP +\fB\-t pid\fR +use transport stream demultiplexer, pid 0x10-0x1ffe +.SH AUTHORS +Michel Lespinasse +.br +Aaron Holtzman +.br +And many others on the net. +.SH "REPORTING BUGS" +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2000-2002 Michel Lespinasse +.br +Copyright \(co 1999-2000 Aaron Holtzman +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +.BR mpeg2dec "(1)" diff --git a/vldp2/src/extract_mpeg2.c b/vldp2/src/extract_mpeg2.c new file mode 100644 index 000000000..0515124b8 --- /dev/null +++ b/vldp2/src/extract_mpeg2.c @@ -0,0 +1,455 @@ +/* + * extract_mpeg2.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_IO_H +#include +#include +#endif +#include + +#define BUFFER_SIZE 4096 +static uint8_t buffer[BUFFER_SIZE]; +static FILE * in_file; +static int demux_track = 0xe0; +static int demux_pid = 0; +static int demux_pva = 0; + +static void print_usage (char ** argv) +{ + fprintf (stderr, "usage: %s [-s ] [-t ] [-p] \n" + "\t-s\tset track number (0-15 or 0xe0-0xef)\n" + "\t-t\tuse transport stream demultiplexer, pid 0x10-0x1ffe\n" + "\t-p\tuse pva demultiplexer\n", + argv[0]); + + exit (1); +} + +static void handle_args (int argc, char ** argv) +{ + int c; + char * s; + + while ((c = getopt (argc, argv, "s:t:p")) != -1) + switch (c) { + case 's': + demux_track = strtol (optarg, &s, 0); + if (demux_track < 0xe0) + demux_track += 0xe0; + if ((demux_track < 0xe0) || (demux_track > 0xef) || (*s)) { + fprintf (stderr, "Invalid track number: %s\n", optarg); + print_usage (argv); + } + break; + + case 't': + demux_pid = strtol (optarg, &s, 0); + if ((demux_pid < 0x10) || (demux_pid > 0x1ffe) || (*s)) { + fprintf (stderr, "Invalid pid: %s\n", optarg); + print_usage (argv); + } + break; + + case 'p': + demux_pva = 1; + break; + + default: + print_usage (argv); + } + + if (optind < argc) { + in_file = fopen (argv[optind], "rb"); + if (!in_file) { + fprintf (stderr, "%s - could not open file %s\n", strerror (errno), + argv[optind]); + exit (1); + } + } else + in_file = stdin; +} + +#define DEMUX_PAYLOAD_START 1 +static int demux (uint8_t * buf, uint8_t * end, int flags) +{ + static int mpeg1_skip_table[16] = { + 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + /* + * the demuxer keeps some state between calls: + * if "state" = DEMUX_HEADER, then "head_buf" contains the first + * "bytes" bytes from some header. + * if "state" == DEMUX_DATA, then we need to copy "bytes" bytes + * of ES data before the next header. + * if "state" == DEMUX_SKIP, then we need to skip "bytes" bytes + * of data before the next header. + * + * NEEDBYTES makes sure we have the requested number of bytes for a + * header. If we dont, it copies what we have into head_buf and returns, + * so that when we come back with more data we finish decoding this header. + * + * DONEBYTES updates "buf" to point after the header we just parsed. + */ + +#define DEMUX_HEADER 0 +#define DEMUX_DATA 1 +#define DEMUX_SKIP 2 + static int state = DEMUX_SKIP; + static int state_bytes = 0; + static uint8_t head_buf[264]; + + uint8_t * header; + int bytes; + int len; + +#define NEEDBYTES(x) \ + do { \ + int missing; \ + \ + missing = (x) - bytes; \ + if (missing > 0) { \ + if (header == head_buf) { \ + if (missing <= end - buf) { \ + memcpy (header + bytes, buf, missing); \ + buf += missing; \ + bytes = (x); \ + } else { \ + memcpy (header + bytes, buf, end - buf); \ + state_bytes = bytes + end - buf; \ + return 0; \ + } \ + } else { \ + memcpy (head_buf, header, bytes); \ + state = DEMUX_HEADER; \ + state_bytes = bytes; \ + return 0; \ + } \ + } \ + } while (0) + +#define DONEBYTES(x) \ + do { \ + if (header != head_buf) \ + buf = header + (x); \ + } while (0) + + if (flags & DEMUX_PAYLOAD_START) + goto payload_start; + switch (state) { + case DEMUX_HEADER: + if (state_bytes > 0) { + header = head_buf; + bytes = state_bytes; + goto continue_header; + } + break; + case DEMUX_DATA: + if (demux_pid || (state_bytes > end - buf)) { + fwrite (buf, end - buf, 1, stdout); + state_bytes -= end - buf; + return 0; + } + fwrite (buf, state_bytes, 1, stdout); + buf += state_bytes; + break; + case DEMUX_SKIP: + if (demux_pid || (state_bytes > end - buf)) { + state_bytes -= end - buf; + return 0; + } + buf += state_bytes; + break; + } + + while (1) { + if (demux_pid) { + state = DEMUX_SKIP; + return 0; + } + payload_start: + header = buf; + bytes = end - buf; + continue_header: + NEEDBYTES (4); + if (header[0] || header[1] || (header[2] != 1)) { + if (demux_pid) { + state = DEMUX_SKIP; + return 0; + } else if (header != head_buf) { + buf++; + goto payload_start; + } else { + header[0] = header[1]; + header[1] = header[2]; + header[2] = header[3]; + bytes = 3; + goto continue_header; + } + } + if (demux_pid) { + if ((header[3] >= 0xe0) && (header[3] <= 0xef)) + goto pes; + fprintf (stderr, "bad stream id %x\n", header[3]); + exit (1); + } + switch (header[3]) { + case 0xb9: /* program end code */ + /* DONEBYTES (4); */ + /* break; */ + return 1; + case 0xba: /* pack header */ + NEEDBYTES (12); + if ((header[4] & 0xc0) == 0x40) { /* mpeg2 */ + NEEDBYTES (14); + len = 14 + (header[13] & 7); + NEEDBYTES (len); + DONEBYTES (len); + /* header points to the mpeg2 pack header */ + } else if ((header[4] & 0xf0) == 0x20) { /* mpeg1 */ + DONEBYTES (12); + /* header points to the mpeg1 pack header */ + } else { + fprintf (stderr, "weird pack header\n"); + exit (1); + } + break; + default: + if (header[3] == demux_track) { + pes: + NEEDBYTES (7); + if ((header[6] & 0xc0) == 0x80) { /* mpeg2 */ + NEEDBYTES (9); + len = 9 + header[8]; + NEEDBYTES (len); + /* header points to the mpeg2 pes header */ + } else { /* mpeg1 */ + len = 7; + while ((header-1)[len] == 0xff) { + len++; + NEEDBYTES (len); + if (len > 23) { + fprintf (stderr, "too much stuffing\n"); + break; + } + } + if (((header-1)[len] & 0xc0) == 0x40) { + len += 2; + NEEDBYTES (len); + } + len += mpeg1_skip_table[(header - 1)[len] >> 4]; + NEEDBYTES (len); + /* header points to the mpeg1 pes header */ + } + DONEBYTES (len); + bytes = 6 + (header[4] << 8) + header[5] - len; + if (demux_pid || (bytes > end - buf)) { + fwrite (buf, end - buf, 1, stdout); + state = DEMUX_DATA; + state_bytes = bytes - (end - buf); + return 0; + } else if (bytes <= 0) + continue; + fwrite (buf, bytes, 1, stdout); + buf += bytes; + } else if (header[3] < 0xb9) { + fprintf (stderr, + "looks like a video stream, not system stream\n"); + DONEBYTES (4); + } else { + NEEDBYTES (6); + DONEBYTES (6); + bytes = (header[4] << 8) + header[5]; + if (bytes > end - buf) { + state = DEMUX_SKIP; + state_bytes = bytes - (end - buf); + return 0; + } + buf += bytes; + } + } + } +} + +static void ps_loop (void) +{ + uint8_t * end; + + do { + end = buffer + fread (buffer, 1, BUFFER_SIZE, in_file); + if (demux (buffer, end, 0)) + break; /* hit program_end_code */ + } while (end == buffer + BUFFER_SIZE); +} + +static int pva_demux (uint8_t * buf, uint8_t * end) +{ + static int state = DEMUX_SKIP; + static int state_bytes = 0; + static uint8_t head_buf[12]; + + uint8_t * header; + int bytes; + int len; + + switch (state) { + case DEMUX_HEADER: + if (state_bytes > 0) { + header = head_buf; + bytes = state_bytes; + goto continue_header; + } + break; + case DEMUX_DATA: + if (state_bytes > end - buf) { + fwrite (buf, end - buf, 1, stdout); + state_bytes -= end - buf; + return 0; + } + fwrite (buf, state_bytes, 1, stdout); + buf += state_bytes; + break; + case DEMUX_SKIP: + if (state_bytes > end - buf) { + state_bytes -= end - buf; + return 0; + } + buf += state_bytes; + break; + } + + while (1) { + payload_start: + header = buf; + bytes = end - buf; + continue_header: + NEEDBYTES (2); + if (header[0] != 0x41 || header[1] != 0x56) { + if (header != head_buf) { + buf++; + goto payload_start; + } else { + header[0] = header[1]; + bytes = 1; + goto continue_header; + } + } + NEEDBYTES (8); + if (header[2] != 1) { + DONEBYTES (8); + bytes = (header[6] << 8) + header[7]; + if (bytes > end - buf) { + state = DEMUX_SKIP; + state_bytes = bytes - (end - buf); + return 0; + } + buf += bytes; + } else { + len = 8; + if (header[5] & 0x10) { + len = 12; + NEEDBYTES (len); + } + DONEBYTES (len); + bytes = (header[6] << 8) + header[7] + 8 - len; + if (bytes > end - buf) { + fwrite (buf, end - buf, 1, stdout); + state = DEMUX_DATA; + state_bytes = bytes - (end - buf); + return 0; + } else if (bytes > 0) { + fwrite (buf, bytes, 1, stdout); + buf += bytes; + } + } + } +} + +static void pva_loop (void) +{ + uint8_t * end; + + do { + end = buffer + fread (buffer, 1, BUFFER_SIZE, in_file); + pva_demux (buffer, end); + } while (end == buffer + BUFFER_SIZE); +} + +static void ts_loop (void) +{ +#define PACKETS (BUFFER_SIZE / 188) + uint8_t * buf; + uint8_t * data; + uint8_t * end; + int packets; + int i; + int pid; + + do { + packets = fread (buffer, 188, PACKETS, in_file); + for (i = 0; i < packets; i++) { + buf = buffer + i * 188; + end = buf + 188; + if (buf[0] != 0x47) { + fprintf (stderr, "bad sync byte\n"); + exit (1); + } + pid = ((buf[1] << 8) + buf[2]) & 0x1fff; + if (pid != demux_pid) + continue; + data = buf + 4; + if (buf[3] & 0x20) { /* buf contains an adaptation field */ + data = buf + 5 + buf[4]; + if (data > end) + continue; + } + if (buf[3] & 0x10) + demux (data, end, (buf[1] & 0x40) ? DEMUX_PAYLOAD_START : 0); + } + } while (packets == PACKETS); +} + +int main (int argc, char ** argv) +{ +#ifdef HAVE_IO_H + setmode (fileno (stdout), O_BINARY); +#endif + + handle_args (argc, argv); + + if (demux_pva) + pva_loop (); + if (demux_pid) + ts_loop (); + else + ps_loop (); + + return 0; +} diff --git a/vldp2/src/getopt.c b/vldp2/src/getopt.c new file mode 100644 index 000000000..4744e4339 --- /dev/null +++ b/vldp2/src/getopt.c @@ -0,0 +1,1055 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/vldp2/src/getopt.h b/vldp2/src/getopt.h new file mode 100644 index 000000000..b0147e9d2 --- /dev/null +++ b/vldp2/src/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/vldp2/src/gettimeofday.c b/vldp2/src/gettimeofday.c new file mode 100644 index 000000000..fb6068cfb --- /dev/null +++ b/vldp2/src/gettimeofday.c @@ -0,0 +1,40 @@ +/* + * gettimeofday.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include "gettimeofday.h" + +#ifdef CUSTOM_GETTIMEOFDAY + +#include + +void gettimeofday (struct timeval * tp, void * dummy) +{ + struct timeb tm; + ftime (&tm); + tp->tv_sec = tm.time; + tp->tv_usec = tm.millitm * 1000; +} + +#endif diff --git a/vldp2/src/gettimeofday.h b/vldp2/src/gettimeofday.h new file mode 100644 index 000000000..5cc3b2f53 --- /dev/null +++ b/vldp2/src/gettimeofday.h @@ -0,0 +1,40 @@ +/* + * gettimeofday.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) +#include +#elif defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME) + +#define HAVE_GETTIMEOFDAY 1 +#define CUSTOM_GETTIMEOFDAY 1 + +struct timeval { + long tv_sec; + long tv_usec; +}; + +void gettimeofday (struct timeval * tp, void * dummy); + +#else +#undef HAVE_GETTIMEOFDAY +#endif diff --git a/vldp2/src/mpeg2dec.1 b/vldp2/src/mpeg2dec.1 new file mode 100644 index 000000000..c88623932 --- /dev/null +++ b/vldp2/src/mpeg2dec.1 @@ -0,0 +1,43 @@ +.TH mpeg2dec "1" "mpeg2dec" +.SH NAME +mpeg2dec \- decode MPEG and MPEG2 video streams +.SH SYNOPSIS +.B mpeg2dec +[\fI-h\fR] [\fI-s [track]\fR] [\fI-t pid\fR] [\fI-c\fR] [\fI-o mode\fR] [\fIfile\fR] +.SH DESCRIPTION +`mpeg2dec' displays MPEG1 and MPEG2 video stream. +Input is from stdin if no file is given. +.TP +\fB\-h\fR +display help and available video modes +.TP +\fB\-s\fR +use program stream demultiplexer, track 0-0xf or 0xe0-0xef +.TP +\fB\-t pid\fR +use transport stream demultiplexer, pid 0x10-0x1ffe +.TP +\fB\-c\fR +use c implementation, disables all accelerations +.TP +\fB\-o\fR \fImode\fR +use video output driver `mode'. +.br +A list of modes is available using the \fB\-h\fR option. +.SH AUTHORS +Michel Lespinasse +.br +Aaron Holtzman +.br +And many others on the net. +.SH "REPORTING BUGS" +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2000-2002 Michel Lespinasse +.br +Copyright \(co 1999-2000 Aaron Holtzman +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +.BR extract_mpeg2 "(1)" diff --git a/vldp2/src/mpeg2dec.c b/vldp2/src/mpeg2dec.c new file mode 100644 index 000000000..587542991 --- /dev/null +++ b/vldp2/src/mpeg2dec.c @@ -0,0 +1,200 @@ +/* + * mpeg2dec.c + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * See http://libmpeg2.sourceforge.net/ for updates. + * + * mpeg2dec 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. + * + * mpeg2dec 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 + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_IO_H +#include +#include +#endif +#include + +#include "mpeg2.h" +#include "video_out.h" +#include "convert.h" + +#define BUFFER_SIZE 4096 +static uint8_t buffer[BUFFER_SIZE]; +static FILE * in_file; +static mpeg2dec_t * mpeg2dec; +static vo_open_t * output_open = NULL; +static vo_instance_t * output; + +static void handle_args (int argc, char ** argv) +{ + int c; + vo_driver_t * drivers; + int i; + + drivers = vo_drivers (); + while ((c = getopt (argc, argv, "s::t:pco:")) != -1) + switch (c) { + case 'o': + for (i = 0; drivers[i].name != NULL; i++) + if (strcmp (drivers[i].name, optarg) == 0) + output_open = drivers[i].open; + if (output_open == NULL) { + fprintf (stderr, "Invalid video driver: %s\n", optarg); + } + break; + + default: + printf("Bad command line\n"); + } + + /* -o not specified, use a default driver */ + if (output_open == NULL) + output_open = drivers[0].open; + + if (optind < argc) { + in_file = fopen (argv[optind], "rb"); + if (!in_file) { + fprintf (stderr, "%s - could not open file %s\n", strerror (errno), + argv[optind]); + exit (1); + } + } else + in_file = stdin; +} + +static void decode_mpeg2 (uint8_t * current, uint8_t * end) +{ + const mpeg2_info_t * info; + int state; + vo_setup_result_t setup_result; + + mpeg2_buffer (mpeg2dec, current, end); + + info = mpeg2_info (mpeg2dec); + while (1) { + state = mpeg2_parse (mpeg2dec); + switch (state) { + case -1: + return; + case STATE_SEQUENCE: + /* might set nb fbuf, convert format, stride */ + /* might set fbufs */ + if (output->setup (output, info->sequence->width, + info->sequence->height, &setup_result)) { + fprintf (stderr, "display setup failed\n"); + exit (1); + } + if (setup_result.convert) + mpeg2_convert (mpeg2dec, setup_result.convert, NULL); + if (output->set_fbuf) { + uint8_t * buf[3]; + void * id; + + mpeg2_custom_fbuf (mpeg2dec, 1); + output->set_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + output->set_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + } else if (output->setup_fbuf) { + uint8_t * buf[3]; + void * id; + + output->setup_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + output->setup_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + output->setup_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + } + break; + case STATE_PICTURE: + /* might skip */ + /* might set fbuf */ + if (output->set_fbuf) { + uint8_t * buf[3]; + void * id; + + output->set_fbuf (output, buf, &id); + mpeg2_set_buf (mpeg2dec, buf, id); + } + if (output->start_fbuf) + output->start_fbuf (output, info->current_fbuf->buf, + info->current_fbuf->id); + break; + case STATE_PICTURE_2ND: + /* should not do anything */ + break; + case STATE_SLICE: + case STATE_END: + /* draw current picture */ + /* might free frame buffer */ + if (info->display_fbuf) { + output->draw (output, info->display_fbuf->buf, + info->display_fbuf->id); + } + if (output->discard && info->discard_fbuf) + output->discard (output, info->discard_fbuf->buf, + info->discard_fbuf->id); + break; + } + } +} + +static void es_loop (void) +{ + uint8_t * end; + + do { + end = buffer + fread (buffer, 1, BUFFER_SIZE, in_file); + decode_mpeg2 (buffer, end); + } while (end == buffer + BUFFER_SIZE); +} + +int main (int argc, char ** argv) +{ +#ifdef HAVE_IO_H + setmode (fileno (stdout), O_BINARY); +#endif + + fprintf (stderr, PACKAGE"-"VERSION + " - by Michel Lespinasse and Aaron Holtzman\n"); + + handle_args (argc, argv); + + output = output_open (); + if (output == NULL) { + fprintf (stderr, "Can not open output\n"); + return 1; + } + mpeg2dec = mpeg2_init (); + if (mpeg2dec == NULL) + exit (1); + + es_loop (); + + mpeg2_close (mpeg2dec); + if (output->close) + output->close (output); + return 0; +} diff --git a/vldp2/test/Makefile.am b/vldp2/test/Makefile.am new file mode 100644 index 000000000..479905e57 --- /dev/null +++ b/vldp2/test/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = regression tests tek-525 tek-625 compile globals +TESTS = regression compile globals diff --git a/vldp2/test/Makefile.in b/vldp2/test/Makefile.in new file mode 100644 index 000000000..182d28675 --- /dev/null +++ b/vldp2/test/Makefile.in @@ -0,0 +1,355 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EXTRA_DIST = regression tests tek-525 tek-625 compile globals +TESTS = regression compile globals +subdir = test +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = README Makefile.am Makefile.in compile +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu test/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -gt `echo "$$banner" | wc -c` && \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -gt `echo "$$banner" | wc -c` && \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -n "$$skipped" && echo "$$skipped"; \ + test -n "$$report" && echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool distclean distclean-generic distclean-libtool \ + distdir dvi dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/test/README b/vldp2/test/README new file mode 100644 index 000000000..560319fa8 --- /dev/null +++ b/vldp2/test/README @@ -0,0 +1,34 @@ +Please do use these tests if you do some libmpeg2 changes. + +* get the official suite of mpeg2 torture tests at +http://www.linuxvideo.org/mpeg2dec/files/mpeg2dec-streams.tar.gz + +or using CVS : + +# export CVSROOT=:pserver:anonymous@cvs.linuxvideo.org:/cvs/livid +# cvs login (Just press Return when prompted for a password) +# cvs checkout mpeg2dec-streams + +(OK, I did some reorganization work on the archive, so its not really the +official suite anymore) + +* extract this archive at the same level as your mpeg2dec directory : +in your working directory you should have subdirectories mpeg2dec and +mpeg2dec-streams. + +* change the "tests" file to indicate where you put these streams + +* set HACK_MODE 2 in libmpeg2/mpeg2_internal.h, because pgm and md5 +output modes currently only works with this change + +* go in the conformance directory and run ./regression + + is the name of the test suite you want to use. For the official +mpeg video conformance tests, just use "tests". + + is the type of IDCT you are using. If your machine supports MMX, +choose "mmx". If your machine uses the c idct, choose "c" + +That's it... + +walken diff --git a/vldp2/test/compile b/vldp2/test/compile new file mode 100644 index 000000000..25f8a45ae --- /dev/null +++ b/vldp2/test/compile @@ -0,0 +1,52 @@ +#!/bin/sh + +if test x"$srcdir" != x""; then + builddir="." # running from make check, but it does not define that +else + srcdir=`echo "$0" | sed s,[^/]*$,,` + test "$srcdir" = "$0" && srcdir=. + test -z "$srcdir" && srcdir=. + builddir="$srcdir" # running manually, have to assume +fi + +srcdir=`cd $srcdir;pwd` +builddir=`cd $builddir;pwd` + +basedir=".." +cd $srcdir; if [ ! -d $basedir -o ! -f $basedir/src/mpeg2dec.c -o \ + ! -f $basedir/mpeg2dec-*.tar.gz ]; then + cd ..; if [ ! -d $basedir -o ! -f $basedir/src/mpeg2dec.c -o \ + ! -f $basedir/mpeg2dec-*.tar.gz ]; then + exit 77 + fi +fi +basedir=`cd $basedir;pwd` + +cd $builddir +rm -fr compile_test + +for compiler in cc gcc gcc272 gcc-2.95 gcc-3.0 gcc-3.1 gcc-3.2 c89 \ + c++ g++ g++-2.95 g++-3.0 g++-3.1 \ + ccmalloc-gcc bgcc checkergcc tcc icc i586-mingw32msvc-gcc; do + compiler_path=`which $compiler` + if test x"$compiler_path" = x""; then continue; fi + + mkdir compile_test + cd compile_test; tar xzpf $basedir/mpeg2dec-*.tar.gz; cd mpeg2dec-* + case "$compiler" in + "i586-mingw32msvc-gcc") + opts="--host=i586-mingw32msvc --disable-sdl --enable-warnings" + if test -f "/usr/local/opt/ddraw/ddraw.h"; then + opts="$opts --with-directx=/usr/local/opt/ddraw" + fi;; + "c89") opts="";; + "ccmalloc-gcc") opts="--enable-warnings --enable-debug";; + "*") opts="--enable-warnings";; + esac + error=1; CC=$compiler ./configure $opts && make && error=0 + if test x"$error" != x"0"; then exit 1; fi + cd ../.. + rm -fr compile_test +done + +exit 0 diff --git a/vldp2/test/globals b/vldp2/test/globals new file mode 100644 index 000000000..b609010bc --- /dev/null +++ b/vldp2/test/globals @@ -0,0 +1,24 @@ +#!/bin/sh + +if test x"$srcdir" != x""; then + builddir="." # running from make check, but it does not define that +else + srcdir=`echo "$0" | sed s,[^/]*$,,` + test "$srcdir" = "$0" && srcdir=. + test -z "$srcdir" && srcdir=. + builddir="$srcdir" # running manually, have to assume +fi + +srcdir=`cd $srcdir;pwd` +builddir=`cd $builddir;pwd` + +bad_globals=`nm -g --defined-only $builddir/../libmpeg2/*.o|\ + awk '{if ($3) print $3}'|grep -v '^_\?mpeg2_'` + +if test x"$bad_globals" != x""; then + echo BAD GLOBAL SYMBOLS: + for s in $bad_globals; do echo $s; done + exit 1 +fi + +exit 0 diff --git a/vldp2/test/regression b/vldp2/test/regression new file mode 100644 index 000000000..e6da31538 --- /dev/null +++ b/vldp2/test/regression @@ -0,0 +1,60 @@ +#!/bin/sh + +if test x"$srcdir" != x""; then + builddir="." # running from make check, but it does not define that +else + srcdir=`echo "$0" | sed s,[^/]*$,,` + test "$srcdir" = "$0" && srcdir=. + test -z "$srcdir" && srcdir=. + builddir="$srcdir" # running manually, have to assume +fi + +srcdir=`cd $srcdir;pwd` +builddir=`cd $builddir;pwd` + +testfile="$srcdir/tests" +if [ $# -ge 1 ]; then testfile="$1"; fi + +dirs=`awk -F '#' '{print $1}' $testfile` + +basedir=`head -n 1 $testfile | awk '{print $2}'` +cd $srcdir; if [ ! -d $basedir ]; then + cd ..; if [ ! -d $basedir ]; then exit 77; fi # for make distcheck +fi +basedir=`cd $basedir;pwd` + +# choose between c_md5 and mmx_md5 (based on the idct you use) +md5=c.md5 +accel="-c" +if [ $# -ge 2 -a x"$2" != x"c" ]; then md5="$2.md5"; accel=""; fi + +cd $builddir +error=0 + +rm -fr data +mkdir data +cd data + +mpeg2dec="../../src/mpeg2dec"; if [ ! -x $mpeg2dec ]; then + if [ -x ../../vc++/Release/mpeg2dec.exe ]; then + mpeg2dec="../../vc++/Release/mpeg2dec.exe" + basedir=`echo "$basedir" | sed "s,/cygdrive/\(.\)/,\1:/,"` + elif [ -x ../../vc++/Debug/mpeg2dec.exe ]; then + mpeg2dec="../../vc++/Debug/mpeg2dec.exe" + basedir=`echo "$basedir" | sed "s,/cygdrive/\(.\)/,\1:/,"` + else + echo "Can not find mpeg2dec executable"; exit 1 + fi +fi + +for dir in $dirs; do + echo $dir + $mpeg2dec $accel -o md5 $basedir/$dir/stream >/dev/null 2>&1 >md5 + diff -wu md5 $basedir/$dir/$md5 || error=1 + rm -f md5 core +done + +cd .. +rmdir data + +exit $error diff --git a/vldp2/test/tek-525 b/vldp2/test/tek-525 new file mode 100644 index 000000000..033536d68 --- /dev/null +++ b/vldp2/test/tek-525 @@ -0,0 +1,89 @@ +#basedir ../../streams/tek/525 + +100b/015 # OK +100b/040 # OK +100b/060 # OK +100b/080 # OK +100b/120 # OK +#100b/180 # FAIL - 4:2:2 chroma +#100b/400 # FAIL - 4:2:2 chroma + +bbc3/015 # OK +bbc3/040 # OK +bbc3/060 # OK +bbc3/080 # OK +bbc3/120 # OK +#bbc3/180 # FAIL - 4:2:2 chroma +#bbc3/400 # FAIL - 4:2:2 chroma + +cact/015 # OK +cact/040 # OK +cact/060 # OK +cact/080 # OK +cact/120 # OK +#cact/180 # FAIL - 4:2:2 chroma +#cact/400 # FAIL - 4:2:2 chroma + +flwr/015 # OK +flwr/040 # OK +flwr/060 # OK +flwr/080 # OK +flwr/120 # OK +#flwr/180 # FAIL - 4:2:2 chroma +#flwr/400 # FAIL - 4:2:2 chroma + +mobl/015 # OK +mobl/040 # OK +mobl/060 # OK +mobl/080 # OK +mobl/120 # OK +#mobl/180 # FAIL - 4:2:2 chroma +#mobl/400 # FAIL - 4:2:2 chroma + +mulb/015 # OK +mulb/040 # OK +mulb/060 # OK +mulb/080 # OK +mulb/120 # OK +#mulb/180 # FAIL - 4:2:2 chroma +#mulb/400 # FAIL - 4:2:2 chroma + +pulb/015 # OK +pulb/040 # OK +pulb/060 # OK +pulb/080 # OK +pulb/120 # OK +#pulb/180 # FAIL - 4:2:2 chroma +#pulb/400 # FAIL - 4:2:2 chroma + +susi/015 # OK +susi/040 # OK +susi/060 # OK +susi/080 # OK +susi/120 # OK +#susi/180 # FAIL - 4:2:2 chroma +#susi/400 # FAIL - 4:2:2 chroma + +tens/015 # OK +tens/040 # OK +tens/060 # OK +tens/080 # OK +tens/120 # OK +#tens/180 # FAIL - 4:2:2 chroma +#tens/400 # FAIL - 4:2:2 chroma + +time/015 # OK +time/040 # OK +time/060 # OK +time/080 # OK +time/120 # OK +#time/180 # FAIL - 4:2:2 chroma +#time/400 # FAIL - 4:2:2 chroma + +v700/015 # OK +v700/040 # OK +v700/060 # OK +v700/080 # OK +v700/120 # OK +#v700/180 # FAIL - 4:2:2 chroma +#v700/400 # FAIL - 4:2:2 chroma diff --git a/vldp2/test/tek-625 b/vldp2/test/tek-625 new file mode 100644 index 000000000..48f111997 --- /dev/null +++ b/vldp2/test/tek-625 @@ -0,0 +1,89 @@ +#basedir ../../streams/tek/625 + +100b/015 # OK +100b/040 # OK +100b/060 # OK +100b/080 # OK +100b/120 # OK +#100b/180 # FAIL - 4:2:2 chroma +#100b/400 # FAIL - 4:2:2 chroma + +bbc3/015 # OK +bbc3/040 # OK +bbc3/060 # OK +bbc3/080 # OK +bbc3/120 # OK +#bbc3/180 # FAIL - 4:2:2 chroma +#bbc3/400 # FAIL - 4:2:2 chroma + +cact/015 # OK +cact/040 # OK +cact/060 # OK +cact/080 # OK +cact/120 # OK +#cact/180 # FAIL - 4:2:2 chroma +#cact/400 # FAIL - 4:2:2 chroma + +flwr/015 # OK +flwr/040 # OK +flwr/060 # OK +flwr/080 # OK +flwr/120 # OK +#flwr/180 # FAIL - 4:2:2 chroma +#flwr/400 # FAIL - 4:2:2 chroma + +mobl/015 # OK +mobl/040 # OK +mobl/060 # OK +mobl/080 # OK +mobl/120 # OK +#mobl/180 # FAIL - 4:2:2 chroma +#mobl/400 # FAIL - 4:2:2 chroma + +mulb/015 # OK +mulb/040 # OK +mulb/060 # OK +mulb/080 # OK +mulb/120 # OK +#mulb/180 # FAIL - 4:2:2 chroma +#mulb/400 # FAIL - 4:2:2 chroma + +pulb/015 # OK +pulb/040 # OK +pulb/060 # OK +pulb/080 # OK +pulb/120 # OK +#pulb/180 # FAIL - 4:2:2 chroma +#pulb/400 # FAIL - 4:2:2 chroma + +susi/015 # OK +susi/040 # OK +susi/060 # OK +susi/080 # OK +susi/120 # OK +#susi/180 # FAIL - 4:2:2 chroma +#susi/400 # FAIL - 4:2:2 chroma + +tens/015 # OK +tens/040 # OK +tens/060 # OK +tens/080 # OK +tens/120 # OK +#tens/180 # FAIL - 4:2:2 chroma +#tens/400 # FAIL - 4:2:2 chroma + +time/015 # OK +time/040 # OK +time/060 # OK +time/080 # OK +time/120 # OK +#time/180 # FAIL - 4:2:2 chroma +#time/400 # FAIL - 4:2:2 chroma + +v700/015 # OK +v700/040 # OK +v700/060 # OK +v700/080 # OK +v700/120 # OK +#v700/180 # FAIL - 4:2:2 chroma +#v700/400 # FAIL - 4:2:2 chroma diff --git a/vldp2/test/tests b/vldp2/test/tests new file mode 100644 index 000000000..3bb771d97 --- /dev/null +++ b/vldp2/test/tests @@ -0,0 +1,65 @@ +#basedir ../../mpeg2dec-streams + +teracom/teracom_vlc4 # OK - test all VLC tables +att/att_mismatch # OK - IDCT accuracy +compcore/ccm1 # OK - IDCT overflow +tek/Tek-5-long # OK - all macroblock types +tek/Tek-5.2 # OK - all macroblock types +ccett/mcp10ccett # OK - MC accuracy +tcela/tcela-17-dots # OK - long-range motion vectors +ti/TI_c1_2 # OK - field MC, interp +lep/bits_conf_lep_11 # OK - parser performance +sony/sony-ct1 # OK - field pictures, parsing flags +sony/sony-ct2 # OK - field pictures, parsing flags +sony/sony-ct3 # OK - field pictures, parsing flags +sony/sony-ct4 # OK - field pictures, parsing flags +hhi/hhi_burst_long # OK - field pictures, burst +hhi/hhi_burst_short # OK - field pictures, burst +tcela/tcela-10-killer # OK - field pictures, 16x8 MC bandwidth +tcela/tcela-8-fp-dp # OK - field pictures, DMV MC bandwidth +tcela/tcela-9-fp-dp # OK - field pictures, DMV MC bandwidth +tcela/tcela-16-matrices # OK - mpeg1 - quant matrixes transposition +tcela/tcela-19-wide # OK - mpeg1 - wide picture size +tcela/tcela-18-d-pict # OK - mpeg1 - D pictures +mei/MEI.stream16.long # OK - mpeg1 +mei/MEI.stream16v2 # OK - mpeg1 +ibm/ibm-bw-v3 # OK - DMV, decoder bandwidth, skipped MB +tcela/tcela-14-bff-dp # OK - DMV bottom first, MC bandwidth +tcela/tcela-14-bff-dp-short # OK - DMV bottom first, MC bandwidth +nokia/nokia6-60 # OK - DMV, MC bandwidth +nokia/nokia6 # OK - DMV, MC bandwidth +nokia/nokia_7 # OK - DMV, MC bandwidth +ntr/ntr_skipped_v3 # OK - DMV, low delay, skipped pictures +toshiba/toshiba_DPall-0 # OK - DMV, MC bandwidth +gi/gi4 # OK - intra dc precision, MC bandwidth +gi/gi6 # OK - intra dc precision, MC bandwidth +gi/gi7 # OK - intra dc precision, MC bandwidth +gi/gi_9 # OK - intra dc precision, MC bandwidth +gi/gi_from_tape # OK - intra dc precision, MC bandwidth +mei/mei.2conftest.4f # OK - vbv buffer size +mei/mei.2conftest.60f.new # OK - vbv buffer size +tceh/tceh_conf2 # OK - vbv buffer size +tcela/tcela-6-slices # OK - short slices +tcela/tcela-7-slices # OK - short slices +tcela/tcela-15-stuffing # OK - huge amounts of stuffing + + + +#the twilight zone streams are not part of the official mpeg2 test suite + +twilight_zone/walken/mpeg1_full_pix # OK - mpeg1 full pixel MC +twilight_zone/walken/mpeg1_stuffing # OK - mpeg1 macroblk stuffing +#twilight_zone/walken/mpeg1_start_slice # OK - weird mba at slice start +#twilight_zone/walken/mpeg1_slice # OK - general slice structure +twilight_zone/walken/repeat_sequence_bitrate # OK - variable bitrate value +twilight_zone/walken/progressive_12x12 # OK - progressive sequence +twilight_zone/walken/interlaced_12x12 # OK - nonprogressive sequence +twilight_zone/walken/very_high # OK - very high picture +twilight_zone/walken/very_wide # OK - very wide picture +twilight_zone/anonymous/anonymous # OK +twilight_zone/chromatic/chroma_dct_type-1 # OK +twilight_zone/tcela/tcela-12 # OK - IDCT drift - see 7.4.4 +#twilight_zone/mei/MEI.stream17.long # FAIL - different img sizes +#twilight_zone/mei/MEI2.stream17 # FAIL - different img sizes +#twilight_zone/tcela/tcela-11v2 # FAIL - IDCT overflow +# we're actually doing better than the reference decoder on tcela-11v2 diff --git a/vldp2/vc++/Makefile.am b/vldp2/vc++/Makefile.am new file mode 100644 index 000000000..87ce0ca9e --- /dev/null +++ b/vldp2/vc++/Makefile.am @@ -0,0 +1,25 @@ +DISTCLEANFILES = cpu_accel.obj yuv2rgb_mmx.obj cpu_state.obj \ + idct_mmx.obj motion_comp_mmx.obj + +EXTRA_DIST = config.h inttypes.h libmpeg2.dsp libvo.dsp mpeg2dec.dsp \ + mpeg2dec.dsw $(DISTCLEANFILES) + +WIN_GCC = i586-mingw32msvc-gcc -I$(top_srcdir)/vc++ -I$(top_srcdir)/include \ + -Wall -Werror -O3 -fomit-frame-pointer -mcpu=pentiumpro + +cpu_accel.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/cpu_accel.c -o cpu_accel.obj + +cpu_state.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/cpu_state.c -o cpu_state.obj + +idct_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/idct_mmx.c -o idct_mmx.obj + +motion_comp_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/motion_comp_mmx.c -o motion_comp_mmx.obj + +yuv2rgb_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libvo/yuv2rgb_mmx.c -o yuv2rgb_mmx.obj + +FORCE: diff --git a/vldp2/vc++/Makefile.in b/vldp2/vc++/Makefile.in new file mode 100644 index 000000000..83124eb62 --- /dev/null +++ b/vldp2/vc++/Makefile.in @@ -0,0 +1,308 @@ +# Makefile.in generated by automake 1.7.1 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INCLUDES = @INCLUDES@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@ +LIBMPEG2_LIBS = @LIBMPEG2_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBVO_CFLAGS = @LIBVO_CFLAGS@ +LIBVO_LIBS = @LIBVO_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SDLCONFIG = @SDLCONFIG@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +DISTCLEANFILES = cpu_accel.obj yuv2rgb_mmx.obj cpu_state.obj \ + idct_mmx.obj motion_comp_mmx.obj + + +EXTRA_DIST = config.h inttypes.h libmpeg2.dsp libvo.dsp mpeg2dec.dsp \ + mpeg2dec.dsw $(DISTCLEANFILES) + + +WIN_GCC = i586-mingw32msvc-gcc -I$(top_srcdir)/vc++ -I$(top_srcdir)/include \ + -Wall -Werror -O3 -fomit-frame-pointer -mcpu=pentiumpro + +subdir = vc++ +mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = Makefile.am Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu vc++/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + + +cpu_accel.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/cpu_accel.c -o cpu_accel.obj + +cpu_state.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/cpu_state.c -o cpu_state.obj + +idct_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/idct_mmx.c -o idct_mmx.obj + +motion_comp_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libmpeg2/motion_comp_mmx.c -o motion_comp_mmx.obj + +yuv2rgb_mmx.obj: FORCE + $(WIN_GCC) -c $(top_srcdir)/libvo/yuv2rgb_mmx.c -o yuv2rgb_mmx.obj + +FORCE: +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/vldp2/vc++/config.h b/vldp2/vc++/config.h new file mode 100644 index 000000000..7cb6e5489 --- /dev/null +++ b/vldp2/vc++/config.h @@ -0,0 +1,149 @@ +/* vc++/config.h - manually adapted from include/config.h.in */ + +/* autodetect accelerations */ +#define ACCEL_DETECT + +/* alpha architecture */ +/* #undef ARCH_ALPHA */ + +/* ppc architecture */ +/* #undef ARCH_PPC */ + +/* x86 architecture */ +#define ARCH_X86 + +/* maximum supported data alignment */ +/* #undef ATTRIBUTE_ALIGNED_MAX */ + +/* debug mode configuration */ +/* #undef DEBUG */ + +/* Define if you have the `__builtin_expect' function. */ +/* #undef HAVE_BUILTIN_EXPECT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DDRAW_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the `ftime' function. */ +#define HAVE_FTIME 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_IO_H 1 + +/* Define to 1 if you have the `memalign' function. */ +/* #undef HAVE_MEMALIGN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMEB_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* libmpeg2 mediaLib support */ +/* #undef LIBMPEG2_MLIB */ + +/* libvo DirectX support */ +#define LIBVO_DX + +/* libvo mediaLib support */ +/* #undef LIBVO_MLIB */ + +/* libvo SDL support */ +/* #undef LIBVO_SDL */ + +/* libvo X11 support */ +/* #undef LIBVO_X11 */ + +/* libvo Xv support */ +/* #undef LIBVO_XV */ + +/* Name of package */ +#define PACKAGE "mpeg2dec" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* The size of a `char', as computed by sizeof. */ +#define SIZEOF_CHAR 1 + +/* The size of a `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of a `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.3.1" + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to 1 if the X Window System is missing or not being used. */ +#define X_DISPLAY_MISSING 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define as `__inline' if that's what the C compiler calls it, or to nothing + if it is not supported. */ +#define inline __inline + +/* Define as `__restrict' if that's what the C compiler calls it, or to + nothing if it is not supported. */ +// MPO : this #define causes problems on Visual Studio 2005 and doesn't seem to be used anyway. +//#define restrict __restrict + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ diff --git a/vldp2/vc++/cpu_accel.obj b/vldp2/vc++/cpu_accel.obj new file mode 100644 index 000000000..b5d5d3d04 Binary files /dev/null and b/vldp2/vc++/cpu_accel.obj differ diff --git a/vldp2/vc++/cpu_state.obj b/vldp2/vc++/cpu_state.obj new file mode 100644 index 000000000..f0fccc786 Binary files /dev/null and b/vldp2/vc++/cpu_state.obj differ diff --git a/vldp2/vc++/idct_mmx.obj b/vldp2/vc++/idct_mmx.obj new file mode 100644 index 000000000..d5dcbe5aa Binary files /dev/null and b/vldp2/vc++/idct_mmx.obj differ diff --git a/vldp2/vc++/inttypes.h b/vldp2/vc++/inttypes.h new file mode 100644 index 000000000..51f14e909 --- /dev/null +++ b/vldp2/vc++/inttypes.h @@ -0,0 +1,7 @@ +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; diff --git a/vldp2/vc++/libmpeg2.dsp b/vldp2/vc++/libmpeg2.dsp new file mode 100644 index 000000000..169d3575a --- /dev/null +++ b/vldp2/vc++/libmpeg2.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="libmpeg2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libmpeg2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libmpeg2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libmpeg2.mak" CFG="libmpeg2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libmpeg2 - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libmpeg2 - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libmpeg2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I "../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libmpeg2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "libmpeg2 - Win32 Release" +# Name "libmpeg2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libmpeg2\alloc.c +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\decode.c +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\header.c +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\idct.c +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\motion_comp.c +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\slice.c +# End Source File +# Begin Source File + +SOURCE=.\cpu_accel.obj +# End Source File +# Begin Source File + +SOURCE=.\cpu_state.obj +# End Source File +# Begin Source File + +SOURCE=.\idct_mmx.obj +# End Source File +# Begin Source File + +SOURCE=.\motion_comp_mmx.obj +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\include\mpeg2.h +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\mpeg2_internal.h +# End Source File +# Begin Source File + +SOURCE=..\libmpeg2\vlc.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vldp2/vc++/libvo.dsp b/vldp2/vc++/libvo.dsp new file mode 100644 index 000000000..f51b2e333 --- /dev/null +++ b/vldp2/vc++/libvo.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="libvo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libvo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libvo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libvo.mak" CFG="libvo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libvo - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libvo - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libvo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I "../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libvo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "libvo - Win32 Release" +# Name "libvo - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\libvo\video_out.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_dx.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_null.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_pgm.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_sdl.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_x11.c +# End Source File +# Begin Source File + +SOURCE=..\libvo\yuv2rgb.c +# End Source File +# Begin Source File + +SOURCE=.\yuv2rgb_mmx.obj +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\include\video_out.h +# End Source File +# Begin Source File + +SOURCE=..\libvo\video_out_internal.h +# End Source File +# Begin Source File + +SOURCE=..\libvo\yuv2rgb.h +# End Source File +# End Group +# End Target +# End Project diff --git a/vldp2/vc++/motion_comp_mmx.obj b/vldp2/vc++/motion_comp_mmx.obj new file mode 100644 index 000000000..6be317582 Binary files /dev/null and b/vldp2/vc++/motion_comp_mmx.obj differ diff --git a/vldp2/vc++/mpeg2dec.dsp b/vldp2/vc++/mpeg2dec.dsp new file mode 100644 index 000000000..8496b7efa --- /dev/null +++ b/vldp2/vc++/mpeg2dec.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="mpeg2dec" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mpeg2dec - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mpeg2dec.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mpeg2dec.mak" CFG="mpeg2dec - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mpeg2dec - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mpeg2dec - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mpeg2dec - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I "../include" /I "../src" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mpeg2dec - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "../include" /I "../src" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_CONFIG_H" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mpeg2dec - Win32 Release" +# Name "mpeg2dec - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\src\getopt.c +# End Source File +# Begin Source File + +SOURCE=..\src\gettimeofday.c +# End Source File +# Begin Source File + +SOURCE=..\src\mpeg2dec.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\src\getopt.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/vldp2/vc++/mpeg2dec.dsw b/vldp2/vc++/mpeg2dec.dsw new file mode 100644 index 000000000..9ffe06fe1 --- /dev/null +++ b/vldp2/vc++/mpeg2dec.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libmpeg2"=".\libmpeg2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "libvo"=".\libvo.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "mpeg2dec"=".\mpeg2dec.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libmpeg2 + End Project Dependency + Begin Project Dependency + Project_Dep_Name libvo + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/vldp2/vc++/yuv2rgb_mmx.obj b/vldp2/vc++/yuv2rgb_mmx.obj new file mode 100644 index 000000000..5753727d8 Binary files /dev/null and b/vldp2/vc++/yuv2rgb_mmx.obj differ diff --git a/vldp2/vldp/mpegscan.c b/vldp2/vldp/mpegscan.c new file mode 100644 index 000000000..ef1ab9823 --- /dev/null +++ b/vldp2/vldp/mpegscan.c @@ -0,0 +1,359 @@ + +/* + * mpegscan.c + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +/////////////////////////// + +/* + +Some mpeg header information that may be useful at some point. + +--------------------------- +PICTURE_CODING_EXT DETAILS: +--------------------------- + +Sample mpeg2 byte sequence: 00 00 01 B5 83 4F F3 59 80 + +the 8 in 0x83 = picture_coding_ext (in header.c) + +the 3 in 0xF3 means FRAME_PICTURE (progressive, not a field) + +if the high bit is set (for the byte that is 0x80) then it means the +picture is a progressive frame (I think!) + +--------------------- +SEQUENCE_EXT DETAILS: +--------------------- +Sample mpeg2 byte sequence: 00 00 01 B5 14 8A 00 01 00 00 + +1 in 0x14 = sequence_ext (in header.c) +bit 3 in 8A set means progressive frame, clear means non-progressive (I +think!) +bits 1 and 2: 00 = invalid, 01 (2) = 4:2:0, 10 (4) = 4:2:2 + +--------------------- +SEQUENCE_DISPLAY_EXT DETAILS: +--------------------- + +Sample mpeg2 byte sequence: 00 00 01 B5 25 06 06 06 0B 42 0F 00 + +2 in 0x25 = sequence_display_ext (in header.c) + +*/ + +#include +#include // for malloc +#include "mpegscan.h" + +unsigned char g_last_three[3] = { 0 }; // the last 3 bytes read +unsigned int g_last_three_loc[3] = { 0 }; // the position of the last 3 bytes read + +int g_last_three_pos = 0; +int g_iframe_count = 0; +int g_pframe_count = 0; +int g_bframe_count = 0; +int g_gop_count = 0; // group of picture count +int g_curframe = 0; +unsigned int g_goppos = 0; +unsigned int g_filepos = 0; // where we are in the file +unsigned int g_frame_type = 0; // I, P, B frame, etc +unsigned int g_last_header_pos = 0; // the position of the last header we've parsed + +int g_fields_detected = 0; // whether the stream uses fields +int g_frames_detected = 0; // whether the stream uses frames (these are both here to detect errors) + +enum { IN_NOTHING, IN_PIC, IN_PIC_EXT }; +int g_status = 0; // whether we are in a special area (inside a picture header, for example) +int g_rel_pos = 0; // which byte of the special area we are in (relative position) + +// 1 = sequence_ext, 2 = sequence_display_ext, 8 = picture_coding_ext +unsigned char g_ext_type = 0; + +///////////////////////////////////////////////// + +// resets all state variables to their initial values. This needs to be called every time an mpeg is parsed +void init_mpegscan() +{ + int i = 0; + + // clear arrays + for (i = 0; i < 3; i++) + { + g_last_three[i] = 0; + g_last_three_loc[i] = 0; + } + g_last_three_pos = 0; + g_iframe_count = 0; + g_pframe_count = 0; + g_bframe_count = 0; + g_gop_count = 0; // group of picture count + g_curframe = 0; + g_goppos = 0; + g_filepos = 0; // where we are in the file + g_frame_type = 0; + g_last_header_pos = 0; + g_status = 0; + g_rel_pos = 0; + g_fields_detected = 0; // assume we don't use fields + g_frames_detected = 0; // " " " frames + g_ext_type = 0; +} + +// return the last 3 bytes that have been read, storing them in a, b, and c +// a is the most recent byte, c is the oldest +// for example, a header of 0 0 1 would be a = 1, b = 0, c = 0 +// header is the position of the 'c' byte (oldest byte) +void get_last_three(unsigned char *a, unsigned char *b, unsigned char *c, unsigned int *header) +{ + + int count = 0; + unsigned char result[3] = { 0 }; + int pos = g_last_three_pos; + + while (count < 3) + { + pos--; + if (pos < 0) + { + pos = 2; + } + + result[count] = g_last_three[pos]; + *header = g_last_three_loc[pos]; // this works out so that the oldest value is the final value + count++; + } + + *a = result[0]; // newest + *b = result[1]; + *c = result[2]; // oldest + +} + + +// updates the last 3 values that we've read, replacing the oldest one with 'val' +// pos is the position of the 'val' in the file +void add_to_last_three(unsigned char val, unsigned int pos) +{ + g_last_three[g_last_three_pos] = val; + g_last_three_loc[g_last_three_pos] = pos; + g_last_three_pos++; + if (g_last_three_pos > 2) + { + g_last_three_pos = 0; + } +} + +// parses from file stream, length # of bytes +// writes results to the open datafile +// returns stat codes +int parse_video_stream(FILE *datafile, unsigned int length) +{ + int result = P_IN_PROGRESS; + int ch = 0; + unsigned int start_pos = g_filepos; + const int minus_one = -1; + unsigned int buf_index = 0; + size_t bytes_read = 0; + unsigned char *buf = (unsigned char *) malloc(length); // allocate a chunk of memory to read in file + + if (!buf) + { + return P_ERROR; + } + + bytes_read = io_read(buf, length); // read in a chunk + + // parse this chunk of video + while (g_filepos - start_pos < length) + { + // this should always be true unless we hit EOF + if (buf_index < bytes_read) + { + g_filepos++; + g_rel_pos++; + ch = buf[buf_index++]; + } + // if we've hit EOF + else + { + // if we're certain we're using fields + if ((g_fields_detected) && (!g_frames_detected)) + { + result = P_FINISHED_FIELDS; + } + // else if we're certain we're not using fields + // (for mpeg1 g_fields_detected and g_frames_detected will both be 0) + else if (!g_fields_detected) + { + result = P_FINISHED_FRAMES; + } + // else we can't determine what's going on, so do an error to be safe + else + { + result = P_ERROR; + } + break; // end loop + } + + // We must make sure we only process 1 byte per iteration of this loop so that we don't + // exceed the maximum length. + + // if we are in the middle of a frame header + if (g_status == IN_PIC) + { + // if we need the first byte following a frame header + if (g_rel_pos == 0) + { + g_frame_type = ch << 8; + } + // else if we need the second byte following a frame header + else if (g_rel_pos == 1) + { + g_frame_type = g_frame_type | ch; + g_frame_type = (g_frame_type >> 3) & 3; // isolate frame type + + // examine which type of frame we've found + switch (g_frame_type) + { + case 1: // I frame + g_iframe_count++; + fwrite(&g_last_header_pos, sizeof(g_last_header_pos), 1, datafile); // actual beginning of I frame +#ifdef VLDP_DEBUG +// fprintf(stderr, "Found an I frame at %x\n", g_last_header_pos); +#endif + break; + default: // if it's not an I frame, just write -1 + fwrite(&minus_one, sizeof(minus_one), 1, datafile); +#ifdef VLDP_DEBUG +// fprintf(stderr, "Found a non I frame at %x\n", g_last_header_pos); +#endif + break; + } + g_status = IN_NOTHING; // we got what we came for, now get it :) + } // end if we are on the second byte of the picture + } // end if we're in a frame header + + // if we're in a picture header extension ... + else if (g_status == IN_PIC_EXT) + { + // if we're about to get the EXT type + if (g_rel_pos == 0) + { + g_ext_type = ch >> 4; + } + + // UPDATE : It seems that this information is just a hint of whether the mpeg is interlaced or progressive, and + // may be wrong, so we cannot rely on this information. + /* + // if we have ext type 1 (sequence_ext) then we can see if it's frames or fields + else if ((g_rel_pos == 1) && (g_ext_type == 1)) + { + // are we progressive? + if (ch & 8) + { + g_frames_detected = 1; + } + // else we're using fields + else + { + g_fields_detected = 1; + } + g_status = IN_NOTHING; + } + */ + + // this is where we either find out if we're using fields/frames or eject + else if (g_rel_pos >= 2) + { + // if we have ext type 8, then we can see if this uses frames or fields + if ((g_rel_pos == 2) && (g_ext_type == 8)) + { + unsigned char u8Val = ch & 3; + + // we need to detect whether the stream uses fields so we can adjust our searches accordingly + // 1 is the code for TOP FIELD, 2 is the code for BOTTOM_FIELD + if ((u8Val == 1) || (u8Val == 2)) + { + g_fields_detected = 1; + } + + // 3 is code for a full image + else if (u8Val == 3) + { + g_frames_detected = 1; + } + } // end if ext type is 8 ... + // else other ext type which we ignore ... + + // when we get this far, we are done parsing EXT ... + g_status = IN_NOTHING; + } + + } + + // if we are in nothing, looking for a new header + else + { + unsigned char header[3] = { 0 }; + + get_last_three(&header[0], &header[1], &header[2], &g_last_header_pos); + + // if we're at a place where a header is + if ((header[2] == 0) && (header[1] == 0) && (header[0] == 1)) + { + + // see what type of header this is + switch (ch) + { + case 0: // video frame + g_curframe++; // advance frame pointer + g_rel_pos = -1; // this gets incremented to 0 before we check, and I wanted 0 to mean 1st byte + g_status = IN_PIC; + break; + case 0xB3: // sequence header + break; + case 0xB5: // extension header + g_rel_pos = -1; + g_status = IN_PIC_EXT; + break; + case 0xB8: // Group of Picture + g_goppos = g_last_header_pos; + g_gop_count++; +#ifdef VLDP_DEBUG + fprintf(stderr, "Got GOP at %x\n", g_goppos); +#endif + break; + default: + break; + } // end switch + } // end if we found a header + } // end if we are looking for a new header + + add_to_last_three((unsigned char) ch, g_filepos - 1); + + } // end while we're not done with video stream + + free(buf); // de-allocate buffer + + return result; + +} diff --git a/vldp2/vldp/mpegscan.h b/vldp2/vldp/mpegscan.h new file mode 100644 index 000000000..2ba364375 --- /dev/null +++ b/vldp2/vldp/mpegscan.h @@ -0,0 +1,26 @@ +/* + * mpegscan.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +enum { P_ERROR, P_IN_PROGRESS, P_FINISHED_FRAMES, P_FINISHED_FIELDS }; + +void init_mpegscan(); +int parse_video_stream(FILE *datafile, unsigned int length); diff --git a/vldp2/vldp/vldp.c b/vldp2/vldp/vldp.c new file mode 100644 index 000000000..1f06eeb70 --- /dev/null +++ b/vldp2/vldp/vldp.c @@ -0,0 +1,399 @@ +/* + * vldp.c + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// see vldp.h for documentation on how to use the API + +#include +#include +#include "vldp.h" +#include "vldp_common.h" + +#define API_VERSION 11 + +////////////////////////////////////////////////////////////////////////////////////// + +int vldp_cmd(int cmd); +int vldp_wait_for_status(int stat); + +////////////////////////////////////////////////////////////////////////////////////// + +SDL_Thread *private_thread = NULL; + +int p_initialized = 0; // whether VLDP has been initialized + +Uint8 g_req_cmdORcount = CMDORCOUNT_INITIAL; // the current command parent thread requests of the child thread +unsigned int g_ack_count = ACK_COUNT_INITIAL; // the result returned by the internal child thread +char g_req_file[STRSIZE]; // requested mpeg filename +Uint32 g_req_timer = 0; // requests timer value to be used for mpeg playback +Uint32 g_req_frame = 0; // requested frame to search to +Uint32 g_req_min_seek_ms = 0; // seek must take at least this many milliseconds (simulate laserdisc seek delay) +unsigned int g_req_precache = VLDP_FALSE; // whether g_req_idx has any meaning +unsigned int g_req_idx = 0; // multipurpose index (used by precaching) +unsigned int g_req_skip_per_frame = 0; // how many frames to skip per frame (for playing at 2X for example) +unsigned int g_req_stall_per_frame = 0; // how many frames to stall per frame (for playing at 1/2X for example) +struct vldp_out_info g_out_info; // contains info that the parent thread should have access to +const struct vldp_in_info *g_in_info; // contains info from parent thread that VLDP should have access to + +///////////////////////////////////////////////////////////////////// + +// issues a command to the internal thread and returns 1 if the internal thread acknowledged our command +// or 0 if we timed out without getting a response +// NOTE : this does not mean that the internal thread has finished executing our requested command, only +// that the command has been received +int vldp_cmd(int cmd) +{ + int result = 0; + Uint32 cur_time = g_in_info->GetTicksFunc(); + Uint8 tmp = g_req_cmdORcount; // we want to replace the real value atomically so we use a tmp variable first + static unsigned int old_ack_count = ACK_COUNT_INITIAL; + + tmp++; // increment the counter so child thread knows we're issuing a new command + tmp &= 0xF; // strip off old command + tmp |= cmd; // replace it with new command + g_req_cmdORcount = tmp; // here is the atomic replacement + + // loop until we timeout or get a response + while ((g_in_info->GetTicksFunc() - cur_time) < VLDP_TIMEOUT) + { + // if the count has changed, it means the other thread has acknowledged our new command + if (g_ack_count != old_ack_count) + { + result = 1; + old_ack_count = g_ack_count; // prepare to receive the next command + break; + } + SDL_Delay(0); // switch to other thread + } + + // if we weren't able to communicate, notify user + if (!result) + { + fprintf(stderr, "VLDP error! Timed out waiting for internal thread to accept command!\n"); + } + + return result; +} + +// waits until the disc status is 'stat' +// if the stat we want is received, return 1 (success) +// if we time out, or if we get an error stat, return 0 (error) +// if we are legitimately busy, we return 2 (busy) +int vldp_wait_for_status(int stat) +{ + int result = 0; // assume error unless we explicitly + int done = 0; + Uint32 cur_time = g_in_info->GetTicksFunc(); + while (!done && ((g_in_info->GetTicksFunc() - cur_time) < VLDP_TIMEOUT)) + { + if (g_out_info.status == stat) + { + done = 1; + result = 1; + } + else if (g_out_info.status == STAT_ERROR) + { + done = 1; + } + // else keep waiting + SDL_Delay(0); // switch to other thread, timing is critical so we delay for 0 + } + + // if we timed out but are busy, indicate that + if (g_out_info.status == STAT_BUSY) + { + result = 2; + } + + // else if we timed out + else if ((g_in_info->GetTicksFunc() - cur_time) >= VLDP_TIMEOUT) + { + fprintf(stderr, "VLDP ERROR!!!! Timed out with getting our expected response!\n"); + } + + return result; +} + +////////////////////////////////////////////////////////// + +void vldp_shutdown() +{ + // only shutdown if we have previous initialized + if (p_initialized) + { + vldp_cmd(VLDP_REQ_QUIT); + SDL_WaitThread(private_thread, NULL); // wait for private thread to terminate + } + p_initialized = 0; +} + +// requests that we open an mpeg file +// IMPORTANT : This function returns immediately once the open command is received, but the +// file will not be open until the VLDP status is 'VLDP_STOPPED'. Parent thread take heed. +int vldp_open(const char *filename) +{ + int result = 0; // assume we're busy so the loop below works the first time + FILE *F = NULL; + + if (p_initialized) + { + F = fopen(filename, "rb"); + // if file exists, we can open it + if (F) + { + fclose(F); + SAFE_STRCPY(g_req_file, filename, sizeof(g_req_file)); + g_req_precache = VLDP_FALSE; // we're not precaching ... + result = vldp_cmd(VLDP_REQ_OPEN); + } + else + { + fprintf(stderr, "VLDP ERROR : can't open file %s\n", filename); + } + } + + return result; +} + +VLDP_BOOL vldp_open_precached(unsigned int uIdx, const char *filename) +{ + VLDP_BOOL bResult = VLDP_FALSE; + + if (p_initialized) + { + // even though we're using an index, we still need filename to compute .dat filename + SAFE_STRCPY(g_req_file, filename, sizeof(g_req_file)); + g_req_idx = uIdx; + g_req_precache = VLDP_TRUE; + bResult = vldp_cmd(VLDP_REQ_OPEN); + } + + return bResult; +} + +int vldp_open_and_block(const char *filename) +{ + int result = 0; + + result = vldp_open(filename); + + // if the open message was received ... + if (result) + { + result = 2; // 2 is the code that wait_for_status returns when it is busy ... + while (result == 2) + { + result = vldp_wait_for_status(STAT_STOPPED); + SDL_Delay(1); // timing isn't critical here, so we can delay for 1 instead of 0 + } + } + + return result; +} + +VLDP_BOOL vldp_precache(const char *filename) +{ + VLDP_BOOL bResult = VLDP_FALSE; + + if (p_initialized) + { + SAFE_STRCPY(g_req_file, filename, sizeof(g_req_file)); + bResult = vldp_cmd(VLDP_REQ_PRECACHE); + } + // else return false + + return bResult; +} + +// issues search command and returns immediately to parent thread. +// Search will not be complete until the VLDP status is STAT_PAUSED +int vldp_search(Uint32 frame, Uint32 min_seek_ms) +{ + int result = 0; + + if (p_initialized) + { + g_req_frame = frame; + g_req_min_seek_ms = min_seek_ms; + result = vldp_cmd(VLDP_REQ_SEARCH); + } + return result; +} + +// issues search command blocks until search is complete +int vldp_search_and_block(Uint32 frame, Uint32 min_seek_ms) +{ + int result = 0; + + if (p_initialized) + { + g_req_frame = frame; + g_req_min_seek_ms = min_seek_ms; + vldp_cmd(VLDP_REQ_SEARCH); + result = vldp_wait_for_status(STAT_PAUSED); + } + return result; +} + +int vldp_play(Uint32 timer) +{ + int result = 0; + + if (p_initialized) + { + g_req_timer = timer; + vldp_cmd(VLDP_REQ_PLAY); + result = vldp_wait_for_status(STAT_PLAYING); // play could get an error if we're at EOF + } + return(result); +} + +int vldp_skip(Uint32 frame) +{ + int result = 0; + + // we can only skip if the mpeg is already playing (esp. since we don't accept a timer as an argument) + if (p_initialized && (g_out_info.status == STAT_PLAYING)) + { + g_req_frame = frame; + g_req_min_seek_ms = 0; // just for safety purposes, we want to ensure that there is no minimum skip delay + result = vldp_cmd(VLDP_REQ_SKIP); +#ifdef VLDP_DEBUG + if (!result) fprintf(stderr, "vldp_cmd rejected SKIP request!\n"); +#endif + } + +#ifdef VLDP_DEBUG + // remove me once this bug is discovered + else + { + fprintf(stderr, "VLDP skip failed because one of these happened: \n"); + fprintf(stderr, "p_initialized is %d\n", p_initialized); + fprintf(stderr, "g_out_info.status == %d\n", g_out_info.status); + } +#endif // VLDP_DEBUG + + return result; +} + +int vldp_pause() +{ + int result = 0; + if (p_initialized) + { + result = vldp_cmd(VLDP_REQ_PAUSE); + } + return result; +} + +int vldp_step_forward() +{ + int result = 0; + + if (p_initialized) + { + result = vldp_cmd(VLDP_REQ_STEP_FORWARD); + } + return result; +} + +int vldp_stop() +{ + return 0; // this is a useless function which I haven't finished yet anyway, so don't use it :) +} + +VLDP_BOOL vldp_speedchange(unsigned int uSkipPerFrame, unsigned int uStallPerFrame) +{ + VLDP_BOOL result = VLDP_FALSE; + + if (p_initialized) + { + g_req_skip_per_frame = uSkipPerFrame; + g_req_stall_per_frame = uStallPerFrame; + result = vldp_cmd(VLDP_REQ_SPEEDCHANGE); + } + return result; +} + +VLDP_BOOL vldp_lock(unsigned int uTimeoutMs) +{ + VLDP_BOOL result = VLDP_FALSE; + + if (p_initialized) + { + result = vldp_cmd(VLDP_REQ_LOCK); + } + return result; +} + +VLDP_BOOL vldp_unlock(unsigned int uTimeoutMs) +{ + VLDP_BOOL result = VLDP_FALSE; + + if (p_initialized) + { + result = vldp_cmd(VLDP_REQ_UNLOCK); + } + return result; +} + +/////////////////////////////////////////////////////////////////////////// + +// This comes at the end so I can avoid putting function declarations in vldp.h +// I want to keep these functions hidden and force the user to use the callbacks +const struct vldp_out_info *vldp_init(const struct vldp_in_info *in_info) +{ + const struct vldp_out_info *result = NULL; + p_initialized = 0; + + g_in_info = in_info; + + // So parent thread knows if it's compatible with us + g_out_info.uApiVersion = API_VERSION; + + // populate function pointers for parent thread's benefit + g_out_info.shutdown = vldp_shutdown; + g_out_info.open = vldp_open; + g_out_info.open_precached = vldp_open_precached; + g_out_info.open_and_block = vldp_open_and_block; + g_out_info.precache = vldp_precache; + g_out_info.play = vldp_play; + g_out_info.search = vldp_search; + g_out_info.search_and_block = vldp_search_and_block; + g_out_info.skip = vldp_skip; + g_out_info.pause = vldp_pause; + g_out_info.step_forward = vldp_step_forward; + g_out_info.stop = vldp_stop; + g_out_info.speedchange = vldp_speedchange; + g_out_info.lock = vldp_lock; + g_out_info.unlock = vldp_unlock; + + private_thread = SDL_CreateThread(idle_handler, NULL); // start our internal thread + + // if private thread was created successfully + if (private_thread) + { + p_initialized = 1; + result = &g_out_info; + } + + return result; +} diff --git a/vldp2/vldp/vldp.h b/vldp2/vldp/vldp.h new file mode 100644 index 000000000..d62ec2ebb --- /dev/null +++ b/vldp2/vldp/vldp.h @@ -0,0 +1,199 @@ +/* + * vldp.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// API for the mpeg2 virtual laserdisc player +// by Matt Ownby, Mar 16th, 2003 + +#ifndef VLDP_H +#define VLDP_H + +#ifdef __cplusplus +extern "C" { +#endif + +// by RDG2010 +// Ubuntu Linux complains with plain +#ifdef WIN32 +#include // only used for threading +#else +#include // only used for threading +#endif + +struct yuv_buf +{ + unsigned char *Y; // Y channel + unsigned char *U; // U channel + unsigned char *V; // V channel + unsigned int Y_size; // size in bytes of Y + unsigned int UV_size; // size in bytes of U and V +}; + +// safe strcpy that null-terminates the end of a string +// Use this instead of strcpy always! +#define SAFE_STRCPY(dst,src,size) strncpy(dst, src, size); dst[size-1] = 0; + +// since this is C and not C++, we can't use booleans ... +enum { VLDP_FALSE=0, VLDP_TRUE=1 } typedef VLDP_BOOL; + +// callback functions and state information provided to VLDP from the parent thread +struct vldp_in_info +{ + // VLDP calls this when it has a frame ready to draw, but before it has slept to maintain + // a consistent framerate. You should do all cpu-intensive cycles to prepare the frame + // to be drawn here. The remaining cycles you don't used will be used by VLDP to sleep + // until it's time for the frame to be displayed. + // This returns 1 if the frame was prepared successfully, or 0 on error + int (*prepare_frame)(struct yuv_buf *buf); + + // VLDP calls this when it wants the frame that was earlier prepared to be displayed + // ASAP + void (*display_frame)(struct yuv_buf *buf); + + // VLDP calls this when it is doing the time consuming process of reporting an mpeg parse + void (*report_parse_progress)(double percent_complete); + + // VLDP calls this to tell the parent-thread what the dimensions of the mpeg are (as soon we know ourselves!) + // This comes before draw_frame to that draw_frame can be more optimized + void (*report_mpeg_dimensions)(int width, int height); + + // VLDP calls this when it wants the parent-thread to render a blank frame + void (*render_blank_frame)(); + + /////////// + + int blank_during_searches; // if this is non-zero, VLDP will call render_blank_frame before every search + int blank_during_skips; // if this is non-zero, VLDP will call render_blank_frame before every skip + unsigned int uMsTimer; // the timer that VLDP will use for everything (replaces SDL_GetTicks()). Calling thread is responsible for updating this timer!! + + // Callback to get an arbitrary millisecond timer (such as SDL_GetTicks) + // (for instances when we know uMsTimer will not be updated, we will call this function instead) + unsigned int (*GetTicksFunc)(); +}; + +// functions and state information provided to the parent thread from VLDP +struct vldp_out_info +{ + // shuts down VLDP, de-allocates any memory that was allocated, etc ... + void (*shutdown)(); + + // All of the following functions return 1 on success, 0 on failure. + + // open an mpeg file and returns immediately. File won't actually be open until + // 'status' is equal to STAT_STOPPED. + int (*open)(const char *filename); + + // like 'open' except it blocks until 'status' is equal to STAT_STOPPED (until all potential parsing has finished, etc) + // does not return on STAT_BUSY + // returns 1 if status is STAT_STOPPED or 0 if status ended up to be something else + int (*open_and_block)(const char *filename); + + // Precaches the indicated file to memory, so that when 'open' is called, the file will + // be read from memory instead of the filesystem (for increased speed). + // IMPORTANT : file won't be precached until status == STAT_STOPPED + // Returns VLDP_TRUE if the precaching succeeded or VLDP_FALSE on failure. + VLDP_BOOL (*precache)(const char *filename); + + // Instructus VLDP to 'open' a file that has been precached. It is referred to + // by its precache index instead of a filename. Behavior is similar to 'open'. + VLDP_BOOL (*open_precached)(unsigned int uIdx, const char *filename); + + // plays the mpeg that has been previously open. 'timer' is the value relative to uMsTimer that + // we should use for the beginning of the first frame that will be displayed + // returns 0 on failure, 1 on success, 2 on busy + int (*play)(Uint32 timer); + + // searches to a frame relative to the beginning of the mpeg (0 is the first frame) + // 'min_seek_ms' is the minimum # of milliseconds that this seek must take + // (for the purpose of simulating laserdisc seek delay) + // returns immediately, but search is not complete until 'status' is STAT_PAUSED + // returns 1 if command was acknowledged, or 0 if we timed out w/o getting acknowlegement + int (*search)(Uint32 frame, Uint32 min_seek_ms); + + // like search except it blocks until the search is complete + // 'min_seek_ms' is the minimum # of milliseconds that this seek must take + // (for the purpose of simulating laserdisc seek delay) + // returns 1 if search succeeded, 2 if search is still going, 0 if search failed + // (so does not do true blocking, we could change this later) + int (*search_and_block)(Uint32 frame, Uint32 min_seek_ms); + + // skips to 'frame' and immediately begins playing. + // the mpeg is required to be playing before skip is called, because we accept no new timer as reference + int (*skip)(Uint32 frame); + + // pauses mpeg playback + int (*pause)(); + + // steps one frame forward while paused + int (*step_forward)(); + + // stops playback + int (*stop)(); + + // Changes the speed of playback (while still maintaining framerate) + // For example, to get 2X, uSkipPerFrame = 1, uStallPerFrame = 0 + // To get 3X, uSkipPerFrame = 2, uStallPerFrame = 0 + // To get 1/2X, uSkipPerFrame = 0, uStallPerFrame = 1 + VLDP_BOOL (*speedchange)(unsigned int uSkipPerFrame, unsigned int uStallPerFrame); + + // Attempts to make sure the VLDP sits idly (mainly to prevent it from calling any callbacks) + // Returns true if VLDP has been locked, or false if we timed out + VLDP_BOOL (*lock)(unsigned int uTimeoutMs); + + // Unlocks a previous lock operation. Returns true if unlock was successful, or false if we timed out. + VLDP_BOOL (*unlock)(unsigned int uTimeoutMs); + + //////////////////////////////////////////////////////////// + + // State information for the parent thread's benefit + unsigned int uApiVersion; // so parent thread knows if it's compatible with this version of VLDP + unsigned int uFpks; // FPKS = frames per kilosecond (FPS = uFpks / 1000.0) + unsigned int u2milDivFpks; // (2000000) / uFpks (pre-calculated, used to determine whether to drop frames) + Uint8 uses_fields; // whether the video uses fields or not + Uint32 w; // width of the mpeg video + Uint32 h; // height of the mpeg video + int status; // the current status of the VLDP (see STAT_ enum's) + unsigned int current_frame; // the current frame of the opened mpeg that we are on + unsigned int uLastCachedIndex; // the index of the file that was last precached (if any) +}; + +enum +{ + STAT_ERROR, STAT_BUSY, STAT_STOPPED, STAT_PLAYING, STAT_PAUSED +}; + +#ifdef WIN32 +// this is the only function that gets exported by this DLL +__declspec(dllexport) const struct vldp_out_info *vldp_init(const struct vldp_in_info *in_info); +#else + +// initializes the VLDP +// 'in_info' contains a few callback functions from parent thread that VLDP needs to use +// returns a pointer to output functions on success or NULL on failure +const struct vldp_out_info *vldp_init(const struct vldp_in_info *in_info); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // VLDP_H diff --git a/vldp2/vldp/vldp_common.h b/vldp2/vldp/vldp_common.h new file mode 100644 index 000000000..5e9b8b325 --- /dev/null +++ b/vldp2/vldp/vldp_common.h @@ -0,0 +1,77 @@ +/* + * vldp_common.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// shared by the public and private VLDP threads +// nothing else should include this + +#ifndef VLDP_COMMON_H +#define VLDP_COMMON_H + +#include +#include + +#define VLDP_REQ_NONE 0x0 +#define VLDP_REQ_OPEN 0x10 +#define VLDP_REQ_SEARCH 0x20 +#define VLDP_REQ_PLAY 0x30 +#define VLDP_REQ_PAUSE 0x40 +#define VLDP_REQ_STEP_FORWARD 0x50 +#define VLDP_REQ_STOP 0x60 +#define VLDP_REQ_STATUS 0x70 +#define VLDP_REQ_QUIT 0x80 +#define VLDP_REQ_SKIP 0x90 +#define VLDP_REQ_LOCK 0xA0 +#define VLDP_REQ_UNLOCK 0xB0 +#define VLDP_REQ_SPEEDCHANGE 0xC0 +#define VLDP_REQ_PRECACHE 0xD0 + +// these are defined to emphasize the importance of the same value being initialized in more than one place +#define CMDORCOUNT_INITIAL 0 +#define ACK_COUNT_INITIAL 0 + +// how big all our character arrays will be +// (needs to be able to accomodate huge paths) +#define STRSIZE 320 + +extern Uint32 g_req_frame; // which frame to seek to +extern Uint32 g_req_min_seek_ms; // minimum # of milliseconds that this seek can take +extern Uint32 g_req_timer; +extern unsigned int g_req_idx; // multipurpose index +extern unsigned int g_req_precache; +extern char g_req_file[]; // which file to open +extern Uint8 g_req_cmdORcount; // the current command count OR'd with the current command of parent thread + // made 8-bit to ensure that it's atomic +extern unsigned int g_ack_count; // how many times we've acknowledged a command + +extern struct vldp_out_info g_out_info; // contains info that the parent thread should have access to +extern const struct vldp_in_info *g_in_info; // contains info from parent thread that VLDP should have access to + +extern unsigned int g_req_skip_per_frame; // how many frames to skip per frame (for playing at 2X for example) +extern unsigned int g_req_stall_per_frame; // how many frames to stall per frame (for playing at 1/2X for example) + +int idle_handler(void *); + +// how ms to wait for responses from the private thread before we give up and return an error +// NOTE : increased from 5000 now that artificial seek delay functionality is added +#define VLDP_TIMEOUT 7500 + +#endif diff --git a/vldp2/vldp/vldp_internal.c b/vldp2/vldp/vldp_internal.c new file mode 100644 index 000000000..0d3d06177 --- /dev/null +++ b/vldp2/vldp/vldp_internal.c @@ -0,0 +1,1389 @@ +/* + * vldp_internal.c + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// contains the function for the VLDP private thread + +#include +#include // for malloc/free +#include +#include +#include +//#include +//#include "inttypesreplace.h" +#include + +#include "vldp_internal.h" +#include "vldp_common.h" +#include "mpegscan.h" + +#ifdef WIN32 +#include "../vc++/inttypes.h" +#else +#include +#endif + +#include "mpeg2.h" +#include "video_out.h" + +///////////////////////////// + +// NOTICE : these variables should only be used by the private thread !!!!!!!!!!!! + +Uint8 s_old_req_cmdORcount = CMDORCOUNT_INITIAL; // the last value of the command byte we received +int s_paused = 0; // whether the video is to be paused +int s_step_forward = 0; // whether to step 1 frame forward +int s_blanked = 0; // whether the mpeg video is to be blanked +int s_frames_to_skip = 0; // how many frames to skip before rendering the next frame (used for P and B frames seeking) +int s_frames_to_skip_with_inc = 0; // // how many frames to skip while increasing the frame number (for multi-speed playback) +int s_skip_all = 0; // if we are to skip any frame to be displayed (to avoid seeing frames we shouldn't) + +// How many frames we've skipped when s_skip_all is enabled. +// (for performance tuning, we want to minimize this number) +unsigned int s_uSkipAllCount = 0; + +Uint32 s_timer = 0; // FPS timer used by the blitting code to run at the right speed + +// any extra delay that null_draw_frame() will use before drawing a frame (intended for laserdisc seek delay simulation) +// NOTE : this value gets reset to 0 after it has been 'used' +Uint32 s_extra_delay_ms = 0; + +// how many frames must have been displayed (relative to s_timer!!!) +// before we advance to the next frame +Uint32 s_uFramesShownSinceTimer = 0; + +// which frame we've skipped to (0 if there is nothing pending) +unsigned int s_uPendingSkipFrame = 0; + +// multi-speed variables ... +unsigned int s_skip_per_frame = 0; // how many frames to skip per frame (for playing at 2X for example) +unsigned int s_stall_per_frame = 0; // how many frames to stall per frame (for playing at 1/2X for example) + +// pre-cache variables +#define MAX_PRECACHE_FILES 300 /* maximum number of files that we'll pre-cache */ +VLDP_BOOL s_bPreCacheEnabled = VLDP_FALSE; // whether precaching is currently enabled +unsigned int s_uCurPreCacheIdx = 0; // if pre-caching is enabled, which index is currently being used +unsigned int s_uPreCacheIdxCount = 0; // how many files have been precached +struct precache_entry_s s_sPreCacheEntries[MAX_PRECACHE_FILES]; // struct array holding precache data + + +#define MAX_LDP_FRAMES 430000 // rdg2010: Anbou 4 hours at 30 frames per second + +static FILE *g_mpeg_handle = NULL; // mpeg file we currently have open +static mpeg2dec_t *g_mpeg_data = NULL; // structure for libmpeg2's state +static vo_instance_t *s_video_output = NULL; +static Uint32 g_frame_position[MAX_LDP_FRAMES] = { 0 }; // the file position of each I frame +static Uint32 g_totalframes = 0; // total # of frames in the current mpeg + +#define BUFFER_SIZE 524288 //262144 rdg2010 +static Uint8 g_buffer[BUFFER_SIZE]; // buffer to hold mpeg2 file as we read it in + +#define HEADER_BUF_SIZE 200 +static Uint8 g_header_buf[HEADER_BUF_SIZE]; +static unsigned int g_header_buf_size = 0; // size of the header buffer + +// how many frames we will stall after beginning playback (should be 1, because presumably before we start playing, +// the disc has been paused showing the same frame, and we want the frame to display 1 more frame before moving +// to the next one. This behavior is somewhat arbitrary to act like we think laserdisc players act, but this +// value could also be proven to be 0 if someone does future research.) +#define PLAY_FRAME_STALL 1 + +//////////////////////////////////////////////// + +// this is our video thread which gets called +int idle_handler(void *surface) +{ + int done = 0; + + s_video_output = (vo_instance_t *) vo_null_open(); // open 'null' driver (we just pass decoded frames to parent thread) + if (s_video_output) + { + g_mpeg_data = mpeg2_init(); + } + else + { + fprintf(stderr, "VLDP : Error opening LIBVO!\n"); + done = 1; + } + + // unless we are drawing video to the screen, we just sit here + // and listen for orders from the parent thread + while (!done) + { + // while we have received new commands to be processed + // (so we don't go to sleep on skips) + while (ivldp_got_new_command() && !done) + { + // examine the actual command (strip off the count) + switch(g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_QUIT: + done = 1; + break; + case VLDP_REQ_OPEN: + idle_handler_open(); + break; + case VLDP_REQ_PRECACHE: + idle_handler_precache(); + break; + case VLDP_REQ_PLAY: + idle_handler_play(); + break; + case VLDP_REQ_SEARCH: + idle_handler_search(0); + break; + case VLDP_REQ_SKIP: + idle_handler_search(1); + break; + case VLDP_REQ_PAUSE: // pause command while we're already idle? this is an error + case VLDP_REQ_STOP: // stop command while we're already idle? this is an error + g_out_info.status = STAT_ERROR; + ivldp_ack_command(); + break; + case VLDP_REQ_LOCK: + ivldp_lock_handler(); + break; + default: + fprintf(stderr, "VLDP WARNING : Idle handler received command which it is ignoring\n"); + break; + } // end switch + SDL_Delay(0); // give other threads some breathing room (but not much hehe) + } // end if we got a new command + + g_in_info->render_blank_frame(); // This makes sure that the video overlay gets drawn even if there is no video being played + + // we need to delay here because otherwise, this idle loop will execute at 100% cpu speed and really slow things down + // It shouldn't hurt us when we get a command that requires immediate attention (such as skip) because of the + // inner while loop above (while ivldp_got_new_command) + // NOTE : we want to delay for about 1 frame (or field) here + SDL_Delay(16); // 1 field is 16.666ms assuming 60 hz + + } // end while we have not received a quit command + + io_close(); + + + g_out_info.status = STAT_ERROR; + mpeg2_close(g_mpeg_data); // shutdown libmpeg2 + s_video_output->close(s_video_output); // shutdown null driver + + // de-allocate any files that have been precached + while (s_uPreCacheIdxCount > 0) + { + --s_uPreCacheIdxCount; + free(s_sPreCacheEntries[s_uPreCacheIdxCount].ptrBuf); + } + + ivldp_ack_command(); // acknowledge quit command + + return 0; +} + +// returns 1 if there is a new command waiting for us or 0 otherwise +int ivldp_got_new_command() +{ + int result = 0; + + // if they are no longer equal + if (g_req_cmdORcount != s_old_req_cmdORcount) + { + result = 1; + } + + return result; +} + +// acknowledges a command sent by the parent thread +// NOTE : We don't check to see if parent thread got our acknowledgement because it creates too much latency +void ivldp_ack_command() +{ + s_old_req_cmdORcount = g_req_cmdORcount; + g_ack_count++; // here is where we acknowledge +} + +void ivldp_lock_handler() +{ +#ifdef VLDP_DEBUG + fprintf(stderr, "DBG: VLDP REQ LOCK RECEIVED!!!\n"); +#endif + ivldp_ack_command(); + { + VLDP_BOOL bLocked = VLDP_TRUE; + + // the user should unlock immediately after locking, so we need not check for other commands + while (bLocked == VLDP_TRUE) + { + SDL_Delay(1); + if (ivldp_got_new_command()) + { + switch (g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_UNLOCK: +#ifdef VLDP_DEBUG + fprintf(stderr, "DBG: VLDP REQ UNLOCK RECEIVED!!!\n"); +#endif + ivldp_ack_command(); + bLocked = VLDP_FALSE; + break; + default: + fprintf(stderr, "WARNING : lock handler received a command %x that wasn't to unlock it\n", g_req_cmdORcount); + break; + } + } + } + } +} + +// the handler we call if we're paused... called from video_out_sdl +// this function is called from within a while loop +void paused_handler() +{ + // the moment we render the still frame, we need to reset the FPS timer so we don't try to catch-up + if (g_out_info.status != STAT_PAUSED) + { + g_out_info.status = STAT_PAUSED; + + // reset these vars because otherwise null_draw_frame will loop redundantly for no good reason + s_timer = g_in_info->uMsTimer; // since we have just rendered the frame we searched to, we refresh the timer + s_uFramesShownSinceTimer = 1; // this gives us a little breathing room + +#ifdef VLDP_DEBUG + printf("paused_handler() : status set to STAT_PAUSED, s_timer set to %u\n", g_in_info->uMsTimer); +#endif + } + + // if we have a new command coming in + if (ivldp_got_new_command()) + { + // strip off the count and examine the command + switch (g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_PLAY: + ivldp_respond_req_play(); + break; + // if we get any of these commands, we have to skip the remaining buffered frames and reset + case VLDP_REQ_STOP: + case VLDP_REQ_QUIT: + case VLDP_REQ_OPEN: + case VLDP_REQ_SEARCH: + s_skip_all = 1; + s_uSkipAllCount = 0; + // we don't acknowledge these requests here, we let the idle handler take care of them + break; + case VLDP_REQ_STEP_FORWARD: + // if they've also requested a step forward + // NOTE : no need to change status, as we started paused and we'll end paused + ivldp_ack_command(); + s_step_forward = 1; + break; + case VLDP_REQ_LOCK: + ivldp_lock_handler(); + break; + default: // else if we get a pause command or another command we don't know how to handle, just ignore it + fprintf(stderr, "WARNING : pause handler received command %x that it is ignoring\n", g_req_cmdORcount); + ivldp_ack_command(); // acknowledge the command + break; + } // end switch + } // end if we have a new command coming in +} + +// the handler we call if we're playing +// this handler is called from within a while loop +void play_handler() +{ + // if we've received a new incoming command + if (ivldp_got_new_command()) + { + // strip off count and examine command + switch(g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_NONE: // no incoming command + break; + case VLDP_REQ_PAUSE: + case VLDP_REQ_STEP_FORWARD: + ivldp_respond_req_pause_or_step(); + break; + case VLDP_REQ_SPEEDCHANGE: + ivldp_respond_req_speedchange(); + break; + case VLDP_REQ_STOP: + case VLDP_REQ_QUIT: + case VLDP_REQ_OPEN: + case VLDP_REQ_SEARCH: + case VLDP_REQ_SKIP: + s_skip_all = 1; // bail out, handle these requests in the idle handler + s_uSkipAllCount = 0; + break; + case VLDP_REQ_LOCK: + ivldp_lock_handler(); + break; + default: // unknown or redundant command, just ignore + ivldp_ack_command(); + fprintf(stderr, "WARNING : play handler received command which it is ignoring\n"); + break; + } + } // end if we got a new command +} + +// sets the framerate inside our info structure based upon the framerate code received +void ivldp_set_framerate(Uint8 frame_rate_code) +{ + // now to compute the framerate + + switch (frame_rate_code) + { + case 1: + g_out_info.uFpks = 23976; + break; + case 2: + g_out_info.uFpks = 24000; + break; + case 3: + g_out_info.uFpks = 25000; + break; + case 4: + g_out_info.uFpks = 29970; + break; + case 5: + g_out_info.uFpks = 30000; + break; + case 6: + g_out_info.uFpks = 50000; + break; + case 7: + g_out_info.uFpks = 59940; + break; + case 8: + g_out_info.uFpks = 60000; + break; + default: + // else we got an invalid frame rate code + fprintf(stderr, "ERROR : Invalid frame rate code!\n"); + g_out_info.uFpks = 1000; // to avoid divide by 0 error + break; + } // end switch + + // precalculate values that we use over and over again + g_out_info.u2milDivFpks = 2000000 / g_out_info.uFpks; + +} + +///////////////// + +// decode_mpeg2 function taken from mpeg2dec.c and optimized a bit +static void decode_mpeg2 (uint8_t * current, uint8_t * end) +{ + const mpeg2_info_t * info; + int state; + vo_setup_result_t setup_result; + + mpeg2_buffer (g_mpeg_data, current, end); + + info = mpeg2_info (g_mpeg_data); + // loop until we return (state is -1) + for (;;) + { + state = mpeg2_parse (g_mpeg_data); + switch (state) + { + case -1: + return; + case STATE_SEQUENCE: + /* might set nb fbuf, convert format, stride */ + /* might set fbufs */ + if (s_video_output->setup (s_video_output, info->sequence->width, + info->sequence->height, &setup_result)) + { + fprintf (stderr, "display setup failed\n"); // this should never happen + } + + if (setup_result.convert) + mpeg2_convert (g_mpeg_data, setup_result.convert, NULL); + + // if this driver offers a setup_fbuf callback ... +// else if (s_video_output->setup_fbuf) +// we KNOW we offer a setup_fbuf function, so get rid of this conditional + { + uint8_t * buf[3]; + void * id; + + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + s_video_output->setup_fbuf (s_video_output, buf, &id); + mpeg2_set_buf (g_mpeg_data, buf, id); + } + break; + case STATE_PICTURE: + /* might skip */ + /* might set fbuf */ + + // all possible stuff we could've done here was removed because the null driver + // doesn't do any of it + + break; + case STATE_PICTURE_2ND: + /* should not do anything */ + break; + case STATE_SLICE: + case STATE_END: + /* draw current picture */ + /* might free frame buffer */ + // if the init hasn't been called yet, this may fail so we have to put the conditional + if (info->display_fbuf) + { + s_video_output->draw (s_video_output, info->display_fbuf->buf, + info->display_fbuf->id); + } + + break; + } // end switch + } // end endless for loop +} + +///////////////// + +// Pre-caches sequence header so that vldp_process_sequence_header (and thus any seeks) are faster +// NOTE: this does change the file position +void vldp_cache_sequence_header() +{ + Uint32 val = 0; + unsigned int index = 0; + + io_seek(0); // start at beginning + io_read(g_header_buf, HEADER_BUF_SIZE); // assume that we must find the first frame in this chunk of bytes + // if not, we'll have to increase the number + + // go until we have found the first frame or we run out of data + while (val != 0x000001B8) + { + val = val << 8; + val |= g_header_buf[index]; // add newest byte to bottom of val + index++; // advance the end pointer + if (index > HEADER_BUF_SIZE) + { + fprintf(stderr, "VLDP : Could not find first frame in 0x%x bytes. Modify source code to increase buffer!\n", HEADER_BUF_SIZE); + break; + } + } + + // subtract 4 because we stopped when we found the 4 byte header of the first frame + g_header_buf_size = index - 4; +} + +// feeds libmpeg2 the beginning of the file up to the first Group of Picture +// It needs this info to get setup to play from an arbitrary position in the file that isn't the beginning +// In other words, this is ONLY used when we are seeking to an arbitrary frame +void vldp_process_sequence_header() +{ + decode_mpeg2 (g_header_buf, g_header_buf + g_header_buf_size); // decode the pre-cached sequence header +} + +// opens a new mpeg2 file +// The file is positioned at the beginning +void idle_handler_open() +{ + char req_file[STRSIZE] = { 0 }; + unsigned int req_idx = g_req_idx; + VLDP_BOOL req_precache = g_req_precache; + VLDP_BOOL bSuccess = VLDP_FALSE; + + SAFE_STRCPY(req_file, g_req_file, sizeof(req_file)); // after we ack the command, this string could become clobbered at any time + + // NOTE : it is very important that we change our status to BUSY before acknowledging the command, because + // our previous status could be STAT_ERROR, which causes problems with the *_and_block commands. + g_out_info.status = STAT_BUSY; // make us busy while opening the file + ivldp_ack_command(); // acknowledge open command + + // reset libmpeg2 so it is prepared to begin reading from a new m2v file + mpeg2_partial_init(g_mpeg_data); + + // if we have previously opened an mpeg, we need to close it and reset + if (io_is_open()) + { + io_close(); + + // since the overlay is double buffered, we want to blank it + // twice before closing it. This is to avoid a 'flicker effect' that we can + // get when switching between mpeg files. + g_in_info->render_blank_frame(); + g_in_info->render_blank_frame(); + + // we need to close this surface, because the new mpeg may have a different resolution than the old one, and therefore, + // the YUV buffer must be re-allocated + s_video_output->close(s_video_output); + } + + // if we've been requested to open a real file ... + if (!req_precache) + { + bSuccess = io_open(req_file); + } + // else we've been requested to open a precached file... + else + { + bSuccess = io_open_precached(req_idx); + } + + // If file was opened successfully, + // check to make sure it's a video stream and also get framerate + if (bSuccess) + { + Uint8 small_buf[8]; + io_read(small_buf, sizeof(small_buf)); // 1st 8 bytes reveal much + + // if we find the proper mpeg2 video header at the beginning of the file + if (((small_buf[0] << 24) | (small_buf[1] << 16) | (small_buf[2] << 8) | small_buf[3]) == 0x000001B3) + { + g_out_info.w = (small_buf[4] << 4) | (small_buf[5] >> 4); // get mpeg width + g_out_info.h = ((small_buf[5] & 0x0F) << 8) | small_buf[6]; // get mpeg height + ivldp_set_framerate(small_buf[7] & 0xF); // set the framerate + + io_seek(0); // go back to beginning for parser's benefit + + // load/parse all the frame locations in the file for super fast seeking + if (ivldp_get_mpeg_frame_offsets(req_file)) + { + g_in_info->report_mpeg_dimensions(g_out_info.w, g_out_info.h); // this function creates the video overlay. + // We want to make sure we do this _after_ the frame offsets are loaded in because + // graphics are drawn to the main screen if parsing needs to be done. + + vldp_cache_sequence_header(); // cache sequence header for faster seeking + + io_seek(0); // seek back to beginning of file + + g_out_info.status = STAT_STOPPED; // now that the file is open, we're ready to play + } + else + { + io_close(); + fprintf(stderr, "VLDP PARSE ERROR : Is the video stream damaged?\n"); + g_out_info.status = STAT_ERROR; // change from BUSY to ERROR + } + } // end if a proper mpeg header was found + + // if the file had a bad header + else + { + io_close(); + fprintf(stderr, "VLDP ERROR : Did not find expected header. Is this mpeg stream demultiplexed??\n"); + g_out_info.status = STAT_ERROR; + } + } // end if file exists + else + { + fprintf(stderr, "VLDP ERROR : Could not open file!\n"); + g_out_info.status = STAT_ERROR; + } +#ifdef VLDP_DEBUG + printf("idle_handler_open returning ...\n"); +#endif +} + +// gets called when the user wants to precache a file ... +void idle_handler_precache() +{ + char req_file[STRSIZE] = { 0 }; + + SAFE_STRCPY(req_file, g_req_file, sizeof(req_file)); // after we ack the command, this string could become clobbered at any time + + // always set the status before acknowledging the command so previous status doesn't get through + g_out_info.status = STAT_BUSY; // make us busy while opening the file + ivldp_ack_command(); + + // if we still have room in our array to precache ... + if (s_uPreCacheIdxCount < MAX_PRECACHE_FILES) + { + // GET LENGTH OF ACTUAL FILE + FILE *F = fopen(req_file, "rb"); + if (F) + { + struct stat filestats; + fstat(fileno(F), &filestats); // get stats for file to get file length + s_sPreCacheEntries[s_uPreCacheIdxCount].uLength = filestats.st_size; + s_sPreCacheEntries[s_uPreCacheIdxCount].uPos = 0; // start at the beginning + + // allocate RAM to hold file ... + s_sPreCacheEntries[s_uPreCacheIdxCount].ptrBuf = malloc(filestats.st_size); + + // if malloc succeeded + if (s_sPreCacheEntries[s_uPreCacheIdxCount].ptrBuf) + { + unsigned char *u8Ptr = (unsigned char *) s_sPreCacheEntries[s_uPreCacheIdxCount].ptrBuf; + unsigned int uTotalBytesRead = 0; + const unsigned int READ_SIZE = 1048576; // how many bytes to read in at a time + + g_in_info->report_parse_progress(-1); // notify other thread that we're starting + + // load in the file ... + for (;;) + { + unsigned int uBytesRead = 0; + unsigned int uBytesToRead = READ_SIZE; + unsigned int uBytesLeft = filestats.st_size - + uTotalBytesRead; + + // don't overflow + if (uBytesToRead > uBytesLeft) uBytesToRead = uBytesLeft; + + uBytesRead = (unsigned int) fread(u8Ptr + uTotalBytesRead, 1, uBytesToRead, F); + uTotalBytesRead += uBytesRead; + + // if we're done ... + if (uTotalBytesRead >= (unsigned int) filestats.st_size) + { + break; + } + + // update user on our precache progress + g_in_info->report_parse_progress((double) uTotalBytesRead / + s_sPreCacheEntries[s_uPreCacheIdxCount].uLength); + } + + g_in_info->report_parse_progress(1); // notify other thread that we're done ... + + // notify other thread of which index we've used to precache this file + g_out_info.uLastCachedIndex = s_uPreCacheIdxCount; + + // we're done with this entry, so the count increases + // (this must be done after we've read in the file so that the index is correct for that operation) + ++s_uPreCacheIdxCount; + + g_out_info.status = STAT_STOPPED; // success + } + // else malloc failed + else + { + g_out_info.status = STAT_ERROR; + } + fclose(F); + } + // else we couldn't open the file + else + { + g_out_info.status = STAT_ERROR; + } + } + // else we're out of room, so return an error + else + { + g_out_info.status = STAT_ERROR; + } +} + +// starts playing the mpeg from the very beginning +// This is ONLY called when a file has just been opened and no seeking has taken place, +// OR if ivldp_render() has hit EOF and rewound back to the beginning +// This ASSUMES that g_mpeg_handle is at the BEGINNING of the file +// and that mpeg2_partial_init() has been called +void idle_handler_play() +{ + ivldp_respond_req_play(); + // when the frame is actually blitted is when we set the status to STAT_PLAYING + ivldp_render(); +} + +// responds to play request +void ivldp_respond_req_play() +{ + s_timer = g_req_timer; +#ifdef VLDP_DEBUG + fprintf(stderr, "ivldp_respond_req_play() : g_req_timer is %u, and uMstimer is %u\n", g_req_timer, g_in_info->uMsTimer); // REMOVE ME +#endif // VLDP_DEBUG + s_uFramesShownSinceTimer = PLAY_FRAME_STALL; // we want to render the currently shown frame for 1 frame before moving on + g_out_info.status = STAT_PLAYING; // we strive for instant response (and catch-up to maintain timing) + ivldp_ack_command(); // acknowledge the play command + s_paused = 0; // we to not want to pause on 1 frame + s_blanked = 0; // we want to see the video + s_frames_to_skip = s_frames_to_skip_with_inc = 0; // skip no frames, just play from current position + // this value is reset again as soon as we confirm that we are playing +} + +// gets called if ivldp_got_new_command() returns true and the new command +// is either a pause or a step +void ivldp_respond_req_pause_or_step() +{ + // if they've also requested a step forward + if ((g_req_cmdORcount & 0xF0) == VLDP_REQ_STEP_FORWARD) + { + s_step_forward = 1; + } + // NOTE : by design, our status should not change until paused_handler is called, so we leave it at PLAYING for now + ivldp_ack_command(); +#ifdef VLDP_DEBUG + printf("VLDP_REQ_PAUSED received when frame is %u, uMsTimer is %u\n", g_out_info.current_frame, + g_in_info->uMsTimer); // DBG REMOVE ME!@ +#endif // VLDP_DEBUG + s_paused = 1; + s_blanked = 0; +} + +// gets called if ivldp_got_new_command() returns true and the new command +// is a speed change command +void ivldp_respond_req_speedchange() +{ + s_skip_per_frame = g_req_skip_per_frame; + s_stall_per_frame = g_req_stall_per_frame; + ivldp_ack_command(); +} + +// displays 1 or more frames to the screen, according to the state variables. +// This function can be used to do both still frames and moving video. Play and search both use this function. +void ivldp_render() +{ + Uint8 *end = NULL; + int render_finished = 0; + +#ifdef VLDP_BENCHMARK + Uint32 render_start_time = SDL_GetTicks(); // keep track of when we started + Sint16 render_start_frame = g_out_info.current_frame; // keep track of the frame we started timing stuff on + double total_seconds = 0.0; // used to calculate FPS + Sint16 total_frames = 0; // used to calculate FPS + FILE *F = fopen("benchmark.txt", "wt"); // create a little logfile for benchmark results +#endif + + s_skip_all = 0; // default value, don't skip frames unless the play or paused handler orders it + +#ifdef VLDP_DEBUG + printf("s_skip_all skipped %u frames.\n", s_uSkipAllCount); +#endif // VLDP_DEBUG + + // check to make sure a file has been opened + if (!io_is_open()) + { + render_finished = 1; + fprintf(stderr, "VLDP RENDER ERROR : we tried to render an mpeg but none was open!\n"); + g_out_info.status = STAT_ERROR; + } + + // while we're not finished playing and pausing + while (!render_finished) + { +// end = g_buffer + fread (g_buffer, 1, BUFFER_SIZE, g_mpeg_handle); + end = g_buffer + io_read(g_buffer, BUFFER_SIZE); + + // safety check, they could be equal if we were already at EOF before we tried this + if (g_buffer != end) + { + // read chunk of video stream + decode_mpeg2 (g_buffer, end); // display it to the screen + } + + // if we've read to the end of the mpeg2 file, then we can't play anymore, so we pause on last frame + if (end != (g_buffer + BUFFER_SIZE)) + { + g_out_info.status = STAT_STOPPED; // it's a toss-up between this and STAT_PAUSED + render_finished = 1; + + // reset libmpeg2 so it is prepared to begin reading from the beginning of the file + mpeg2_partial_init(g_mpeg_data); + io_seek(0); // seek to the beginning of the file + g_out_info.current_frame = 0; // set frame # to beginning of file where it belongs + } + + // if a new command is coming in, check to see if we need to stop + if (ivldp_got_new_command()) + { + // check to see if we need to suddenly abort the rendering process + switch (g_req_cmdORcount & 0xF0) + { + case VLDP_REQ_QUIT: + case VLDP_REQ_OPEN: + case VLDP_REQ_SEARCH: + case VLDP_REQ_STOP: + g_out_info.status = STAT_BUSY; + render_finished = 1; + break; + case VLDP_REQ_SKIP: + // do not change the playing status because skips are supposed to be instant + render_finished = 1; + break; + } // end switch + } // end if they got a new command + } // end while + +#ifdef VLDP_BENCHMARK + fprintf(F, "Benchmarking result:\n"); + total_frames = g_out_info.current_frame - render_start_frame; + total_seconds = (SDL_GetTicks() - render_start_time) / 1000.0; + fprintf(F, "VLDP displayed %u frames (%d to %d) in %f seconds (%f FPS)\n", + total_frames, render_start_frame, g_out_info.current_frame, total_seconds, total_frames / total_seconds); + fclose(F); +#endif + +} + +#ifdef VLDP_DEBUG +#ifdef UNIX +#include // to break into debugger +#endif // UNIX +#endif // VLDP_DEBUG + +// searches to any arbitrary frame, be it I, P, or B, and renders it +// if skip is set, it will do a laserdisc skip instead of a search (ie it will go a frame, resume playback, +// and not adjust any timers) +void idle_handler_search(int skip) +{ + unsigned int proposed_pos = 0; + Uint32 req_frame = g_req_frame; // after we acknowledge the command, g_req_frame could become clobbered + Uint32 min_seek_ms = g_req_min_seek_ms; // g_req_min_seek_ms can be clobbered at any time after we acknowledge command + + // adjusted req frame is the requested frame with fields taken into account + unsigned int uAdjustedReqFrame = 0; + + unsigned int actual_frame = 0; + int skipped_I = 0; + + // status must be changed before acknowledging command, because previous status could be STAT_ERROR, which + // causes problems with *_and_block vldp API commands. + if (!skip) g_out_info.status = STAT_BUSY; + // else we're skipping + // (our status is already STAT_PLAYING so we don't need to set it) + else + { + // Since we're skipping, we must re-calculate s_uFramesShownSinceTimer because it is possible on laggy systems for + // this value to be behind what it ought to be, and we need to be perfectly in sync with the parent thread's + // g_in_info->uMsTimer value in order to display the correct frames. + // NOTE : this _must_ happen before we acknowledge the command, because we need g_in_info->uMsTimer to be constant while + // we recalculate s_uFramesShownSinceTimer + // NOTE 2 : we must use Uint64 here because otherwise this will overflow sometime after 2 minutes which DOES happen + // on Astron Belt if 'infinite timer' is enabled (it doesn't do any searches, just skips) + unsigned int uNewFramesShownSinceTimer = (unsigned int) ((((Uint64) (g_in_info->uMsTimer - s_timer)) * g_out_info.uFpks) / 1000000); + + // take into account the extra frame we did when playback started + uNewFramesShownSinceTimer += PLAY_FRAME_STALL; + +#ifdef VLDP_DEBUG + // break into debugger if this happens so we can examine what's going on + if (uNewFramesShownSinceTimer != s_uFramesShownSinceTimer) + { + printf("skip timing off: uNewFramesShownSinceTimer is %u, s_uFramesShownSinceTimer is %u\n", + uNewFramesShownSinceTimer, s_uFramesShownSinceTimer); + + // this shouldn't ever happen + if (s_uFramesShownSinceTimer > uNewFramesShownSinceTimer) + { + fprintf(stderr, "!!! s_uFramesShownSinceTimer > uNewFramesShownSinceTimer, this shouldn't happen!\n"); +#ifdef UNIX + raise(SIGTRAP); // we wanna know what's going on ... +#endif // UNIX + } + } +#endif // VLDP_DEBUG + + s_uFramesShownSinceTimer = uNewFramesShownSinceTimer; + } + + ivldp_ack_command(); // acknowledge search/skip command + + // reset libmpeg2 so it is prepared to start from a new spot + mpeg2_partial_init(g_mpeg_data); + + vldp_process_sequence_header(); // we need to process the sequence header before we can jump around the file for frames + + // if we're doing a search... + if (!skip) + { + s_paused = 1; // we do want to pause on the frame we search to + s_timer = g_in_info->uMsTimer; // reset timer so framerate is correct + // NOTE : resetting s_timer here doesn't do much if we aren't simulating + // artificial seek delay, because paused_handler() will reset it again anyway. + // (but it is important for seek delay!) + + s_uFramesShownSinceTimer = 0; + // NOTE : by setting this to 0, we are eliminating any potential unnecessary + // delays before paused_handler() gets called, which is what we want. + + s_extra_delay_ms = min_seek_ms; // any extra delay we have will be when the parent thread requested (this can be 0) + + // if we are to blank during searches ... + if (g_in_info->blank_during_searches) + { + g_in_info->render_blank_frame(); + } + } + + // if we are skipping we are actually in the middle of playback so we don't reset the timer + else + { + // NOTE : we don't want to change the status here because + // skipping is supposed to be instantaneous + + s_paused = 0; + + // if we need to blank frame for skipping + if (g_in_info->blank_during_skips) + { + g_in_info->render_blank_frame(); + } + } + + // adjusted req frame is the requested frame with fields taken into account + uAdjustedReqFrame = req_frame; + + // if we're using fields, then the requested frame must be doubled (2 fields per frame) + if (g_out_info.uses_fields) uAdjustedReqFrame <<= 1; + + actual_frame = uAdjustedReqFrame; + + // do a bounds check + if (uAdjustedReqFrame < g_totalframes) + { + proposed_pos = g_frame_position[uAdjustedReqFrame]; // get the proposed position + +#ifdef VLDP_DEBUG + printf("Initial proposed position is : %x\n", proposed_pos); +#endif + + s_frames_to_skip = s_frames_to_skip_with_inc = 0; // the below problem is no longer a problem + + // loop until we find which position in the file to seek to + for (;;) + { + // if the frame we want is not an I frame, go backward until we find an I frame, and increase # of frames to skip forward + while ((proposed_pos == 0xFFFFFFFF) && (actual_frame > 0)) + { + s_frames_to_skip++; + actual_frame--; + proposed_pos = g_frame_position[actual_frame]; + } + skipped_I++; + + // if we are only 2 frames away from an I frame, we will get a corrupted image and need to go back to + // the I frame before this one + if ((skipped_I < 2) && (s_frames_to_skip < 3) && (actual_frame > 0)) + { + proposed_pos = 0xFFFFFFFF; + } + else + { +#ifdef VLDP_DEBUG +// printf("We've decided on a position within the file.\n"); +// printf("skipped_I is %d\n", skipped_I); +// printf("s_frames_to_skip is %d\n", s_frames_to_skip); +// printf("actual_frame is %d\n", actual_frame); +#endif + break; + } + } + +#ifdef VLDP_DEBUG + printf("frames_to_skip is %d, skipped_I is %d\n", s_frames_to_skip, skipped_I); + printf("position in mpeg2 stream we are seeking to : %x\n", proposed_pos); +#endif + + io_seek(proposed_pos); +// fseek(g_mpeg_handle, proposed_pos, SEEK_SET); // go to the place in the stream where the I frame begins + + // if we're seeking, we can change the frame right now ... + if (!skip) + { + g_out_info.current_frame = req_frame; // this is no longer incremented in null_draw_frame due to s_paused being set + s_uPendingSkipFrame = 0; + } + // if we're skipping, we have to leave the current frame alone until it changes, in order + // to be consistent with actual laserdisc behavior. + else + { + s_uPendingSkipFrame = req_frame; + } + + s_blanked = 0; // we want to see the frame + + ivldp_render(); + } // end if the bounds check passed + else + { + fprintf(stderr, "SEARCH ERROR : frame %u was requested, but it is out of bounds\n", req_frame); + g_out_info.status = STAT_ERROR; + } +} + + + +// parses an mpeg video stream to get its frame offsets, or if the parsing had taken place earlier +VLDP_BOOL ivldp_get_mpeg_frame_offsets(char *mpeg_name) +{ + char datafilename[320] = { 0 }; + VLDP_BOOL mpeg_datafile_good = VLDP_FALSE; + FILE *data_file = NULL; + VLDP_BOOL result = VLDP_TRUE; + unsigned int mpeg_size = 0; + struct dat_header header; + + // GET LENGTH OF ACTUAL FILE + mpeg_size = io_length(); + + // change extension of file to be dat instead of (presumably) m2v + SAFE_STRCPY(datafilename, mpeg_name, sizeof(datafilename)); + strcpy(&datafilename[strlen(mpeg_name)-3], "dat"); + + // loop until we get a good datafile + // or until we get an error + while (!mpeg_datafile_good && result) + { + data_file = fopen(datafilename, "rb"); // check to see if datafile exists + + // If file cannot be opened, try to create it. + // Most likely the file cannot be opened because it doesn't + // exist. + if (!data_file) + { + result = ivldp_parse_mpeg_frame_offsets(datafilename, mpeg_size); + // we could open the file here, but there is no need to + // because we will loop back through and open the file anyway + } + + // else if the file has been opened + else + { + // now that file exists and we have it open, we have to read it + +#ifdef LARGE_FILE_SUPPORT // RDG + #ifdef WIN32 + _fseeki64(data_file, 0L, SEEK_SET); + #else + fseeko64(data_file, 0L, SEEK_SET); + #endif +#else + fseek(data_file, 0L, SEEK_SET); +#endif + fread(&header, sizeof(header), 1, data_file); // read .DAT file header + + // if version, file size, or finished are wrong, the dat file is no good and has to be regenerated + if ((header.length != mpeg_size) || (header.version != DAT_VERSION) || (header.finished != 1)) + { +// printf("*** Alleged mpeg size is %u, actual size is %u\n", header.length, mpeg_size); +// printf("Finished flag is %x\n", header.finished); +// printf("DAT version is %x\n", header.version); + printf("NOTICE : MPEG data file has to be created again!\n"); + fclose(data_file); + data_file = NULL; + + // try to delete obsolete .DAT file so we can create a modern one + if (unlink(datafilename) == -1) + { + fprintf(stderr, "Couldn't delete obsolete .DAT file!\n"); + result = VLDP_FALSE; + } + } + else + { + g_out_info.uses_fields = header.uses_fields; + mpeg_datafile_good = 1; // escape the loop + } + } // end if mpeg parsing was not necessary + } // end while we don't have a good datafile and haven't gotten an error + + // if we didn't exit the loop because of an error, then we need to read the datafile + if (result && data_file) + { + g_totalframes = 0; + +#ifdef VLDP_DEBUG +// unlink("frame_report.txt"); +#endif + + // read all the frame positions + // if we don't read 4 bytes, it means we've hit the EOF and we're done + while (fread(&g_frame_position[g_totalframes], 4, 1, data_file) == 1) + { +#ifdef VLDP_DEBUG +// FILE *tmp_F = fopen("frame_report.txt", "ab"); +// fprintf(tmp_F, "Frame %d has offset of %x\n", g_totalframes, g_frame_position[g_totalframes]); +// fclose(tmp_F); +#endif + g_totalframes++; + + // safety check, it is possible to make mpegs with too many frames to fit onto one CAV laserdisc + // (in fact I did this, and it caused a lot of problems in the debug stages hehe) + if (g_totalframes >= MAX_LDP_FRAMES) + { + fprintf(stderr, "ERROR : current mpeg has too many frames, VLDP will ignore any frames above %u\n", MAX_LDP_FRAMES); + break; + } + } +#ifdef VLDP_DEBUG + printf("*** g_totalframes is %u\n", g_totalframes); + printf("And frame 0's offset is %x\n", g_frame_position[0]); +#endif + } + + // close any files that are still open + if (data_file) + { + fclose(data_file); + } + + return result; +} + + +VLDP_BOOL ivldp_parse_mpeg_frame_offsets(char *datafilename, Uint32 mpeg_size) +{ + int result = VLDP_TRUE; + FILE *data_file = fopen(datafilename, "wb"); // create file + struct dat_header header; // header to put inside .DAT file + + // if we could create the file successfully, then we need to populate it + if (data_file) + { + Uint32 pos = 0; // position in the file + int count = 0; + int parse_result = 0; + + header.version = DAT_VERSION; + header.finished = 0; + header.uses_fields = 0; + header.length = mpeg_size; + fwrite(&header, sizeof(header), 1, data_file); + // first thing that goes in the file is the .DAT header + // That way we can re-use the file another time with confidence that it's + // the right one + + init_mpegscan(); + + g_in_info->report_parse_progress(-1); // notify other thread that we're starting + + // keep reading the file while there is a file left to be read + do + { +#define PARSE_CHUNK 200000 + + parse_result = parse_video_stream(data_file, PARSE_CHUNK); + pos += PARSE_CHUNK; + + // we want to give the user updates but don't want to flood them + if (count > 10) + { + count = 0; + + // report progress to parent thread + g_in_info->report_parse_progress((double) pos / mpeg_size); + } + count++; + + } while (parse_result == P_IN_PROGRESS); + + g_in_info->report_parse_progress(1); // notify other thread that we're done + + // if parse finished, then we have to update the header + if (parse_result != P_ERROR) + { + header.finished = 1; + header.uses_fields = 0; + if (parse_result == P_FINISHED_FIELDS) + { + header.uses_fields = 1; + } +#ifdef LARGE_FILE_SUPPORT // RDG + #ifdef WIN32 + _fseeki64(data_file, 0L, SEEK_SET); + #else + fseeko64(data_file, 0L, SEEK_SET); + #endif +#else + fseek(data_file, 0L, SEEK_SET); +#endif + fwrite(&header, sizeof(header), 1, data_file); // save changes + } + + // we have to close data file because it's write-only + // and it needs to be re-opened read-only + fclose(data_file); + data_file = NULL; + + // if the mpeg did not finish parsing gracefully, we've got problems + // NOTE : I separated this from the other if above to guarantee that the file gets closed + if (parse_result == P_ERROR) + { + fprintf(stderr, "There was an error parsing the MPEG file.\n"); + fprintf(stderr, "Either there is a bug in the parser or the MPEG file is corrupt.\n"); + fprintf(stderr, "OR the user aborted the decoding process :)\n"); + result = VLDP_FALSE; + unlink(datafilename); + } + } // end if we could create the file successfully + + // we couldn't create data file which means no write permission probably + // this is probably a good time to shut VLDP down =] + else + { + fprintf(stderr, "Could not create file %s\n", datafilename); + fprintf(stderr, "This probably means you don't have permission to create the file\n"); + result = VLDP_FALSE; + } + + return result; +} + + +VLDP_BOOL io_open(const char *cpszFilename) +{ + VLDP_BOOL bResult = VLDP_FALSE; + + // make sure everything is closed + if ((!s_bPreCacheEnabled) && (!g_mpeg_handle)) + { + g_mpeg_handle = fopen(cpszFilename, "rb"); + if (g_mpeg_handle) bResult = VLDP_TRUE; + } + return bResult; +} + +VLDP_BOOL io_open_precached(unsigned int uIdx) +{ + VLDP_BOOL bResult = VLDP_FALSE; + + // make sure everything is closed + if ((!g_mpeg_handle) && (!s_bPreCacheEnabled)) + { + // make sure index is within range ... + if (uIdx < s_uPreCacheIdxCount) + { + bResult = VLDP_TRUE; + s_uCurPreCacheIdx = uIdx; + s_bPreCacheEnabled = VLDP_TRUE; + s_sPreCacheEntries[s_uCurPreCacheIdx].uPos = 0; // when opening, rewind to beginning + } + // else out of range ... + } + return bResult; +} + +unsigned int io_read(void *buf, unsigned int uBytesToRead) +{ + unsigned int uBytesRead = 0; + + // if we're reading from a file stream + if (g_mpeg_handle) + { + uBytesRead = (unsigned int) fread(buf, 1, uBytesToRead, g_mpeg_handle); + } + // else we're reading from a precache stream + else + { + struct precache_entry_s *entry = &s_sPreCacheEntries[s_uCurPreCacheIdx]; + unsigned int uBytesLeft = entry->uLength - entry->uPos; + + // if we're trying to read beyond our means ... + if (uBytesToRead > uBytesLeft) + { + uBytesToRead = uBytesLeft; + } + + memcpy(buf, ((unsigned char *) entry->ptrBuf) + entry->uPos, uBytesToRead); + uBytesRead = uBytesToRead; + entry->uPos += uBytesRead; + } + + return uBytesRead; +} + +VLDP_BOOL io_seek(unsigned int uPos) +{ + VLDP_BOOL bResult = VLDP_FALSE; + + if (g_mpeg_handle) + { + +// BY RDG +// Preliminary support for MPEGS over 2GBs in size. +#ifdef LARGE_FILE_SUPPORT + #ifdef WIN32 + __int64 uPos64 = uPos; + if (_fseeki64(g_mpeg_handle, uPos64, SEEK_SET) == 0) + { + bResult = VLDP_TRUE; + } + #else + off_t uPos64 = uPos; + if (fseeko64(g_mpeg_handle, uPos64, SEEK_SET) == 0) + { + bResult = VLDP_TRUE; + } + + #endif +#else + + if (fseek(g_mpeg_handle, uPos, SEEK_SET) == 0) + { + bResult = VLDP_TRUE; + } + +#endif + } + else + { + struct precache_entry_s *entry = &s_sPreCacheEntries[s_uCurPreCacheIdx]; + + // if we're seeking within bounds ... + if (uPos < entry->uLength) + { + entry->uPos = uPos; + bResult = VLDP_TRUE; + } + } + return bResult; +} + +void io_close() +{ + if (g_mpeg_handle) + { + fclose(g_mpeg_handle); + g_mpeg_handle = NULL; + } + else if (s_bPreCacheEnabled) + { + s_bPreCacheEnabled = VLDP_FALSE; + } + // else nothing is open ... +} + +VLDP_BOOL io_is_open() +{ + VLDP_BOOL bResult = VLDP_FALSE; + if ((g_mpeg_handle) || (s_bPreCacheEnabled)) + { + bResult = VLDP_TRUE; + } + return bResult; +} + +unsigned int io_length() +{ + unsigned int uResult = 0; + + if (g_mpeg_handle) + { + struct stat the_stat; + fstat(fileno(g_mpeg_handle), &the_stat); + uResult = the_stat.st_size; + } + else if (s_bPreCacheEnabled) + { + uResult = s_sPreCacheEntries[s_uCurPreCacheIdx].uLength; + } + + return uResult; +} diff --git a/vldp2/vldp/vldp_internal.h b/vldp2/vldp/vldp_internal.h new file mode 100644 index 000000000..cc74d4dd6 --- /dev/null +++ b/vldp2/vldp/vldp_internal.h @@ -0,0 +1,104 @@ +/* + * vldp_internal.h + * + * Copyright (C) 2001 Matt Ownby + * + * This file is part of VLDP, a virtual laserdisc player. + * + * VLDP 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. + * + * VLDP 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 + */ + +// should only be used by the vldp private thread! + +#ifndef VLDP_INTERNAL_H +#define VLDP_INTERNAL_H + +#include "vldp.h" // for the VLDP_BOOL definition and SDL.h + +// this is which version of the .dat file format we are using +#define DAT_VERSION 2 + +// header for the .DAT files that are generated +struct dat_header +{ + Uint8 version; // which version of the DAT file this is + Uint8 finished; // whether the parse finished parsing or was interrupted + Uint8 uses_fields; // whether the stream uses fields or frames + Uint32 length; // length of the m2v stream +}; + +struct precache_entry_s +{ + void *ptrBuf; // buffer that holds precached file + unsigned int uLength; // length (in bytes) of the buffer + unsigned int uPos; // our current position within the stream +}; + +int idle_handler(void *surface); +void blank_video(); +void erase_yuv_overlay(SDL_Overlay *dst); +int ivldp_got_new_command(); +void ivldp_ack_command(); +void ivldp_lock_handler(); +void paused_handler(); +void play_handler(); +void ivldp_set_framerate(Uint8 frame_rate_code); +void vldp_process_sequence_header(); +void idle_handler_open(); +void idle_handler_precache(); +void idle_handler_play(); +void ivldp_respond_req_play(); +void ivldp_respond_req_pause_or_step(); +void ivldp_respond_req_speedchange(); +void ivldp_render(); +void idle_handler_search(int skip); +VLDP_BOOL ivldp_get_mpeg_frame_offsets(char *mpeg_name); +VLDP_BOOL ivldp_parse_mpeg_frame_offsets(char *datafilename, Uint32 mpeg_size); +void ivldp_update_progress_indicator(SDL_Surface *indicator, double percentage_completed); + +VLDP_BOOL io_open(const char *cpszFilename); +VLDP_BOOL io_open_precached(unsigned int uIdx); +unsigned int io_read(void *buf, unsigned int uBytesToRead); +VLDP_BOOL io_seek(unsigned int uPos); +void io_close(); +VLDP_BOOL io_is_open(); +unsigned int io_length(); + +/////////////////////////////////////// + +extern Uint8 s_old_req_cmdORcount; // the last value of the command byte we received +extern int s_paused; // whether the video is to be paused +extern int s_blanked; // whether the mpeg video is to be blanked +extern int s_frames_to_skip; // how many frames to skip before rendering the next frame (used for P and B frames seeking) +extern int s_frames_to_skip_with_inc; // how many frames to skip while increasing the frame number (for multi-speed playback) +extern int s_skip_all; // skip all subsequent frames. Used to bail out of the middle of libmpeg2, back to vldp +extern unsigned int s_uSkipAllCount; // how many frames we've skipped when s_skip_all is enabled. +extern int s_step_forward; // if this is set, we step forward 1 frame +extern Uint32 s_timer; // FPS timer used by the blitting code to run at the right speed +extern Uint32 s_extra_delay_ms; // any extra delay that null_draw_frame() will use before drawing a frame (intended for laserdisc seek delay simulation) +extern Uint32 s_uFramesShownSinceTimer; // how many frames should've been rendered (relative to s_timer) before we advance +extern int s_overlay_allocated; // whether the SDL overlays have been allocated + +// Which frame we've skipped to (0 if we haven't skipped) +// Used in order to maintain the current frame number until the skip actually occurs. +extern unsigned int s_uPendingSkipFrame; + +extern SDL_Overlay *s_hw_overlay; // if the game uses video overlay, we can't modify our buffers, so we have to + // copy to the extra overlay and let that get displayed + +extern unsigned int s_skip_per_frame; // how many frames to skip per frame (for playing at 2X for example) +extern unsigned int s_stall_per_frame; // how many frames to stall per frame (for playing at 1/2X for example) + +#endif diff --git a/vldp2_vs2003.vcproj b/vldp2_vs2003.vcproj new file mode 100644 index 000000000..a2acd8de2 --- /dev/null +++ b/vldp2_vs2003.vcproj @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vldp2_vs2008.vcproj b/vldp2_vs2008.vcproj new file mode 100644 index 000000000..c8951177d --- /dev/null +++ b/vldp2_vs2008.vcproj @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +