From 2893176b18c55c3436f982e6aa571d64b16605a6 Mon Sep 17 00:00:00 2001 From: Logue Date: Fri, 17 Feb 2012 21:26:42 +0900 Subject: [PATCH] =?utf8?q?=E3=82=A4=E3=83=8B=E3=82=B7=E3=83=A3=E3=83=AB?= =?utf8?q?=E3=82=B3=E3=83=9F=E3=83=83=E3=83=88=E3=80=82=20WxWidgets-2.9.3?= =?utf8?q?=E3=81=A7=E3=83=93=E3=83=AB=E3=83=89=E3=81=A7=E3=81=8D=E3=82=8B?= =?utf8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- BigEndianBuffer.cpp | 142 + BigEndianBuffer.h | 51 + COPYING.txt | 340 ++ DefaultNames.cpp | 648 ++++ DefaultNames.h | 52 + DefaultNames.txt | 256 ++ GenericEndianBuffer.cpp | 189 + GenericEndianBuffer.h | 60 + LittleEndianBuffer.cpp | 137 + LittleEndianBuffer.h | 48 + Makefile.am | 35 + Makefile.in | 863 +++++ Physics/Makefile.am | 8 + Physics/Makefile.in | 471 +++ Physics/PhysicsDocument.cpp | 292 ++ Physics/PhysicsDocument.h | 93 + Physics/PhysicsEditor.cpp | 1361 +++++++ Physics/PhysicsElements.cpp | 791 ++++ Physics/PhysicsElements.h | 816 ++++ Physics/PhysicsTreeItemData.cpp | 28 + Physics/PhysicsTreeItemData.h | 55 + Physics/PhysicsView.cpp | 1465 ++++++++ Physics/PhysicsView.h | 515 +++ README.txt | 218 ++ Resources/shapefusion.icns | Bin 0 -> 218316 bytes Resources/shapefusion.ico | Bin 0 -> 65794 bytes Resources/shapefusion.rc | 26 + Resources/shapefusion.svg | 1361 +++++++ ShapeFusion-Info.plist | 26 + ShapeFusion.xcodeproj/project.pbxproj | 592 +++ ShapeFusionApp.cpp | 133 + ShapeFusionApp.h | 46 + ShapeFusionDocManager.cpp | 169 + ShapeFusionDocManager.h | 34 + ShapeFusionMain.cpp | 56 + ShapeFusionMain.h | 39 + ShapeFusionMenus.cpp | 194 + ShapeFusionMenus.h | 101 + Shapes/BitmapBrowser.cpp | 390 ++ Shapes/BitmapBrowser.h | 83 + Shapes/BitmapView.cpp | 140 + Shapes/BitmapView.h | 61 + Shapes/CTBrowser.cpp | 204 + Shapes/CTBrowser.h | 66 + Shapes/CTView.cpp | 242 ++ Shapes/CTView.h | 64 + Shapes/FrameBrowser.cpp | 428 +++ Shapes/FrameBrowser.h | 86 + Shapes/FrameView.cpp | 315 ++ Shapes/FrameView.h | 74 + Shapes/Makefile.am | 11 + Shapes/Makefile.in | 484 +++ Shapes/SequenceView.cpp | 613 +++ Shapes/SequenceView.h | 97 + Shapes/ShapesDocument.cpp | 344 ++ Shapes/ShapesDocument.h | 91 + Shapes/ShapesElements.cpp | 2093 +++++++++++ Shapes/ShapesElements.h | 454 +++ Shapes/ShapesTreeItemData.cpp | 50 + Shapes/ShapesTreeItemData.h | 53 + Shapes/ShapesView.cpp | 2000 ++++++++++ Shapes/ShapesView.h | 269 ++ Shapes/utilities.cpp | 183 + Shapes/utilities.h | 32 + Sounds/Makefile.am | 6 + Sounds/Makefile.in | 466 +++ Sounds/SoundsDocument.cpp | 255 ++ Sounds/SoundsDocument.h | 77 + Sounds/SoundsElements.cpp | 698 ++++ Sounds/SoundsElements.h | 230 ++ Sounds/SoundsView.cpp | 582 +++ Sounds/SoundsView.h | 128 + aclocal.m4 | 2202 +++++++++++ config.guess | 1522 ++++++++ config.h.in | 25 + config.sub | 1771 +++++++++ configure | 6665 +++++++++++++++++++++++++++++++++ configure.ac | 91 + depcomp | 688 ++++ install-sh | 527 +++ missing | 376 ++ 81 files changed, 36947 insertions(+) create mode 100644 BigEndianBuffer.cpp create mode 100644 BigEndianBuffer.h create mode 100644 COPYING.txt create mode 100644 DefaultNames.cpp create mode 100644 DefaultNames.h create mode 100644 DefaultNames.txt create mode 100644 GenericEndianBuffer.cpp create mode 100644 GenericEndianBuffer.h create mode 100644 LittleEndianBuffer.cpp create mode 100644 LittleEndianBuffer.h create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 Physics/Makefile.am create mode 100644 Physics/Makefile.in create mode 100644 Physics/PhysicsDocument.cpp create mode 100644 Physics/PhysicsDocument.h create mode 100644 Physics/PhysicsEditor.cpp create mode 100644 Physics/PhysicsElements.cpp create mode 100644 Physics/PhysicsElements.h create mode 100644 Physics/PhysicsTreeItemData.cpp create mode 100644 Physics/PhysicsTreeItemData.h create mode 100644 Physics/PhysicsView.cpp create mode 100644 Physics/PhysicsView.h create mode 100644 README.txt create mode 100644 Resources/shapefusion.icns create mode 100644 Resources/shapefusion.ico create mode 100644 Resources/shapefusion.rc create mode 100644 Resources/shapefusion.svg create mode 100644 ShapeFusion-Info.plist create mode 100644 ShapeFusion.xcodeproj/project.pbxproj create mode 100644 ShapeFusionApp.cpp create mode 100644 ShapeFusionApp.h create mode 100644 ShapeFusionDocManager.cpp create mode 100644 ShapeFusionDocManager.h create mode 100644 ShapeFusionMain.cpp create mode 100644 ShapeFusionMain.h create mode 100644 ShapeFusionMenus.cpp create mode 100644 ShapeFusionMenus.h create mode 100644 Shapes/BitmapBrowser.cpp create mode 100644 Shapes/BitmapBrowser.h create mode 100644 Shapes/BitmapView.cpp create mode 100644 Shapes/BitmapView.h create mode 100644 Shapes/CTBrowser.cpp create mode 100644 Shapes/CTBrowser.h create mode 100644 Shapes/CTView.cpp create mode 100644 Shapes/CTView.h create mode 100644 Shapes/FrameBrowser.cpp create mode 100644 Shapes/FrameBrowser.h create mode 100644 Shapes/FrameView.cpp create mode 100644 Shapes/FrameView.h create mode 100644 Shapes/Makefile.am create mode 100644 Shapes/Makefile.in create mode 100644 Shapes/SequenceView.cpp create mode 100644 Shapes/SequenceView.h create mode 100644 Shapes/ShapesDocument.cpp create mode 100644 Shapes/ShapesDocument.h create mode 100644 Shapes/ShapesElements.cpp create mode 100644 Shapes/ShapesElements.h create mode 100644 Shapes/ShapesTreeItemData.cpp create mode 100644 Shapes/ShapesTreeItemData.h create mode 100644 Shapes/ShapesView.cpp create mode 100644 Shapes/ShapesView.h create mode 100644 Shapes/utilities.cpp create mode 100644 Shapes/utilities.h create mode 100644 Sounds/Makefile.am create mode 100644 Sounds/Makefile.in create mode 100644 Sounds/SoundsDocument.cpp create mode 100644 Sounds/SoundsDocument.h create mode 100644 Sounds/SoundsElements.cpp create mode 100644 Sounds/SoundsElements.h create mode 100644 Sounds/SoundsView.cpp create mode 100644 Sounds/SoundsView.h create mode 100644 aclocal.m4 create mode 100644 config.guess create mode 100644 config.h.in create mode 100644 config.sub create mode 100644 configure create mode 100644 configure.ac create mode 100644 depcomp create mode 100644 install-sh create mode 100644 missing diff --git a/BigEndianBuffer.cpp b/BigEndianBuffer.cpp new file mode 100644 index 0000000..e8edd84 --- /dev/null +++ b/BigEndianBuffer.cpp @@ -0,0 +1,142 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include +#include "BigEndianBuffer.h" + +BigEndianBuffer::BigEndianBuffer(unsigned int _size): + GenericEndianBuffer(_size) +{ + +} + +BigEndianBuffer::BigEndianBuffer(unsigned char *_data, unsigned int _size): + GenericEndianBuffer(_data, _size) +{ + +} + +BigEndianBuffer::~BigEndianBuffer(void) +{ + +} + +short BigEndianBuffer::ReadShort(void) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + unsigned char hi = *mPosition++, + lo = *mPosition++; + + return (short)((hi << 8) | lo); + } else { + std::cerr << "BigEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +unsigned short BigEndianBuffer::ReadUShort(void) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + unsigned char hi = *mPosition++, + lo = *mPosition++; + + return (unsigned short)((hi << 8) | lo); + } else { + std::cerr << "BigEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +long BigEndianBuffer::ReadLong(void) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + unsigned char a = *mPosition++, + b = *mPosition++, + c = *mPosition++, + d = *mPosition++; + + return (long)((a << 24) | (b << 16) | (c << 8) | d); + } else { + std::cerr << "BigEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +unsigned long BigEndianBuffer::ReadULong(void) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + unsigned char a = *mPosition++, + b = *mPosition++, + c = *mPosition++, + d = *mPosition++; + + return (unsigned long)((a << 24) | (b << 16) | (c << 8) | d); + } else { + std::cerr << "BigEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +void BigEndianBuffer::WriteShort(short v) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = v & 0xff; + } else { + std::cerr << "BigEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void BigEndianBuffer::WriteUShort(unsigned short v) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = v & 0xff; + } else { + std::cerr << "BigEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void BigEndianBuffer::WriteLong(long v) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + *mPosition++ = (v >> 24) & 0xff; + *mPosition++ = (v >> 16) & 0xff; + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = v & 0xff; + } else { + std::cerr << "BigEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void BigEndianBuffer::WriteULong(unsigned long v) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + *mPosition++ = (v >> 24) & 0xff; + *mPosition++ = (v >> 16) & 0xff; + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = v & 0xff; + } else { + std::cerr << "BigEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void BigEndianBuffer::WriteFixed(double d) +{ + WriteLong(static_cast(std::floor(d * 65536.0 + 0.5))); +} diff --git a/BigEndianBuffer.h b/BigEndianBuffer.h new file mode 100644 index 0000000..5646bb1 --- /dev/null +++ b/BigEndianBuffer.h @@ -0,0 +1,51 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// BigEndianBuffer +// Utility class to access big-endian data buffers easily +// + +#ifndef BIGENDIANBUFFER_H +#define BIGENDIANBUFFER_H + +#include "GenericEndianBuffer.h" + +class BigEndianBuffer: public GenericEndianBuffer { +public: + // self-allocate data buffer + BigEndianBuffer(unsigned int _size); + // use a pre-allocated buffer + BigEndianBuffer(unsigned char *_data, unsigned int _size); + ~BigEndianBuffer(void); + // read big-endian values, advance position accordingly + short ReadShort(void); + unsigned short ReadUShort(void); + long ReadLong(void); + unsigned long ReadULong(void); + double ReadFixed(void) { return ReadLong() / 65536.0; } + + // write big-endian values, advance position accordingly + void WriteShort(short v); + void WriteUShort(unsigned short v); + void WriteLong(long v); + void WriteULong(unsigned long v); + void WriteFixed(double d); +}; + +#endif diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..dcfa4c2 --- /dev/null +++ b/COPYING.txt @@ -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/DefaultNames.cpp b/DefaultNames.cpp new file mode 100644 index 0000000..3eb923f --- /dev/null +++ b/DefaultNames.cpp @@ -0,0 +1,648 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "DefaultNames.h" + +#include +#include +#include + +static const wxString alienNames[] = { + _("Marine"), + _("Minor Tick"), + _("Major Tick"), + _("Kamikaze Tick"), + _("Minor S'pht"), + _("Major S'pht"), + _("Minor Invisible S'pht"), + _("Major Invisible S'pht"), + _("Minor Pfhor"), + _("Major Pfhor"), + _("Minor Projectile Pfhor"), + _("Major Projectile Pfhor"), + _("Green Bob"), + _("Blue Bob"), + _("Security Bob"), + _("Assimilated Bob"), + _("Minor Drone"), + _("Major Drone"), + _("Big Minor Drone"), + _("Big Angry Drone"), + _("Possessed Drone"), + _("Minor Cyborg"), + _("Major Cyborg"), + _("Minor Flame Cyborg"), + _("Major Flame Cyborg"), + _("Minor Enforcer"), + _("Major Enforcer"), + _("Minor Hunter"), + _("Major Hunter"), + _("Minor Trooper"), + _("Major Trooper"), + _("Mother of All Cyborgs"), + _("Mother of All Hunters"), + _("Sewage F'lickta"), + _("Water F'lickta"), + _("Lava F'lickta"), + _("Minor S'pht'Kr"), + _("Major S'pht'Kr"), + _("Minor Juggernaut"), + _("Major Juggernaut"), + _("Tiny P'fhor"), + _("Tiny Bob"), + _("Tiny Flick'ta"), + _("Green VacBob"), + _("Blue VacBob"), + _("Security VacBob"), + _("Assimilated VacBob"), +}; + +static const wxString collectionNames[] = { + _("Interface"), + _("Weapons in Hand"), + _("Juggernaut"), + _("Tick"), + _("Explosion Effects"), + _("Hunter"), + _("Marine"), + _("Items"), + _("Trooper"), + _("Pfhor fighter"), + _("S'pht'Kr"), + _("F'lickta"), + _("Bob"), + _("VacBob (Inf only)"), + _("Enforcer"), + _("Drone"), + _("S'pht"), + _("Walls 1 (Water)"), + _("Walls 2 (Lava)"), + _("Walls 3 (Sewage)"), + _("Walls 4 (Jjaro)"), + _("Walls 5 (Pfhor)"), + _("Scenery 1 (Water)"), + _("Scenery 2 (Lava)"), + _("Scenery 3 (Sewage)"), + _("Scenery 4 (Jjaro)"), + _("Scenery 5 (Pfhor)"), + _("Landscape 1 (Day)"), + _("Landscape 2 (Night)"), + _("Landscape 3 (Moon)"), + _("Landscape 4 (Space)"), + _("Cyborg"), +}; + +static const wxString classNames[] = { + _("Marine"), + _("Bob"), + _("Marathon Drone"), + _("Possessed Drone"), + _("S'pht'Kr"), + _("Pfhor Fighter"), + _("Pfhor Trooper"), + _("Hunter"), + _("Enforcer"), + _("Juggernaut"), + _("Drone"), + _("S'pht"), + _("Cyborg"), + _("Assimilated Bob"), + _("Tick"), + _("F'lickta"), +}; + +static const wxString damageNames[] = { + _("Explosion"), + _("Electrical Staff"), + _("Projectile"), + _("Absorbed"), + _("Flame"), + _("Claws"), + _("Alien Projectile"), + _("Hulk Slap"), + _("Compiler Bolt"), + _("Fusion Bolt"), + _("Hunter Bolt"), + _("Fist"), + _("Teleporter"), + _("S'pht'Kr Bolt"), + _("Flick'ta Claws"), + _("Flick'ta Projectile"), + _("Crushing"), + _("Lava"), + _("Suffocation"), + _("Goo"), + _("Energy Drain"), + _("Oxygen Drain"), + _("Drone Bolt"), + _("Shotgun"), +}; + +static const wxString effectNames[] = { + _("Missile Explosion"), + _("Missile Contrail"), + _("Grenade Explosion"), + _("Grenade Contrail"), + _("Bullet Ricochet"), + _("Alien Weapon Impact"), + _("Flamethrower Burst"), + _("Pfhor Hit"), + _("Marine Hit"), + _("Bob Hit"), + _("Assimilated Bob Hit"), + _("Enforcer Hit"), + _("S'pht Bolt Impact"), + _("Seeking S'pht Bolt Impact"), + _("S'pht Bolt Contrail"), + _("Staff-Bolt Impact"), + _("Staff Impact"), + _("Hunter Bolt Impact"), + _("Hunter Hit"), + _("Plasma Impact"), + _("Plasma Overload Impact"), + _("Plasma Contrail"), + _("Fist Impact"), + _("S'pht'Kr Bolt Impact"), + _("Major S'pht'Kr Bolt Impact"), + _("S'pht'Kr Hit"), + _("Trooper Hit"), + _("Lamp Breaking 1"), + _("Lamp Breaking 2"), + _("Lamp Breaking 3"), + _("Lamp Breaking 4"), + _("Clank (melee hit)"), + _("Teleport In"), + _("Teleport Out"), + _("Small Water Splash"), + _("Medium Water Splash"), + _("Large Water Splash"), + _("Large Water Emergence"), + _("Small Lava Splash"), + _("Medium Lava Splash"), + _("Large Lava Splash"), + _("Large Lava Emergence"), + _("Small Sewage Splash"), + _("Medium Sewage Splash"), + _("Large Sewage Splash"), + _("Large Sewage Emergence"), + _("Small Goo Splash"), + _("Medium Goo Splash"), + _("Large Goo Splash"), + _("Large Goo Emergence"), + _("Drone Bolt Impact"), + _("Fast Drone Bolt Impact"), + _("Possessed Drone Bolt Impact"), + _("Drone Hit"), + _("Cyborg Grenade Detonation"), + _("Cyborg Hit"), + _("Fusion Dispersal"), + _("Major Fusion Dispersal"), + _("Overloaded Fusion Dispersal"), + _("F'lickta Hit"), + _("F'lickta Glob Impact"), + _("Water Flick'ta Hit"), + _("Lava Flick'ta Hit"), + _("Flick'ta Lava Glob Impact"), + _("Flick'ta Claw Impact"), + _("Juggernaut Hit"), + _("Juggernaut Missile Contrail"), + _("Small Special Splash"), + _("Medium Special Splash"), + _("Large Special Splash"), + _("Special Emergence"), + _("VacBob Hit"), + _("Assimilated VacBob Hit"), +}; + +static const wxString itemNames[] = { + _("Fist"), + _("Magnum Pistol"), + _("Magnum Magazine"), + _("Plasma Pistol"), + _("Plasma Battery"), + _("Assault Rifle"), + _("Assault Rifle Clip"), + _("Grenade Clip"), + _("Missile Launcher"), + _("Missile Launcher Clip"), + _("Invisibility Powerup"), + _("Invincibility Powerup"), + _("Infravision Powerup"), + _("Alien Weapon"), + _("Alien Weapon Magazine"), + _("Flamethrower"), + _("Flamethrower Canister"), + _("Extravision Powerup"), + _("Oxygen Powerup"), + _("Energy Powerup"), + _("Double Energy Powerup"), + _("Triple Energy Powerup"), + _("Shotgun"), + _("Shotgun Magazine"), + _("S'pht Door Key"), + _("Uplink Chip"), + _("Light Blue Ball"), + _("The Ball"), + _("Violet Ball"), + _("Yellow Ball"), + _("Brown Ball"), + _("Orange Ball"), + _("Blue Ball"), + _("Green Ball"), + _("SMG"), + _("SMG Ammo"), +}; + +static const wxString soundNames[] = { + _("Startup"), + _("Teleport In"), + _("Teleport Out"), + _("Crunch"), + _("Creak (Inf only)"), + _("Absorbed"), + _("Unused 1"), + _("Oxygen Warning"), + _("Suffocation"), + _("Energy Refuel"), + _("Oxygen Refuel"), + _("Can't Toggle Switch"), + _("Switch On"), + _("Switch Off"), + _("Puzzle Switch"), + _("Chip Insertion"), + _("Pattern Buffer"), + _("Destroy Control Panel"), + _("Adjust Volume"), + _("Got Powerup"), + _("Got Item"), + _("Bullet Ricochet"), + _("Metallic Ricochet"), + _("Empty Gun"), + _("S'pht Door Opening"), + _("S'pht Door Closing"), + _("S'pht Door Obstructed"), + _("S'pht Platform Starting"), + _("S'pht Platform Stopping"), + _("Loon"), + _("SMG firing (Inf only)"), + _("SMG reloading (Inf only)"), + _("Heavy S'pht Platform Starting"), + _("Heavy S'pht Platform Stopping"), + _("Fist Hitting"), + _("Magnum Firing"), + _("Magnum Reloading"), + _("Assault Rifle Firing"), + _("Grenade Launcher Firing"), + _("Grenade Exploding"), + _("Grenade Flyby"), + _("Fusion Firing"), + _("Fusion Exploding"), + _("Fusion Flyby"), + _("Fusion Charging"), + _("Rocket Expoding"), + _("Rocket Flyby"), + _("Rocket Firing"), + _("Flamethrower"), + _("Body Falling"), + _("Body Exploding"), + _("Bullet Hitting Flesh"), + _("Fighter Activate"), + _("Fighter Wail"), + _("Fighter Scream"), + _("Fighter Chatter"), + _("Fighter Attack"), + _("Fighter Projectile Hit"), + _("Fighter Projectile Flyby"), + _("S'pht Attack"), + _("S'pht Death"), + _("S'pht Hit"), + _("S'pht Projectile Flyby"), + _("S'pht Projectile Hit"), + _("Cyborg Moving"), + _("Cyborg Attack"), + _("Cyborg Hit"), + _("Cyborg Death"), + _("Cyborg Projectile Bounce"), + _("Cyborg Projectile Hit"), + _("Unused 2"), + _("Drone Activate"), + _("Drone Start Attack"), + _("Drone Attack"), + _("Drone Dying"), + _("Drone Death"), + _("Drone Projectile Hit"), + _("Drone Projectile Flyby"), + _("Human Wail"), + _("Human Scream"), + _("Human Hit"), + _("Human Chatter"), + _("Assimilated Human Chatter"), + _("Human Trash Talk"), + _("Human Apology"), + _("Human Activation"), + _("Human Clear"), + _("Human Stop Shooting Me You Bastard"), + _("Human Area Secure"), + _("Kill The Player!"), + _("Water"), + _("Sewage"), + _("Lava"), + _("Goo"), + _("Under Stuff"), + _("Wind"), + _("Waterfall"), + _("Siren"), + _("Fan"), + _("S'pht Door"), + _("S'pht Platform"), + _("Alien Harmonics (Inf only)"), + _("Heavy S'pht Platform"), + _("Light Machinery"), + _("Heavy Machinery"), + _("Transformer"), + _("Sparking Transformer"), + _("Water Drip"), + _("Walking in Water"), + _("Exit Water"), + _("Enter Water"), + _("Small Water Splash"), + _("Medium Water Splash (unused)"), + _("Large Water Splash"), + _("Walking in Lava (unused)"), + _("Exit Lava"), + _("Enter Lava"), + _("Small Lava Splash"), + _("Medium Lava Splash (unused)"), + _("Large Lava Splash"), + _("Walking in Sewage (unused)"), + _("Exit Sewage"), + _("Enter Sewage"), + _("Small Sewage Splash"), + _("Medium Sewage Splash (unused)"), + _("Large Sewage Splash"), + _("Walking in Goo (unused)"), + _("Exit Goo (unused)"), + _("Enter Goo (unused)"), + _("Small Goo Splash (unused)"), + _("Medium Goo Splash (unused)"), + _("Large Goo Splash (unused)"), + _("Major Fusion Firing"), + _("Major Fusion Charged"), + _("Assault Rifle Reloading"), + _("Assault Rifle Shell Casings"), + _("Shotgun Firing"), + _("Shotgun Reloading"), + _("Ball Bounce"), + _("You Are It"), + _("Got The Ball"), + _("Computer Login"), + _("Computer Logout"), + _("Computer Page"), + _("Heavy S'pht Door"), + _("Heavy S'pht Door Opening"), + _("Heavy S'pht Door Closing"), + _("Heavy S'pht Door Open"), + _("Heavy S'pht Door Closed"), + _("Heavy S'pht Door Obstructed"), + _("Hunter Activate (unused)"), + _("Hunter Attack"), + _("Hunter Dying (unused)"), + _("Hunter Landing"), + _("Hunter Exploding"), + _("Hunter Projectile Hit"), + _("Hunter Projectile Flyby"), + _("Enforcer Activate"), + _("Enforcer Attack"), + _("Enforcer Projectile Hit"), + _("Enforcer Projctile Flyby"), + _("F'lickta Melee Attack"), + _("F'lickta Melee Attack Hit"), + _("F'lickta Projectile Attack"), + _("F'lickta Sewage Attack Hit"), + _("F'lickta Sewage Flyby"), + _("F'lickta Lava Attack Hit"), + _("F'lickta Lava Flyby"), + _("F'lickta Dying"), + _("Machine Binder"), + _("Machine Bookpress"), + _("Machine Puncher"), + _("Electric"), + _("Alarm"), + _("Night Wind"), + _("Surface Explosion"), + _("Underground Explosion"), + _("S'pht'Kr Attack"), + _("S'pht'Kr Hit"), + _("S'pht'Kr Flyby"), + _("S'pht'Kr Being Hit"), + _("S'pht'Kr Exploding"), + _("Tick Chatter"), + _("Tick Falling"), + _("Tick Flapping"), + _("Tick Exploding"), + _("Lamp Exploding"), + _("Pfhor Platform Start"), + _("Pfhor Platform Stop"), + _("Pfhor Platform"), + _("Pfhor Door Opening"), + _("Pfhor Door Closing"), + _("Pfhor Door Obstructed"), + _("Pfhor Door"), + _("Pfhor Switch Off"), + _("Pfhor Switch On"), + _("Juggernaut Firing"), + _("Juggernaut Warning"), + _("Juggernaut Exploding"), + _("Juggernaut Preparing to Fire"), + _("Enforcer Exploding"), + _("Alien Noise 1"), + _("Alien Noise 2"), + _("VacBob Wail"), + _("VacBob Scream"), + _("VacBob Hit"), + _("VacBob Chatter"), + _("Assimilated VacBob Chatter"), + _("VacBob Trash Talk"), + _("VacBob Apology"), + _("VacBob Activation"), + _("VacBob Clear"), + _("VacBob Stop Shooting Me You Bastard"), + _("VacBob Area Secure"), + _("VacBob Kill The Player"), +}; + +static const wxString shotNames[] = { + _("Missile"), + _("Grenade"), + _("Pistol Bullet"), + _("Assault Rifle Bullet"), + _("Shotgun Shot"), + _("Pfhor Staff"), + _("Pfhor Projectile"), + _("Flamethrower"), + _("S'pht Bolt"), + _("Seeking S'pht Bolt"), + _("Alien Weapon Blast"), + _("Fusion Bolt"), + _("Fusion Overload Bolt"), + _("Hunter Bolt"), + _("Fist Punch"), + _("unused 1"), + _("unused 2"), + _("Missile 2"), + _("Trooper Machine Gun"), + _("Trooper Grenade"), + _("S'pht'Kr Bolt"), + _("Major S'pht'Kr Bolt"), + _("Juggernaut Missile"), + _("Energy Drain"), + _("Major Energy Drain"), + _("Oxygen Drain"), + _("Drone Bolt"), + _("Fast Drone Bolt"), + _("Possessed Drone Bolt"), + _("Bouncing Grenade"), + _("Seeking Grenade"), + _("Ball"), + _("Fusion Media Backblast"), + _("Fusion Overload Media Backblast"), + _("Fusion Overload Self-Destruct"), + _("Flick'ta Claw"), + _("Flick'ta Glob"), + _("Flick'ta Lava Glob"), + _("SMG Bullet"), +}; + +static const wxString weaponNames[] = { + _("Fist"), + _("Pistol"), + _("Plasma Pistol"), + _("Assault Rifle"), + _("Missile Launcher"), + _("Flamethrower"), + _("Alien Weapon"), + _("Shotgun"), + _("The Ball"), + _("SMG") +}; + +DefaultNames* DefaultNames::mInstance; + +DefaultNames::DefaultNames() +{ + for (int i = 0; i < 47; ++i) { + mMap[wxT("alien")][i] = alienNames[i]; + } + + for (int i = 0; i < 16; ++i) { + mMap[wxT("class")][i] = classNames[i]; + } + + for (int i = 0; i < 32; ++i) { + mMap[wxT("collection")][i] = collectionNames[i]; + } + + for (int i = 0; i < 24; ++i) { + mMap[wxT("damage")][i] = damageNames[i]; + } + + for (int i = 0; i < 73; ++i) { + mMap[wxT("effect")][i] = effectNames[i]; + } + + for (int i = 0; i < 36; ++i) { + mMap[wxT("item")][i] = itemNames[i]; + } + + for (int i = 0; i < 215; ++i) { + mMap[wxT("sound")][i] = soundNames[i]; + } + + for (int i = 0; i < 39; ++i) { + mMap[wxT("shot")][i] = shotNames[i]; + } + + for (int i = 0; i < 10; ++i) { + mMap[wxT("weapon")][i] = weaponNames[i]; + } + + wxTextFile namesFile(wxStandardPaths::Get().GetResourcesDir() + wxT("/DefaultNames.txt")); + + if (namesFile.Exists()) { + if (namesFile.Open()) { + for (wxString str = namesFile.GetFirstLine(); !namesFile.Eof(); str = namesFile.GetNextLine()) { + str.Trim(true); + str.Trim(false); + + if (str[0] == '#') { + continue; + } + + // parse into three tokens + wxStringTokenizer tokenizer(str); + if (tokenizer.CountTokens() >= 3) { + wxString key = tokenizer.GetNextToken(); + wxString indexStr = tokenizer.GetNextToken(); + wxString value = tokenizer.GetString(); + + long index = 0; + if (!indexStr.ToLong(&index)) { + continue; + } + + mMap[key][index] = value; + } + } + + namesFile.Close(); + } + } +} + +wxString DefaultNames::Get(const wxString& set, int index) +{ + std::map >::const_iterator it = mMap.find(set); + if (it != mMap.end()) { + std::map::const_iterator kvp = it->second.find(index); + if (kvp != it->second.end()) { + return kvp->second; + } + } + + if (index == -1) { + return _("None"); + } else { + return set + wxString::Format(wxT(" %i"), index); + } +} + +std::vector DefaultNames::GetArray(const wxString& set) +{ + std::vector v; + + int size = mMap[set].rbegin()->first + 1; + if (size > 0) { + v.resize(size); + + for (int i = 0; i < size; ++i) { + v[i] = GetName(set, i); + } + } + + return v; +} diff --git a/DefaultNames.h b/DefaultNames.h new file mode 100644 index 0000000..1677108 --- /dev/null +++ b/DefaultNames.h @@ -0,0 +1,52 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef DEFAULTNAMES_H +#define DEFAULTNAMES_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include + +class DefaultNames { +public: + static DefaultNames* Instance() { + if (!mInstance) { + mInstance = new DefaultNames; + } + return mInstance; + } + + wxString Get(const wxString& set, int index); + std::vector GetArray(const wxString& set); + +private: + DefaultNames(); + + static DefaultNames* mInstance; + + std::map > mMap; +}; + +static inline wxString GetName(const wxString& set, int index) { return DefaultNames::Instance()->Get(set, index); } + +#endif diff --git a/DefaultNames.txt b/DefaultNames.txt new file mode 100644 index 0000000..c92facf --- /dev/null +++ b/DefaultNames.txt @@ -0,0 +1,256 @@ +# +# Default names for elements related to ShapeFusion +# +# This file lists names for Infinity-like scenarios +# + +# collection names +collection 0 Interface graphics +collection 1 Weapons in hand +collection 2 Juggernaut +collection 3 Tick +collection 4 Projectiles & explosions +collection 5 Hunter +collection 6 Player +collection 7 Items +collection 8 Trooper +collection 9 Pfhor fighter +collection 10 Defender +collection 11 Yeti +collection 12 Bob +collection 13 Vacuum Bob +collection 14 Enforcer +collection 15 Hummer +collection 16 Compiler +collection 17 Walls 1 (water) +collection 18 Walls 2 (lava) +collection 19 Walls 3 (sewage) +collection 20 Walls 4 (jiaro) +collection 21 Walls 5 (pfhor) +collection 22 Scenery 1 (water) +collection 23 Scenery 2 (lava) +collection 24 Scenery 3 (sewage) +collection 25 Scenery 4 (jiaro) +collection 26 Scenery 5 (pfhor) +collection 27 Landscape 1 (daytime) +collection 28 Landscape 2 (nighttime) +collection 29 Landscape 3 (moon) +collection 30 Landscape 4 (space) +collection 31 Cyborg + +# sound class names (from AlephOne sources) +sound 0 Startup +sound 1 Teleport in +sound 2 Teleport out +sound 3 Body being crunched +sound 4 Jjaro ship creak +sound 5 Absorbed +sound 6 Breathing +sound 7 Oxygen warning +sound 8 Suffocation +sound 9 Energy refuel +sound 10 Oxygen refuel +sound 11 Can't toggle switch +sound 12 Switch on +sound 13 Switch off +sound 14 Puzzle switch +sound 15 Chip insertion +sound 16 Pattern buffer +sound 17 Destroy control panel +sound 18 Adjust volume +sound 19 Got powerup +sound 20 Got item +sound 21 Bullet ricochet +sound 22 Metallic ricochet +sound 23 Empty gun +sound 24 S'pht door opening +sound 25 S'pht door closing +sound 26 S'pht door obstructed +sound 27 S'pht platform starting +sound 28 S'pht platform stopping +sound 29 Owl +sound 30 SMG firing +sound 31 SMG reloading +sound 32 Heavy s'pht platform starting +sound 33 Heavy s'pht platform stopping +sound 34 Fist hitting +sound 35 Magnum firing +sound 36 Magnum reloading +sound 37 Assault rifle firing +sound 38 Grenade launcher firing +sound 39 Grenade exploding +sound 40 Grenade flyby +sound 41 Fusion firing +sound 42 Fusion exploding +sound 43 Fusion flyby +sound 44 Fusion charging +sound 45 Rocket exploding +sound 46 Rocket flyby +sound 47 Rocket firing +sound 48 Flamethrower +sound 49 Body falling +sound 50 Body exploding +sound 51 Bullet hitting flesh +sound 52 Fighter activate +sound 53 Fighter wail +sound 54 Fighter scream +sound 55 Fighter chatter +sound 56 Fighter attack +sound 57 Fighter projectile hit +sound 58 Fighter projectile flyby +sound 59 Compiler attack +sound 60 Compiler death +sound 61 Compiler hit +sound 62 Compiler projectile flyby +sound 63 Compiler projectile hit +sound 64 Cyborg moving +sound 65 Cyborg attack +sound 66 Cyborg hit +sound 67 Cyborg death +sound 68 Cyborg projectile bounce +sound 69 Cyborg projectile hit +sound 70 Cyborg projectile flyby +sound 71 Hummer activate +sound 72 Hummer start attack +sound 73 Hummer attack +sound 74 Hummer dying +sound 75 Hummer death +sound 76 Hummer projectile hit +sound 77 Hummer projectile flyby +sound 78 Human wail +sound 79 Human scream +sound 80 Human hit +sound 81 Human chatter +sound 82 Assimilated human chatter +sound 83 Human trash talk +sound 84 Human apology +sound 85 Human activation +sound 86 Human clear +sound 87 Human stop shooting me you bastard +sound 88 Human area secure +sound 89 Kill the player +sound 90 Water +sound 91 Sewage +sound 92 Lava +sound 93 Goo +sound 94 Under media +sound 95 Wind +sound 96 Waterfall +sound 97 Siren +sound 98 Fan +sound 99 S'pht door +sound 100 S'pht platform +sound 101 Alien harmonics +sound 102 Heavy s'pht platform +sound 103 Light machinery +sound 104 Heavy machinery +sound 105 Transformer +sound 106 Sparking transformer +sound 107 Water drip +sound 108 Walking in water +sound 109 Exit water +sound 110 Enter water +sound 111 Small water splash +sound 112 Medium water splash +sound 113 Large water splash +sound 114 Walking in lava +sound 115 Enter lava +sound 116 Exit lava +sound 117 Small lava splash +sound 118 Medium lava splash +sound 119 Large lava splash +sound 120 Walking in sewage +sound 121 Exit sewage +sound 122 Enter sewage +sound 123 Small sewage splash +sound 124 Medium sewage splash +sound 125 Large sewage splash +sound 126 Walking in goo +sound 127 Exit goo +sound 128 Enter goo +sound 129 Small goo splash +sound 130 Medium goo splash +sound 131 Large goo splash +sound 132 Major fusion firing +sound 133 Major fusion charged +sound 134 Assault rifle reloading +sound 135 Assault rifle shell casings +sound 136 Shotgun firing +sound 137 Shotgun reloading +sound 138 Ball bounce +sound 139 You are it +sound 140 Got ball +sound 141 Computer interface logon +sound 142 Computer interface logout +sound 143 Computer interface page +sound 144 Heavy s'pht door +sound 145 Heavy s'pht door opening +sound 146 Heavy s'pht door closing +sound 147 Heavy s'pht door open +sound 148 Heavy s'pht door closed +sound 149 Heavy s'pht door obstructed +sound 150 Hunter activate +sound 151 Hunter attack +sound 152 Hunter dying +sound 153 Hunter landing +sound 154 Hunter exploding +sound 155 Hunter projectile hit +sound 156 Hunter projectile flyby +sound 157 Enforcer activate +sound 158 Enforcer attack +sound 159 Enforcer projectile hit +sound 160 Enforcer projectile flyby +sound 161 Yeti melee attack +sound 162 Yeti melee attack hit +sound 163 Yeti projectile attack +sound 164 Yeti projectile sewage attack hit +sound 165 Yeti projectile sewage flyby +sound 166 Yeti projectile lava attack hit +sound 167 Yeti projectile lava flyby +sound 168 Yeti dying +sound 169 Machine binder +sound 170 Machine bookpress +sound 171 Machine puncher +sound 172 Electric +sound 173 Alarm +sound 174 Night wind +sound 175 Surface explosion +sound 176 Underground explosion +sound 177 Defender attack +sound 178 Defender hit +sound 179 Defender flyby +sound 180 Defender being hit +sound 181 Defender exploding +sound 182 Tick chatter +sound 183 Tick falling +sound 184 Tick flapping +sound 185 Tick exploding +sound 186 Ceiling lamp exploding +sound 187 Pfhor platform starting +sound 188 Pfhor platform stopping +sound 189 Pfhor platform +sound 190 Pfhor door opening +sound 191 Pfhor door closing +sound 192 Pfhor door obstructed +sound 193 Pfhor door +sound 194 Pfhor switch off +sound 195 Pfhor switch on +sound 196 Juggernaut firing +sound 197 Juggernaut warning +sound 198 Juggernaut exploding +sound 199 Juggernaut preparing to fire +sound 200 Enforcer exploding +sound 201 Alien noise 1 +sound 202 Alien noise 2 +sound 203 Civilian fusion wail +sound 204 Civilian fusion scream +sound 205 Civilian fusion hit +sound 206 Civilian fusion chatter +sound 207 Assimilated civilian fusion chatter +sound 208 Civilian fusion trash talk +sound 209 Civilian fusion apology +sound 210 Civilian fusion activation +sound 211 Civilian fusion clear +sound 212 Civilian fusion stop shooting me you bastard +sound 213 Civilian fusion area secure +sound 214 Civilian fusion kill the player diff --git a/GenericEndianBuffer.cpp b/GenericEndianBuffer.cpp new file mode 100644 index 0000000..4f8f3e7 --- /dev/null +++ b/GenericEndianBuffer.cpp @@ -0,0 +1,189 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include +#include +#include "GenericEndianBuffer.h" + +GenericEndianBuffer::GenericEndianBuffer(unsigned int _size): + mSize(0), mSelfAllocated(true) +{ + mData = new unsigned char[_size]; + if (mData != NULL) { + mPosition = mData; + mSize = _size; + } +} + +GenericEndianBuffer::GenericEndianBuffer(unsigned char *_data, unsigned int _size): + mData(_data), mPosition(_data), mSize(_size), mSelfAllocated(false) +{ + +} + +GenericEndianBuffer::~GenericEndianBuffer(void) +{ + if (mSelfAllocated && mData != NULL) { + delete[] mData; + mData = NULL; + } +} + +char GenericEndianBuffer::ReadChar(void) +{ + if ((unsigned int)(mPosition - mData) < mSize) { + unsigned char v = *mPosition; + + mPosition++; + return (char)v; + } else { + std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +unsigned char GenericEndianBuffer::ReadUChar(void) +{ + if ((unsigned int)(mPosition - mData) < mSize) { + unsigned char v = *mPosition; + + mPosition++; + return v; + } else { + std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +void GenericEndianBuffer::ReadBlock(unsigned long _size, unsigned char *dest) +{ + if ((unsigned int)(mPosition - mData + _size - 1) < mSize) { + memcpy(dest, mPosition, _size); + mPosition += _size; + } else { + std::cerr << "GenericEndianBuffer: attempted read beyond buffer limits\n"; + } +} + +void GenericEndianBuffer::WriteChar(char v) +{ + if ((unsigned int)(mPosition - mData) < mSize) + *mPosition++ = v; + else + std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n"; +} + +void GenericEndianBuffer::WriteUChar(unsigned char v) +{ + if ((unsigned int)(mPosition - mData) < mSize) + *mPosition++ = v; + else + std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n"; +} + +void GenericEndianBuffer::Write4CharCode(char c1, char c2, char c3, char c4) +{ + if ((unsigned int)(mPosition - mData + 4 - 1) < mSize) { + *mPosition++ = c1; + *mPosition++ = c2; + *mPosition++ = c3; + *mPosition++ = c4; + } else { + std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void GenericEndianBuffer::WriteBlock(unsigned long _size, const void *src) +{ + if ((unsigned int)(mPosition - mData + _size - 1) < mSize) { + memcpy(mPosition, src, _size); + mPosition += _size; + } else { + std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void GenericEndianBuffer::WriteZeroes(unsigned int n) +{ + if ((unsigned int)(mPosition - mData + n - 1) < mSize) { + memset(mPosition, 0, n); + mPosition += n; + } else { + std::cerr << "GenericEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +unsigned char *GenericEndianBuffer::Data(void) const +{ + return mData; +} + +unsigned int GenericEndianBuffer::Size(void) const +{ + return mSize; +} + +void GenericEndianBuffer::Position(unsigned int pos) +{ + if (pos < mSize) + mPosition = mData + pos; + else + std::cerr << "GenericEndianBuffer: attempted to position beyond buffer limits (" << pos << "/" << (mSize-1) << ")\n"; +} + +unsigned int GenericEndianBuffer::Position(void) const +{ + return mPosition - mData; +} + +static const unsigned long CRC32_POLYNOMIAL = 0xEDB88320L; +static std::vector crc_table; + +static void BuildCRCTable() +{ + if (crc_table.empty()) { + crc_table.resize(256); + + for (unsigned int i = 0; i < crc_table.size(); ++i) { + unsigned long crc = i; + for (int j = 0; j < 8; ++j) { + if (crc & 1) { + crc = (crc >> 1) ^ CRC32_POLYNOMIAL; + } else { + crc >>= 1; + } + crc_table[i] = crc; + } + } + } +} + +unsigned long GenericEndianBuffer::CalculateCRC() const +{ + BuildCRCTable(); + + unsigned long crc = 0xFFFFFFFFL; + + unsigned char* p = mData; + for (unsigned int i = 0; i < mSize; ++i) { + unsigned long a = (crc >> 8) & 0x00FFFFFFL; + unsigned long b = crc_table[((int) crc ^ *p++) & 0xff]; + crc = a^b; + } + return crc ^ 0xFFFFFFFFL; +} diff --git a/GenericEndianBuffer.h b/GenericEndianBuffer.h new file mode 100644 index 0000000..c604a9d --- /dev/null +++ b/GenericEndianBuffer.h @@ -0,0 +1,60 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// GenericEndianBuffer +// + +#ifndef GENERICENDIANBUFFER_H +#define GENERICENDIANBUFFER_H + +class GenericEndianBuffer { +protected: + unsigned char *mData, + *mPosition; + unsigned int mSize; + bool mSelfAllocated; + +public: + // self-allocate data buffer + GenericEndianBuffer(unsigned int _size); + // use a pre-allocated buffer + GenericEndianBuffer(unsigned char *_data, unsigned int _size); + ~GenericEndianBuffer(void); + // set access position + void Position(unsigned int pos); + // return access position + unsigned int Position(void) const; + // read values, advance position accordingly + char ReadChar(void); + unsigned char ReadUChar(void); + void ReadBlock(unsigned long _size, unsigned char *dest); + // write values, advance position accordingly + void WriteChar(char v); + void WriteUChar(unsigned char v); + void Write4CharCode(char c1, char c2, char c3, char c4); + void WriteBlock(unsigned long _size, const void *src); + void WriteZeroes(unsigned int n); + // stuff access + unsigned char *Data(void) const; + unsigned int Size(void) const; + + unsigned long CalculateCRC() const; +}; + +#endif diff --git a/LittleEndianBuffer.cpp b/LittleEndianBuffer.cpp new file mode 100644 index 0000000..8f0f133 --- /dev/null +++ b/LittleEndianBuffer.cpp @@ -0,0 +1,137 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include "LittleEndianBuffer.h" + +LittleEndianBuffer::LittleEndianBuffer(unsigned int _size): + GenericEndianBuffer(_size) +{ + +} + +LittleEndianBuffer::LittleEndianBuffer(unsigned char *_data, unsigned int _size): + GenericEndianBuffer(_data, _size) +{ + +} + +LittleEndianBuffer::~LittleEndianBuffer(void) +{ + +} + +short LittleEndianBuffer::ReadShort(void) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + unsigned char lo = *mPosition++, + hi = *mPosition++; + + return (short)((hi << 8) | lo); + } else { + std::cerr << "LittleEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +unsigned short LittleEndianBuffer::ReadUShort(void) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + unsigned char lo = *mPosition++, + hi = *mPosition++; + + return (unsigned short)((hi << 8) | lo); + } else { + std::cerr << "LittleEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +long LittleEndianBuffer::ReadLong(void) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + unsigned char a = *mPosition++, + b = *mPosition++, + c = *mPosition++, + d = *mPosition++; + + return (long)((d << 24) | (c << 16) | (b << 8) | a); + } else { + std::cerr << "LittleEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +unsigned long LittleEndianBuffer::ReadULong(void) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + unsigned char a = *mPosition++, + b = *mPosition++, + c = *mPosition++, + d = *mPosition++; + + return (unsigned long)((d << 24) | (c << 16) | (b << 8) | a); + } else { + std::cerr << "LittleEndianBuffer: attempted read beyond buffer limits\n"; + return 0; + } +} + +void LittleEndianBuffer::WriteShort(short v) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + *mPosition++ = v & 0xff; + *mPosition++ = (v >> 8) & 0xff; + } else { + std::cerr << "LittleEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void LittleEndianBuffer::WriteUShort(unsigned short v) +{ + if ((unsigned int)(mPosition - mData + 1) < mSize) { + *mPosition++ = v & 0xff; + *mPosition++ = (v >> 8) & 0xff; + } else { + std::cerr << "LittleEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void LittleEndianBuffer::WriteLong(long v) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + *mPosition++ = v & 0xff; + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = (v >> 16) & 0xff; + *mPosition++ = (v >> 24) & 0xff; + } else { + std::cerr << "LittleEndianBuffer: attempted write beyond buffer limits\n"; + } +} + +void LittleEndianBuffer::WriteULong(unsigned long v) +{ + if ((unsigned int)(mPosition - mData + 3) < mSize) { + *mPosition++ = v & 0xff; + *mPosition++ = (v >> 8) & 0xff; + *mPosition++ = (v >> 16) & 0xff; + *mPosition++ = (v >> 24) & 0xff; + } else { + std::cerr << "LittleEndianBuffer: attempted write beyond buffer limits\n"; + } +} + diff --git a/LittleEndianBuffer.h b/LittleEndianBuffer.h new file mode 100644 index 0000000..46fcf29 --- /dev/null +++ b/LittleEndianBuffer.h @@ -0,0 +1,48 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// LittleEndianBuffer +// Utility class to access little-endian data buffers easily +// + +#ifndef LITTLEENDIANBUFFER_H +#define LITTLEENDIANBUFFER_H + +#include "GenericEndianBuffer.h" + +class LittleEndianBuffer: public GenericEndianBuffer { +public: + // self-allocate data buffer + LittleEndianBuffer(unsigned int _size); + // use a pre-allocated buffer + LittleEndianBuffer(unsigned char *_data, unsigned int _size); + ~LittleEndianBuffer(void); + // read little-endian values, advance position accordingly + short ReadShort(void); + unsigned short ReadUShort(void); + long ReadLong(void); + unsigned long ReadULong(void); + // write little-endian values, advance position accordingly + void WriteShort(short v); + void WriteUShort(unsigned short v); + void WriteLong(long v); + void WriteULong(unsigned long v); +}; + +#endif diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..dcff0e7 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,35 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = Physics Shapes Sounds + +AUTOMAKE_OPTIONS = 1.5 foreign + +EXTRA_DIST = ShapeFusion.xcodeproj/project.pbxproj COPYING.txt \ + DefaultNames.txt README.txt ShapeFusion-Info.plist \ + Resources/shapefusion.icns Resources/shapefusion.ico \ + Resources/shapefusion.rc Resources/shapefusion.svg + +if MAKE_WINDOWS +bin_PROGRAMS = ShapeFusion +else +bin_PROGRAMS = shapefusion +endif + +shapefusion_SOURCES = BigEndianBuffer.h DefaultNames.h \ + GenericEndianBuffer.h LittleEndianBuffer.h ShapeFusionApp.h \ + ShapeFusionDocManager.h ShapeFusionMain.h ShapeFusionMenus.h \ + BigEndianBuffer.cpp DefaultNames.cpp GenericEndianBuffer.cpp \ + LittleEndianBuffer.cpp ShapeFusionApp.cpp \ + ShapeFusionDocManager.cpp ShapeFusionMain.cpp \ + ShapeFusionMenus.cpp + +shapefusion_LDADD = \ + Physics/libphysics.a Shapes/libshapes.a Sounds/libsounds.a + +ShapeFusion_SOURCES = $(shapefusion_SOURCES) +ShapeFusion_LDADD = $(shapefusion_LDADD) shapefusion-resources.o + +INCLUDES = -I$(top_srcdir)/Physics -I$(top_srcdir)/Shapes -I$(top_srcdir)/Sounds + +shapefusion-resources.o: $(top_srcdir)/Resources/shapefusion.rc + @WX_RESCOMP@ -I$(top_srcdir)/Resources $(top_srcdir)/Resources/shapefusion.rc -o shapefusion-resources.o diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..0c8c414 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,863 @@ +# Makefile.in generated by automake 1.11.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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 = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@MAKE_WINDOWS_FALSE@bin_PROGRAMS = shapefusion$(EXEEXT) +@MAKE_WINDOWS_TRUE@bin_PROGRAMS = ShapeFusion$(EXEEXT) +subdir = . +DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure config.guess config.sub depcomp \ + install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = BigEndianBuffer.$(OBJEXT) DefaultNames.$(OBJEXT) \ + GenericEndianBuffer.$(OBJEXT) LittleEndianBuffer.$(OBJEXT) \ + ShapeFusionApp.$(OBJEXT) ShapeFusionDocManager.$(OBJEXT) \ + ShapeFusionMain.$(OBJEXT) ShapeFusionMenus.$(OBJEXT) +am_ShapeFusion_OBJECTS = $(am__objects_1) +ShapeFusion_OBJECTS = $(am_ShapeFusion_OBJECTS) +ShapeFusion_DEPENDENCIES = $(shapefusion_LDADD) \ + shapefusion-resources.o +am_shapefusion_OBJECTS = BigEndianBuffer.$(OBJEXT) \ + DefaultNames.$(OBJEXT) GenericEndianBuffer.$(OBJEXT) \ + LittleEndianBuffer.$(OBJEXT) ShapeFusionApp.$(OBJEXT) \ + ShapeFusionDocManager.$(OBJEXT) ShapeFusionMain.$(OBJEXT) \ + ShapeFusionMenus.$(OBJEXT) +shapefusion_OBJECTS = $(am_shapefusion_OBJECTS) +shapefusion_DEPENDENCIES = Physics/libphysics.a Shapes/libshapes.a \ + Sounds/libsounds.a +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(ShapeFusion_SOURCES) $(shapefusion_SOURCES) +DIST_SOURCES = $(ShapeFusion_SOURCES) $(shapefusion_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = Physics Shapes Sounds +AUTOMAKE_OPTIONS = 1.5 foreign +EXTRA_DIST = ShapeFusion.xcodeproj/project.pbxproj COPYING.txt \ + DefaultNames.txt README.txt ShapeFusion-Info.plist \ + Resources/shapefusion.icns Resources/shapefusion.ico \ + Resources/shapefusion.rc Resources/shapefusion.svg + +shapefusion_SOURCES = BigEndianBuffer.h DefaultNames.h \ + GenericEndianBuffer.h LittleEndianBuffer.h ShapeFusionApp.h \ + ShapeFusionDocManager.h ShapeFusionMain.h ShapeFusionMenus.h \ + BigEndianBuffer.cpp DefaultNames.cpp GenericEndianBuffer.cpp \ + LittleEndianBuffer.cpp ShapeFusionApp.cpp \ + ShapeFusionDocManager.cpp ShapeFusionMain.cpp \ + ShapeFusionMenus.cpp + +shapefusion_LDADD = \ + Physics/libphysics.a Shapes/libshapes.a Sounds/libsounds.a + +ShapeFusion_SOURCES = $(shapefusion_SOURCES) +ShapeFusion_LDADD = $(shapefusion_LDADD) shapefusion-resources.o +INCLUDES = -I$(top_srcdir)/Physics -I$(top_srcdir)/Shapes -I$(top_srcdir)/Sounds +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .cpp .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +ShapeFusion$(EXEEXT): $(ShapeFusion_OBJECTS) $(ShapeFusion_DEPENDENCIES) + @rm -f ShapeFusion$(EXEEXT) + $(CXXLINK) $(ShapeFusion_OBJECTS) $(ShapeFusion_LDADD) $(LIBS) +shapefusion$(EXEEXT): $(shapefusion_OBJECTS) $(shapefusion_DEPENDENCIES) + @rm -f shapefusion$(EXEEXT) + $(CXXLINK) $(shapefusion_OBJECTS) $(shapefusion_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BigEndianBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultNames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericEndianBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LittleEndianBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapeFusionApp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapeFusionDocManager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapeFusionMain.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapeFusionMenus.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +# 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): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + 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; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + 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; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -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 $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | 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 + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(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 ../.. && umask 077 && mkdir "$$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 \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { 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 $(PROGRAMS) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-binPROGRAMS \ + clean-generic ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS + + +shapefusion-resources.o: $(top_srcdir)/Resources/shapefusion.rc + @WX_RESCOMP@ -I$(top_srcdir)/Resources $(top_srcdir)/Resources/shapefusion.rc -o shapefusion-resources.o + +# 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/Physics/Makefile.am b/Physics/Makefile.am new file mode 100644 index 0000000..119dbe4 --- /dev/null +++ b/Physics/Makefile.am @@ -0,0 +1,8 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libphysics.a + +libphysics_a_SOURCES = PhysicsDocument.h PhysicsElements.h \ + PhysicsTreeItemData.h PhysicsView.h PhysicsDocument.cpp \ + PhysicsEditor.cpp PhysicsElements.cpp PhysicsView.cpp \ + PhysicsTreeItemData.cpp diff --git a/Physics/Makefile.in b/Physics/Makefile.in new file mode 100644 index 0000000..cb097d8 --- /dev/null +++ b/Physics/Makefile.in @@ -0,0 +1,471 @@ +# Makefile.in generated by automake 1.11.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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 = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = Physics +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libphysics_a_AR = $(AR) $(ARFLAGS) +libphysics_a_LIBADD = +am_libphysics_a_OBJECTS = PhysicsDocument.$(OBJEXT) \ + PhysicsEditor.$(OBJEXT) PhysicsElements.$(OBJEXT) \ + PhysicsView.$(OBJEXT) PhysicsTreeItemData.$(OBJEXT) +libphysics_a_OBJECTS = $(am_libphysics_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libphysics_a_SOURCES) +DIST_SOURCES = $(libphysics_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libphysics.a +libphysics_a_SOURCES = PhysicsDocument.h PhysicsElements.h \ + PhysicsTreeItemData.h PhysicsView.h PhysicsDocument.cpp \ + PhysicsEditor.cpp PhysicsElements.cpp PhysicsView.cpp \ + PhysicsTreeItemData.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Physics/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Physics/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libphysics.a: $(libphysics_a_OBJECTS) $(libphysics_a_DEPENDENCIES) + -rm -f libphysics.a + $(libphysics_a_AR) libphysics.a $(libphysics_a_OBJECTS) $(libphysics_a_LIBADD) + $(RANLIB) libphysics.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhysicsDocument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhysicsEditor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhysicsElements.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhysicsTreeItemData.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PhysicsView.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-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/Physics/PhysicsDocument.cpp b/Physics/PhysicsDocument.cpp new file mode 100644 index 0000000..bf8630c --- /dev/null +++ b/Physics/PhysicsDocument.cpp @@ -0,0 +1,292 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if wxUSE_STD_IOSTREAM + #include "wx/ioswrap.h" +#else + #include "wx/txtstrm.h" +#endif + +#include "../BigEndianBuffer.h" +#include "PhysicsDocument.h" + +#define FOUR_CHARS_TO_INT(a,b,c,d) (((unsigned int)(a) << 24) | ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d)) + +IMPLEMENT_DYNAMIC_CLASS(PhysicsDocument, wxDocument) + +PhysicsDocument::PhysicsDocument() : wxDocument(), PhysicsElement(true) +{ + mConstants.resize(2); +} + +PhysicsDocument::~PhysicsDocument() +{ +} + +bool PhysicsDocument::DoOpenDocument(const wxString& file) +{ + bool wxOpen = wxDocument::DoOpenDocument(file); + + if (!(wxOpen && mGoodData)) { + wxLogError(wxT("[PhysicsDocument] There was an error while opening, see log")); + return false; + } + return true; +} + +#if wxUSE_STD_IOSTREAM +wxSTD istream& PhysicsDocument::LoadObject(wxSTD istream& stream) +#else +wxInputStream& PhysicsDocument::LoadObject(wxInputStream& stream) +#endif +{ + // validate the wad header, load the first wad + BigEndianBuffer wad_header(128); +#if wxUSE_STD_IOSTREAM + stream.read((char *)wad_header.Data(), wad_header.Size()); +#else + stream.Read((char *)wad_header.Data(), wad_header.Size()); +#endif + + int version = wad_header.ReadShort(); + int data_version = wad_header.ReadShort(); + + if (!(version == 1 || version == 2) || !(data_version == 0 || data_version == 1)) { + wxLogError(wxT("[PhysicsDocument] Error loading: Incorrect version/data version (%i/%i)"), version, data_version); + return stream; + } + + wad_header.ReadBlock(MAXIMUM_WADFILE_NAME_LENGTH, wadfile_name); + + // skip to the directory offset and wad count + wad_header.Position(72); + + long directory_offset = wad_header.ReadLong(); + int wad_count = wad_header.ReadShort(); + wad_header.ReadShort(); // application specific directory data size + int entry_header_size = wad_header.ReadShort(); + + if (wad_count != 1) { + wxLogError(wxT("[PhysicsDocument] Error loading: wad count must be 1")); + return stream; + } + + // jump to the directory and read the offset of the first (and + // hopefully only) wad + BigEndianBuffer directory_entry(10); +#if wxUSE_STD_IOSTREAM + stream.seekg(directory_offset, std::ios::beg); + stream.read((char *) directory_entry.Data(), directory_entry.Size()); +#else + stream.SeekI(directory_offset, wxFromStart); + stream.Read((char *) directory_entry.Data(), directory_entry.Size()); +#endif + long wad_offset = directory_entry.ReadLong(); + directory_entry.ReadLong(); // wad_size + int wad_index = directory_entry.ReadShort(); + + if (wad_index != 0) { + wxLogError(wxT("[PhysicsDocument] Error loading: first wad index must be 0")); + return stream; + } + + long next_offset = 0; + + // read the tags + do { + BigEndianBuffer entry_header(entry_header_size); +#if wxUSE_STD_IOSTREAM + stream.seekg(next_offset + wad_offset, std::ios::beg); + stream.read((char *) entry_header.Data(), entry_header.Size()); +#else + stream.SeekI(next_offset + wad_offset, wxFromStart); + stream.Read((char *) entry_header.Data(), entry_header.Size()); +#endif + unsigned long tag = entry_header.ReadULong(); + next_offset = entry_header.ReadLong(); + long entry_size = entry_header.ReadLong(); + + BigEndianBuffer tag_data(entry_size); +#if wxUSE_STD_IOSTREAM + stream.read((char *) tag_data.Data(), tag_data.Size()); +#else + stream.Read((char *) tag_data.Data(), tag_data.Size()); +#endif + + switch (tag) + { + case FOUR_CHARS_TO_INT('M','N','p','x'): { + int count = tag_data.Size() / MonsterDefinition::kSize; + mMonsterDefinitions.resize(count); + for (int i = 0; i < count; ++i) { + mMonsterDefinitions[i].LoadObject(tag_data); + if (!mMonsterDefinitions[i].IsGood()) { + return stream; + } + } + break; + } + case FOUR_CHARS_TO_INT('F','X','p','x'): { + int count = tag_data.Size() / EffectDefinition::kSize; + mEffectDefinitions.resize(count); + for (int i = 0; i < count; ++i) { + mEffectDefinitions[i].LoadObject(tag_data); + if (!mEffectDefinitions[i].IsGood()) { + return stream; + } + } + break; + } + case FOUR_CHARS_TO_INT('P','R','p','x'): { + int count = tag_data.Size() / ProjectileDefinition::kSize; + mProjectileDefinitions.resize(count); + for (int i = 0; i < count; ++i) { + mProjectileDefinitions[i].LoadObject(tag_data); + if (!mProjectileDefinitions[i].IsGood()) { + return stream; + } + } + break; + } + case FOUR_CHARS_TO_INT('P','X','p','x'): { + int count = tag_data.Size() / PhysicsConstants::kSize; + mConstants.resize(2); + for (int i = 0; i < count; ++i) { + mConstants[i].LoadObject(tag_data); + if (!mConstants[i].IsGood()) { + return stream; + } + } + break; + } + case FOUR_CHARS_TO_INT('W','P','p','x'): { + int count = tag_data.Size() / WeaponDefinition::kSize; + mWeaponDefinitions.resize(count); + for (int i = 0; i < count; ++i) { + mWeaponDefinitions[i].LoadObject(tag_data); + if (!mWeaponDefinitions[i].IsGood()) { + return stream; + } + } + break; + } + } + } while (next_offset); + + if (mConstants.size() && mMonsterDefinitions.size() && mEffectDefinitions.size() && mProjectileDefinitions.size() && mWeaponDefinitions.size()) { + mGoodData = true; + } + + return stream; +} + +template +void PhysicsDocument::WriteTag(BigEndianBuffer& buffer, long& offset, unsigned long tag, const std::vector& data, bool last) +{ + long entry_size = T::kSize * data.size(); + offset += entry_size + kEntryHeaderSize; + + buffer.WriteULong(tag); + buffer.WriteLong(last ? 0 : offset); + buffer.WriteLong(entry_size); + buffer.WriteLong(0); + + for (typename std::vector::const_iterator it = data.begin(); it != data.end(); ++it) { + it->SaveObject(buffer); + } + +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& PhysicsDocument::SaveObject(wxSTD ostream& stream) +#else +wxOutputStream& PhysicsDocument::SaveObject(wxOutputStream& stream) +#endif +{ + unsigned long filesize = SizeInFile(); + BigEndianBuffer buffer(filesize); + + // header + buffer.WriteShort(2); // version + buffer.WriteShort(0); // data version + buffer.WriteBlock(MAXIMUM_WADFILE_NAME_LENGTH, wadfile_name); + buffer.WriteULong(0); // blank checksum + buffer.WriteLong(filesize - 10); // directory offset + buffer.WriteShort(1); // wad count + buffer.WriteShort(0); // application specific data size + buffer.WriteShort(kEntryHeaderSize); // entry header size + buffer.WriteShort(10); // directory entry size + buffer.WriteLong(0); // parent checksum + buffer.WriteZeroes(40); // unused + + // tags + long next_offset = 0; + WriteTag(buffer, next_offset, FOUR_CHARS_TO_INT('M','N','p','x'), mMonsterDefinitions); + WriteTag(buffer, next_offset, FOUR_CHARS_TO_INT('F','X','p','x'), mEffectDefinitions); + WriteTag(buffer, next_offset, FOUR_CHARS_TO_INT('P','R','p','x'), mProjectileDefinitions); + WriteTag(buffer, next_offset, FOUR_CHARS_TO_INT('P','X','p','x'), mConstants); + WriteTag(buffer, next_offset, FOUR_CHARS_TO_INT('W','P','p','x'), mWeaponDefinitions, true); + + // directory + buffer.WriteLong(128); + buffer.WriteLong(filesize - 128 - 10); + buffer.WriteShort(0); + + buffer.Position(68); + buffer.WriteULong(buffer.CalculateCRC()); + +#if wxUSE_STD_IOSTREAM + stream.write(reinterpret_cast(buffer.Data()), buffer.Size()); +#else + stream.Write(reinterpret_cast(buffer.Data()), buffer.Size()); +#endif + + return stream; +} + +unsigned long PhysicsDocument::SizeInFile() +{ + unsigned long size = 0; + size += 128; // wad header + + size += kEntryHeaderSize; + size += MonsterDefinition::kSize * mMonsterDefinitions.size(); + + size += kEntryHeaderSize; + size += EffectDefinition::kSize * mEffectDefinitions.size(); + + size += kEntryHeaderSize; + size += ProjectileDefinition::kSize * mProjectileDefinitions.size(); + + size += kEntryHeaderSize; + size += PhysicsConstants::kSize * mConstants.size(); + + size += kEntryHeaderSize; + size += WeaponDefinition::kSize * mWeaponDefinitions.size(); + + size += 10; // directory entry + + return size; +} diff --git a/Physics/PhysicsDocument.h b/Physics/PhysicsDocument.h new file mode 100644 index 0000000..4549261 --- /dev/null +++ b/Physics/PhysicsDocument.h @@ -0,0 +1,93 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __PHYSICSDOCUMENT_H__ +#define __PHYSICSDOCUMENT_H__ + +#include "wx/docview.h" +#include "wx/cmdproc.h" + +#include + +#include + +#include "PhysicsElements.h" + +class PhysicsDocument : public wxDocument, public PhysicsElement +{ + DECLARE_DYNAMIC_CLASS(PhysicsDocument) + +private: + std::vector mMonsterDefinitions; + std::vector mEffectDefinitions; + std::vector mProjectileDefinitions; + std::vector mConstants; + std::vector mWeaponDefinitions; + + static const int MAXIMUM_WADFILE_NAME_LENGTH = 64; + unsigned char wadfile_name[MAXIMUM_WADFILE_NAME_LENGTH]; + + static const int kEntryHeaderSize = 16; + +public: + // counts + unsigned int MonsterCount() const { return mMonsterDefinitions.size(); } + unsigned int EffectCount() const { return mEffectDefinitions.size(); } + unsigned int ProjectileCount() const { return mProjectileDefinitions.size(); } + unsigned int PhysicsConstantsCount() const { return mConstants.size(); } + unsigned int WeaponCount() const { return mWeaponDefinitions.size(); } + + // element accessors + PhysicsConstants* GetPhysicsConstants(unsigned int id) { + return &mConstants[id]; + } + + EffectDefinition* GetEffectDefinition(unsigned int id) { + return &mEffectDefinitions[id]; + } + + ProjectileDefinition* GetProjectileDefinition(unsigned int id) { + return &mProjectileDefinitions[id]; + } + + MonsterDefinition* GetMonsterDefinition(unsigned int id) { + return &mMonsterDefinitions[id]; + } + + WeaponDefinition* GetWeaponDefinition(unsigned int id) { + return &mWeaponDefinitions[id]; + } + + PhysicsDocument(); + ~PhysicsDocument(); + + bool DoOpenDocument(const wxString& file); + +#if wxUSE_STD_IOSTREAM + wxSTD ostream& SaveObject(wxSTD ostream& stream); + wxSTD istream& LoadObject(wxSTD istream& stream); +#else + wxOutputStream& SaveObject(wxOutputStream& stream); + wxInputStream& LoadObject(wxInputStream& stream); +#endif + + unsigned long SizeInFile(); + template void WriteTag(BigEndianBuffer& buffer, long& offset, unsigned long tag, const std::vector& data, bool last = false); +}; + +#endif diff --git a/Physics/PhysicsEditor.cpp b/Physics/PhysicsEditor.cpp new file mode 100644 index 0000000..cbe58da --- /dev/null +++ b/Physics/PhysicsEditor.cpp @@ -0,0 +1,1361 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/clipbrd.h" + +#include + +#include "PhysicsView.h" +#include "PhysicsTreeItemData.h" +#include "../ShapeFusionMenus.h" + +BEGIN_EVENT_TABLE(PhysicsView, wxView) + EVT_MENU(EDIT_MENU_COPY, PhysicsView::MenuEditCopy) + EVT_MENU(EDIT_MENU_PASTE, PhysicsView::MenuEditPaste) + EVT_TREE_SEL_CHANGED(-1, PhysicsView::OnTreeSelect) + EVT_COMMAND_RANGE(FIELD_ALIEN_COLLECTION, FIELD_ALIEN_RANGED_ATTACK_SHAPE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_TEXT(FIELD_ALIEN_RANDOM_SOUND_MASK, PhysicsView::EditAlienFields) + EVT_TEXT(FIELD_ALIEN_SOUND_PITCH, PhysicsView::EditAlienDoubles) + EVT_COMMAND_RANGE(MENU_ALIEN_ACTIVATION, MENU_ALIEN_RANDOM, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditAlienMenus) + EVT_TEXT(FIELD_ALIEN_ATTACK_FREQUENCY, PhysicsView::EditAlienFields) + EVT_CHOICE(MENU_ALIEN_ATTACK_TYPE, PhysicsView::EditAlienMenus) + EVT_COMMAND_RANGE(FIELD_ALIEN_ATTACK_REPETITIONS, FIELD_ALIEN_ATTACK_DZ, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_CHOICE(MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS, PhysicsView::EditAlienMenus) + EVT_COMMAND_RANGE(FIELD_ALIEN_ATTACK_REPETITIONS + NUM_ALIEN_ATTACK_CONTROLS, FIELD_ALIEN_ATTACK_DZ + NUM_ALIEN_ATTACK_CONTROLS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_TEXT(FIELD_ALIEN_SHRAPNEL_RADIUS, PhysicsView::EditAlienFields) + EVT_CHOICE(MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE, PhysicsView::EditAlienMenus) + EVT_COMMAND_RANGE(FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE, FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_TEXT(FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE, PhysicsView::EditAlienDoubles) + EVT_CHECKBOX(CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE, PhysicsView::EditAlienCheckboxes) + EVT_CHOICE(MENU_ALIEN_RANGED_IMPACT_EFFECT, PhysicsView::EditAlienMenus) + EVT_CHOICE(MENU_ALIEN_MELEE_IMPACT_EFFECT, PhysicsView::EditAlienMenus) + EVT_COMMAND_RANGE(FIELD_ALIEN_VITALITY, FIELD_ALIEN_MAX_LEDGE_JUMP, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_TEXT(FIELD_ALIEN_EXT_VELOCITY_SCALE, PhysicsView::EditAlienDoubles) + EVT_COMMAND_RANGE(FIELD_ALIEN_HOVER_HEIGHT, FIELD_ALIEN_INTELLIGENCE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields) + EVT_COMMAND_RANGE(MENU_ALIEN_CARRYING_ITEM, MENU_ALIEN_CLASS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditAlienMenus) + EVT_COMMAND_RANGE(CB_ALIEN_FRIENDS, CB_ALIEN_WEAKNESSES + 23, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditAlienCheckboxes) + + EVT_COMMAND_RANGE(FIELD_EFFECT_COLLECTION, FIELD_EFFECT_SEQUENCE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditEffectFields) + EVT_TEXT(FIELD_EFFECT_PITCH, PhysicsView::EditEffectDoubles) + EVT_CHOICE(MENU_EFFECT_DELAY_SOUND, PhysicsView::EditEffectMenus) + EVT_COMMAND_RANGE(CB_EFFECT_END_WHEN_ANIMATION_LOOPS, CB_EFFECT_MEDIA_EFFECT, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditEffectCheckboxes) + + EVT_COMMAND_RANGE(CB_SHOT_FLAGS, CB_SHOT_ALIEN_DAMAGE, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditShotCheckboxes) + EVT_COMMAND_RANGE(FIELD_SHOT_COLLECTION, FIELD_SHOT_MAXIMUM_CONTRAILS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditShotFields) + EVT_COMMAND_RANGE(FIELD_SHOT_DAMAGE_SCALE, FIELD_SHOT_SOUND_PITCH, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditShotDoubles) + EVT_COMMAND_RANGE(MENU_SHOT_DAMAGE_TYPE, MENU_SHOT_MEDIA_IMPACT, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditShotMenus) + + EVT_COMMAND_RANGE(FIELD_MAX_FORWARD_VELOCITY, FIELD_HALF_CAMERA_SEPARATION, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditPhysicsConstants) + + EVT_COMMAND_RANGE(CB_WEAPON_FLAGS, CB_WEAPON_FLAGS + 9, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditWeaponCheckboxes) + EVT_COMMAND_RANGE(FIELD_WEAPON_COLLECTION, FIELD_WEAPON_FLASH_DECAY, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditWeaponFields) + EVT_COMMAND_RANGE(FIELD_WEAPON_FLASH_INTENSITY, FIELD_WEAPON_IDLE_WIDTH, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditWeaponDoubles) + EVT_COMMAND_RANGE(MENU_WEAPON_ITEM_TYPE, MENU_WEAPON_CLASS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditWeaponMenus) + EVT_COMMAND_RANGE(FIELD_TRIGGER_ROUNDS, FIELD_TRIGGER_BURST_COUNT, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditTriggerFields) + EVT_COMMAND_RANGE(FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS, FIELD_TRIGGER_BURST_COUNT + NUM_TRIGGER_IDS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditTriggerFields) + EVT_COMMAND_RANGE(MENU_TRIGGER_PROJECTILE, MENU_TRIGGER_SHELL_CASING_TYPE, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditTriggerMenus) + EVT_COMMAND_RANGE(MENU_TRIGGER_PROJECTILE + NUM_TRIGGER_IDS, MENU_TRIGGER_SHELL_CASING_TYPE + NUM_TRIGGER_IDS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditTriggerMenus) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(PhysicsView, wxView) + + +static inline wxString Format(double f) { + return wxString::Format(wxT("%0.4f"), f); +} + +static inline wxString Format(unsigned short u) { + return wxString::Format(wxT("%hu"), u); +} + +static inline wxString Format(short i) { + return wxString::Format(wxT("%hi"), i); +} + +void PhysicsView::OnSelectPhysicsConstants(int index) +{ + PhysicsConstants* constants = static_cast(GetDocument())->GetPhysicsConstants(index); + + max_forward_velocity_field->ChangeValue(Format(constants->GetMaximumForwardVelocity())); + max_backward_velocity_field->ChangeValue(Format(constants->GetMaximumBackwardVelocity())); + max_perpendicular_velocity_field->ChangeValue(Format(constants->GetMaximumPerpendicularVelocity())); + + acceleration_field->ChangeValue(Format(constants->GetAcceleration())); + deceleration_field->ChangeValue(Format(constants->GetDeceleration())); + airborne_deceleration_field->ChangeValue(Format(constants->GetAirborneDeceleration())); + gravitational_acceleration_field->ChangeValue(Format(constants->GetGravitationalAcceleration())); + climbing_acceleration_field->ChangeValue(Format(constants->GetClimbingAcceleration())); + terminal_velocity_field->ChangeValue(Format(constants->GetTerminalVelocity())); + external_deceleration_field->ChangeValue(Format(constants->GetExternalDeceleration())); + + step_delta_field->ChangeValue(Format(constants->GetStepDelta())); + step_amplitude_field->ChangeValue(Format(constants->GetStepAmplitude())); + + radius_field->ChangeValue(Format(constants->GetRadius())); + height_field->ChangeValue(Format(constants->GetHeight())); + + angular_acceleration_field->ChangeValue(Format(constants->GetAngularAcceleration())); + angular_deceleration_field->ChangeValue(Format(constants->GetAngularDeceleration())); + maximum_angular_velocity_field->ChangeValue(Format(constants->GetMaximumAngularVelocity())); + angular_recentering_velocity_field->ChangeValue(Format(constants->GetAngularRecenteringVelocity())); + head_angular_velocity_field->ChangeValue(Format(constants->GetFastAngularVelocity())); + head_angular_maximum_field->ChangeValue(Format(constants->GetFastAngularMaximum())); + maximum_elevation_field->ChangeValue(Format(constants->GetMaximumElevation())); + external_angular_deceleration_field->ChangeValue(Format(constants->GetExternalAngularDeceleration())); + + dead_height_field->ChangeValue(Format(constants->GetDeadHeight())); + camera_height_field->ChangeValue(Format(constants->GetCameraHeight())); + splash_height_field->ChangeValue(Format(constants->GetSplashHeight())); + half_camera_separation_field->ChangeValue(Format(constants->GetHalfCameraSeparation())); + + mainbox->Show(physics_sizer, true); +} + +void PhysicsView::OnSelectAlienAppearance(int index) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(index); + + alien_collection_field->ChangeValue(Format(monster->GetCollection())); + alien_color_table_field->ChangeValue(Format(monster->GetColorTable())); + + alien_hit_field->ChangeValue(Format(monster->GetHitShapes())); + alien_hard_dying_field->ChangeValue(Format(monster->GetHardDyingShape())); + alien_soft_dying_field->ChangeValue(Format(monster->GetSoftDyingShape())); + alien_hard_dead_field->ChangeValue(Format(monster->GetHardDeadShapes())); + alien_soft_dead_field->ChangeValue(Format(monster->GetSoftDeadShapes())); + alien_stationary_field->ChangeValue(Format(monster->GetStationaryShape())); + alien_moving_field->ChangeValue(Format(monster->GetMovingShape())); + alien_teleport_in_field->ChangeValue(Format(monster->GetTeleportInShape())); + alien_teleport_out_field->ChangeValue(Format(monster->GetTeleportOutShape())); + alien_melee_attack_shape_field->ChangeValue(Format(monster->GetMeleeAttack()->GetShape())); + alien_ranged_attack_shape_field->ChangeValue(Format(monster->GetRangedAttack()->GetShape())); + + alien_activation_choice->SetSelection(monster->GetActivationSound() + 1); + alien_friendly_activation_choice->SetSelection(monster->GetFriendlyActivationSound() + 1); + alien_clear_choice->SetSelection(monster->GetClearSound() + 1); + alien_kill_choice->SetSelection(monster->GetKillSound() + 1); + alien_apology_choice->SetSelection(monster->GetApologySound() + 1); + alien_friendly_fire_choice->SetSelection(monster->GetFriendlyFireSound() + 1); + alien_flaming_choice->SetSelection(monster->GetFlamingSound() + 1); + alien_random_choice->SetSelection(monster->GetRandomSound() + 1); + + alien_random_sound_mask_field->ChangeValue(Format(monster->GetRandomSoundMask())); + alien_sound_pitch_field->ChangeValue(Format(monster->GetSoundPitch())); + + mainbox->Show(aliens_appearance_sizer, true); +} + +void PhysicsView::OnSelectAlienCombat(int index) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(index); + + alien_attack_frequency_field->ChangeValue(Format(monster->GetAttackFrequency())); + + for (int i = 0; i < 2; ++i) { + AttackDefinition* attack = (i == 0) ? monster->GetMeleeAttack() : monster->GetRangedAttack(); + alien_attack_type_choices[i]->SetSelection(attack->GetType() + 1); + alien_attack_repetitions_fields[i]->ChangeValue(Format(attack->GetRepetitions())); + // Anvil displays the raw angle units here... + alien_attack_error_fields[i]->ChangeValue(Format(static_cast(std::floor(attack->GetError() * 512.0 / 360.0 + 0.5)))); + alien_attack_range_fields[i]->ChangeValue(Format(attack->GetRange())); + alien_attack_sequence_fields[i]->ChangeValue(Format(attack->GetShape())); + alien_attack_dx_fields[i]->ChangeValue(Format(attack->GetDx())); + alien_attack_dy_fields[i]->ChangeValue(Format(attack->GetDy())); + alien_attack_dz_fields[i]->ChangeValue(Format(attack->GetDz())); + } + + alien_shrapnel_radius_field->ChangeValue(Format(monster->GetShrapnelRadius())); + + DamageDefinition* shrapnel = monster->GetShrapnelDamage(); + alien_shrapnel_damage_type_choice->SetSelection(shrapnel->GetType() + 1); + alien_shrapnel_base_damage_field->ChangeValue(Format(shrapnel->GetBase())); + alien_shrapnel_random_damage_field->ChangeValue(Format(shrapnel->GetRandom())); + alien_shrapnel_damage_scale_field->ChangeValue(Format(shrapnel->GetScale())); + alien_shrapnel_alien_damage_checkbox->SetValue(shrapnel->GetAlien()); + + alien_ranged_impact_effect_choice->SetSelection(monster->GetImpactEffect() + 1); + alien_melee_impact_effect_choice->SetSelection(monster->GetMeleeImpactEffect() + 1); + + mainbox->Show(aliens_combat_sizer, true); +} + +void PhysicsView::OnSelectAlienConstants(int index) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(index); + + alien_vitality_field->ChangeValue(Format(monster->GetVitality())); + + alien_radius_field->ChangeValue(Format(monster->GetRadius())); + alien_height_field->ChangeValue(Format(monster->GetHeight())); + + alien_speed_field->ChangeValue(Format(monster->GetSpeed())); + + alien_terminal_velocity_field->ChangeValue(Format(monster->GetTerminalVelocity())); + alien_gravity_field->ChangeValue(Format(monster->GetGravity())); + + alien_min_ledge_jump_field->ChangeValue(Format(monster->GetMinimumLedgeDelta())); + alien_max_ledge_jump_field->ChangeValue(Format(monster->GetMaximumLedgeDelta())); + alien_ext_velocity_scale_field->ChangeValue(Format(monster->GetExternalVelocityScale())); + alien_hover_height_field->ChangeValue(Format(monster->GetPreferredHoverHeight())); + + alien_door_retry_mask_field->ChangeValue(Format(monster->GetDoorRetryMask())); + + alien_visual_range_field->ChangeValue(Format(monster->GetVisualRange())); + alien_dark_visual_range_field->ChangeValue(Format(monster->GetDarkVisualRange())); + alien_intelligence_field->ChangeValue(Format(monster->GetIntelligence())); + + alien_carrying_item_choice->SetSelection(monster->GetCarryingItemType() + 1); + alien_contrail_effect_choice->SetSelection(monster->GetContrailEffect() + 1); + + mainbox->Show(aliens_constants_sizer, true); +} + +void PhysicsView::OnSelectAlienBehavior(int index) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(index); + + int monster_class_index = 0; + long monster_class = monster->GetClass(); + while (monster_class >>= 1) { + monster_class_index++; + } + alien_class_choice->SetSelection(monster_class_index); + + for (int i = 0; i < 16; ++i) { + alien_friends_checkboxes[i]->SetValue(monster->GetFriend(i)); + alien_enemies_checkboxes[i]->SetValue(monster->GetEnemy(i)); + } + + for (int i = 0; i < 27; ++i) { + alien_flags_checkboxes[i]->SetValue(monster->GetFlag(i + 1)); + } + + mainbox->Show(aliens_behavior_sizer, true); +} + +void PhysicsView::OnSelectAlienImmunities(int index) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(index); + + for (int i = 0; i < 24; ++i) { + alien_immunities_checkboxes[i]->SetValue(monster->GetImmunity(i)); + alien_weaknesses_checkboxes[i]->SetValue(monster->GetWeakness(i)); + } + + mainbox->Show(aliens_immunities_sizer, true); +} + +void PhysicsView::OnSelectEffect(int index) +{ + EffectDefinition* effect = static_cast(GetDocument())->GetEffectDefinition(index); + + eff_collection_field->ChangeValue(Format(effect->GetCollection())); + eff_color_table_field->ChangeValue(Format(effect->GetColorTable())); + eff_sequence_field->ChangeValue(Format(effect->GetShape())); + + eff_delay_field->ChangeValue(Format(effect->GetDelay())); + eff_pitch_field->ChangeValue(Format(effect->GetSoundPitch())); + + eff_delay_sound_choice->SetSelection(effect->GetDelaySound() + 1); + + eff_end_when_animation_loops_checkbox->SetValue(effect->GetEndWhenAnimationLoops()); + eff_end_when_transfer_animation_loops_checkbox->SetValue(effect->GetEndWhenTransferAnimationLoops()); + eff_sound_only_checkbox->SetValue(effect->GetSoundOnly()); + eff_media_effect_checkbox->SetValue(effect->GetMediaEffect()); + + mainbox->Show(effects_sizer, true); +} + +void PhysicsView::OnSelectShot(int index) +{ + ProjectileDefinition* projectile = static_cast(GetDocument())->GetProjectileDefinition(index); + + shots_collection_field->ChangeValue(Format(projectile->GetCollection())); + shots_color_table_field->ChangeValue(Format(projectile->GetColorTable())); + shots_sequence_field->ChangeValue(Format(projectile->GetShape())); + + DamageDefinition* damage = projectile->GetDamage(); + + shots_damage_type_choice->SetSelection(damage->GetType() + 1); + shots_damage_base_field->ChangeValue(Format(damage->GetBase())); + shots_damage_random_field->ChangeValue(Format(damage->GetRandom())); + shots_damage_scale_field->ChangeValue(Format(damage->GetScale())); + shots_alien_damage_checkbox->SetValue(damage->GetAlien()); + + shots_flyby_sound_choice->SetSelection(projectile->GetFlybySound() + 1); + shots_rebound_sound_choice->SetSelection(projectile->GetReboundSound() + 1); + shots_sound_pitch_field->ChangeValue(Format(projectile->GetSoundPitch())); + + shots_radius_field->ChangeValue(Format(projectile->GetRadius())); + shots_area_of_effect_field->ChangeValue(Format(projectile->GetAreaOfEffect())); + shots_speed_field->ChangeValue(Format(projectile->GetSpeed())); + shots_range_field->ChangeValue(Format(projectile->GetMaximumRange())); + + shots_detonation_effect_choice->SetSelection(projectile->GetDetonationEffect() + 1); + shots_media_detonation_effect_choice->SetSelection(projectile->GetMediaDetonationEffect() + 1); + shots_contrail_choice->SetSelection(projectile->GetContrailEffect() + 1); + shots_contrail_ticks_field->ChangeValue(Format(projectile->GetTicksBetweenContrails())); + shots_maximum_contrails_field->ChangeValue(Format(projectile->GetMaximumContrails())); + + for (int i = 0; i < 22; ++i) { + shots_flags_checkboxes[i]->SetValue(projectile->GetFlag(i)); + } + + shots_media_impact_choice->SetSelection(projectile->GetMediaProjectilePromotion() + 1); + + mainbox->Show(shots_sizer, true); +} + +void PhysicsView::OnSelectWeaponDefinition(int index) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(index); + + weapon_item_type_choice->SetSelection(weapon->GetItemType() + 1); + + weapon_collection_field->ChangeValue(Format(weapon->GetCollection())); + weapon_color_table_field->ChangeValue(Format(weapon->GetColorTable())); + weapon_idle_field->ChangeValue(Format(weapon->GetIdleShape())); + weapon_firing_field->ChangeValue(Format(weapon->GetFiringShape())); + weapon_reloading_field->ChangeValue(Format(weapon->GetReloadingShape())); + weapon_charging_field->ChangeValue(Format(weapon->GetChargingShape())); + weapon_charged_field->ChangeValue(Format(weapon->GetChargedShape())); + weapon_flash_intensity_field->ChangeValue(Format(weapon->GetFiringLightIntensity())); + + weapon_ready_field->ChangeValue(Format(weapon->GetReadyTicks())); + weapon_await_reload_field->ChangeValue(Format(weapon->GetAwaitReloadTicks())); + weapon_loading_field->ChangeValue(Format(weapon->GetLoadingTicks())); + weapon_finish_loading_field->ChangeValue(Format(weapon->GetFinishLoadingTicks())); + weapon_flash_decay_field->ChangeValue(Format(weapon->GetFiringIntensityDecayTicks())); + + weapon_class_choice->SetSelection(weapon->GetWeaponClass() + 1); + + weapon_idle_height_field->ChangeValue(Format(weapon->GetIdleHeight())); + weapon_bob_amplitude_field->ChangeValue(Format(weapon->GetBobAmplitude())); + weapon_kick_height_field->ChangeValue(Format(weapon->GetKickHeight())); + weapon_reload_height_field->ChangeValue(Format(weapon->GetReloadHeight())); + weapon_idle_width_field->ChangeValue(Format(weapon->GetIdleWidth())); + + for (int i = 0; i < 10; ++i) { + weapon_flags_checkboxes[i]->SetValue(weapon->GetFlag(i >= 5 ? i + 1 : i)); + } + + mainbox->Show(weapons_definitions_sizer, true); +} + +void PhysicsView::OnSelectWeaponTriggers(int index) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(index); + + for (int i = 0; i < 2; ++i) { + TriggerDefinition* trigger = (i == 0) ? weapon->GetPrimaryTrigger() : weapon->GetSecondaryTrigger(); + + trigger_projectile_choices[i]->SetSelection(trigger->GetProjectileType() + 1); + trigger_rounds_fields[i]->ChangeValue(Format(trigger->GetRoundsPerMagazine())); + trigger_ammo_type_choices[i]->SetSelection(trigger->GetAmmunitionType() + 1); + + trigger_firing_choices[i]->SetSelection(trigger->GetFiringSound() + 1); + trigger_click_choices[i]->SetSelection(trigger->GetClickSound() + 1); + trigger_charging_choices[i]->SetSelection(trigger->GetChargingSound() + 1); + trigger_shell_casing_choices[i]->SetSelection(trigger->GetShellCasingSound() + 1); + trigger_reloading_choices[i]->SetSelection(trigger->GetReloadingSound() + 1); + trigger_charged_choices[i]->SetSelection(trigger->GetChargedSound() + 1); + + trigger_ticks_fields[i]->ChangeValue(Format(trigger->GetTicksPerRound())); + trigger_recovery_fields[i]->ChangeValue(Format(trigger->GetRecoveryTicks())); + trigger_charging_fields[i]->ChangeValue(Format(trigger->GetChargingTicks())); + trigger_recoil_fields[i]->ChangeValue(Format(trigger->GetRecoilMagnitude())); + trigger_theta_fields[i]->ChangeValue(Format(trigger->GetThetaError())); + trigger_dx_fields[i]->ChangeValue(Format(trigger->GetDx())); + trigger_dz_fields[i]->ChangeValue(Format(trigger->GetDz())); + trigger_burst_count_fields[i]->ChangeValue(Format(trigger->GetBurstCount())); + + trigger_shell_casing_type_choices[i]->SetSelection(trigger->GetShellCasingType() + 1); + + } + + mainbox->Show(weapons_triggers_sizer, true); +} + +void PhysicsView::OnTreeSelect(wxTreeEvent& e) +{ + PhysicsTreeItemData* data = dynamic_cast(tree->GetItemData(e.GetItem())); + if (data) { + mainbox->Show(aliens_appearance_sizer, false); + mainbox->Show(aliens_behavior_sizer, false); + mainbox->Show(aliens_combat_sizer, false); + mainbox->Show(aliens_constants_sizer, false); + mainbox->Show(aliens_immunities_sizer, false); + mainbox->Show(dummy_sizer, false); + mainbox->Show(effects_sizer, false); + mainbox->Show(shots_sizer, false); + mainbox->Show(physics_sizer, false); + mainbox->Show(weapons_definitions_sizer, false); + mainbox->Show(weapons_triggers_sizer, false); + + int new_section = data->Section(); + switch (new_section) { + case TREESECTION_PHYSICS: + OnSelectPhysicsConstants(data->ID()); + break; + case TREESECTION_EFFECTS: + OnSelectEffect(data->ID()); + break; + case TREESECTION_PROJECTILES: + OnSelectShot(data->ID()); + break; + case TREESECTION_MONSTERS_APPEARANCE: + OnSelectAlienAppearance(data->ID()); + break; + case TREESECTION_MONSTERS_COMBAT: + OnSelectAlienCombat(data->ID()); + break; + case TREESECTION_MONSTERS_CONSTANTS: + OnSelectAlienConstants(data->ID()); + break; + case TREESECTION_MONSTERS_BEHAVIOR: + OnSelectAlienBehavior(data->ID()); + break; + case TREESECTION_MONSTERS_IMMUNITIES: + OnSelectAlienImmunities(data->ID()); + break; + case TREESECTION_WEAPONS_SETTINGS: + OnSelectWeaponDefinition(data->ID()); + break; + case TREESECTION_WEAPONS_TRIGGERS: + OnSelectWeaponTriggers(data->ID()); + break; + default: + mainbox->Show(dummy_sizer, true); + break; + } + + switch (new_section) { + case TREESECTION_MONSTERS: + case TREESECTION_EFFECTS: + case TREESECTION_PROJECTILES: + case TREESECTION_PHYSICS: + case TREESECTION_WEAPONS: + menubar->Enable(EDIT_MENU_COPY, true); + menubar->Enable(EDIT_MENU_PASTE, true); + break; + default: + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_PASTE, false); + break; + } + + mainbox->Layout(); + } +} + +short PhysicsView::GetSelection() { + return static_cast(tree->GetItemData(tree->GetSelection()))->ID(); +} + +template +inline unsigned char* Serialize(T* element, size_t& size) +{ + size = T::kSize; + unsigned char* data = new unsigned char[size]; + BigEndianBuffer buffer(data, size); + element->SaveObject(buffer); + return data; +} + +void PhysicsView::MenuEditCopy(wxCommandEvent&) { + if (wxTheClipboard->Open()) { + + PhysicsTreeItemData* data = static_cast(tree->GetItemData(tree->GetSelection())); + PhysicsDocument* document = static_cast(GetDocument()); + + if (data) { + size_t size = 0; + unsigned char* buf = 0; + wxDataFormat format; + + switch (data->Section()) { + case TREESECTION_MONSTERS: + buf = Serialize(document->GetMonsterDefinition(data->ID()), size); + format.SetId(wxT("application/vnd.shapefusion.monster")); + break; + case TREESECTION_EFFECTS: + buf = Serialize(document->GetEffectDefinition(data->ID()), size); + format.SetId(wxT("application/vnd.shapefusion.effect")); + break; + case TREESECTION_PROJECTILES: + buf = Serialize(document->GetProjectileDefinition(data->ID()), size); + format.SetId(wxT("application/vnd.shapefusion.projectile")); + break; + case TREESECTION_PHYSICS: + buf = Serialize(document->GetPhysicsConstants(data->ID()), size); + format.SetId(wxT("application/vnd.shapefusion.physics")); + break; + case TREESECTION_WEAPONS: + buf = Serialize(document->GetWeaponDefinition(data->ID()), size); + format.SetId(wxT("application/vnd.shapefusion.weapon")); + break; + } + + wxCustomDataObject* dataObject = new wxCustomDataObject(format); + dataObject->TakeData(size, buf); + wxTheClipboard->SetData(dataObject); + + wxTheClipboard->Close(); + } + } +} + +void PhysicsView::MenuEditPaste(wxCommandEvent&) { + if (wxTheClipboard->Open()) { + PhysicsTreeItemData* data = static_cast(tree->GetItemData(tree->GetSelection())); + PhysicsDocument* document = static_cast(GetDocument()); + + if (data) { + wxDataFormat format; + + switch (data->Section()) { + case TREESECTION_MONSTERS: + format.SetId(wxT("application/vnd.shapefusion.monster")); + break; + case TREESECTION_EFFECTS: + format.SetId(wxT("application/vnd.shapefusion.effect")); + break; + case TREESECTION_PROJECTILES: + format.SetId(wxT("application/vnd.shapefusion.projectile")); + break; + case TREESECTION_PHYSICS: + format.SetId(wxT("application/vnd.shapefusion.physics")); + break; + case TREESECTION_WEAPONS: + format.SetId(wxT("application/vnd.shapefusion.weapon")); + break; + + } + + wxCustomDataObject dataObject(format); + if (wxTheClipboard->GetData(dataObject)) { + BigEndianBuffer buffer(reinterpret_cast(dataObject.GetData()), dataObject.GetSize()); + + switch (data->Section()) { + case TREESECTION_MONSTERS: + document->GetMonsterDefinition(data->ID())->LoadObject(buffer); + break; + case TREESECTION_EFFECTS: + document->GetEffectDefinition(data->ID())->LoadObject(buffer); + OnSelectEffect(data->ID()); + break; + case TREESECTION_PROJECTILES: + document->GetProjectileDefinition(data->ID())->LoadObject(buffer); + OnSelectShot(data->ID()); + break; + case TREESECTION_PHYSICS: + document->GetPhysicsConstants(data->ID())->LoadObject(buffer); + OnSelectPhysicsConstants(data->ID()); + break; + case TREESECTION_WEAPONS: + document->GetWeaponDefinition(data->ID())->LoadObject(buffer); + break; + } + + document->Modify(true); + } + } + + wxTheClipboard->Close(); + } +} + +void PhysicsView::EditAlienCheckboxes(wxCommandEvent& e) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(GetSelection()); + + int id = e.GetId(); + + if (id == CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE) { + monster->GetShrapnelDamage()->SetAlien(e.IsChecked()); + } else if (id >= CB_ALIEN_FRIENDS && id < CB_ALIEN_ENEMIES) { + monster->SetFriend(id - CB_ALIEN_FRIENDS, e.IsChecked()); + } else if (id >= CB_ALIEN_ENEMIES && id < CB_ALIEN_FLAGS) { + monster->SetEnemy(id - CB_ALIEN_ENEMIES, e.IsChecked()); + } else if (id >= CB_ALIEN_FLAGS && id < CB_ALIEN_IMMUNITIES) { + monster->SetFlag(id - CB_ALIEN_FLAGS + 1, e.IsChecked()); + } else if (id >= CB_ALIEN_IMMUNITIES && id < CB_ALIEN_WEAKNESSES) { + monster->SetImmunity(id - CB_ALIEN_IMMUNITIES, e.IsChecked()); + } else if (id >= CB_ALIEN_WEAKNESSES && id <= CB_ALIEN_WEAKNESSES + 24) { + monster->SetWeakness(id - CB_ALIEN_WEAKNESSES, e.IsChecked()); + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditAlienDoubles(wxCommandEvent& e) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(GetSelection()); + + double d = 0.0; + if (e.GetString().ToDouble(&d)) { + switch (e.GetId()) { + case FIELD_ALIEN_SOUND_PITCH: + monster->SetSoundPitch(d); + break; + case FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE: + monster->GetShrapnelDamage()->SetScale(d); + break; + case FIELD_ALIEN_EXT_VELOCITY_SCALE: + monster->SetExternalVelocityScale(d); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditAlienFields(wxCommandEvent& e) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(GetSelection()); + + long v = 0; + if (e.GetString().ToLong(&v)) { + int id = e.GetId(); + AttackDefinition* attack = monster->GetMeleeAttack(); + + if (id >= MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS && id <= FIELD_ALIEN_ATTACK_DZ + NUM_ALIEN_ATTACK_CONTROLS) + { + id -= NUM_ALIEN_ATTACK_CONTROLS; + attack = monster->GetRangedAttack(); + } + + switch (id) { + case FIELD_ALIEN_COLLECTION: + if (v == -1) { + monster->SetCollection(31); + monster->SetColorTable(7); + alien_collection_field->ChangeValue(wxT("31")); + alien_color_table_field->ChangeValue(wxT("7")); + } else { + monster->SetCollection(v); + } + break; + case FIELD_ALIEN_COLOR_TABLE: + if (v == -1) { + monster->SetCollection(31); + monster->SetColorTable(7); + alien_collection_field->ChangeValue(wxT("31")); + alien_color_table_field->ChangeValue(wxT("7")); + } else { + monster->SetColorTable(v); + } + break; + case FIELD_ALIEN_HIT: + monster->SetHitShapes(v); + break; + case FIELD_ALIEN_HARD_DYING: + monster->SetHardDyingShape(v); + break; + case FIELD_ALIEN_SOFT_DYING: + monster->SetSoftDyingShape(v); + break; + case FIELD_ALIEN_HARD_DEAD: + monster->SetHardDeadShapes(v); + break; + case FIELD_ALIEN_SOFT_DEAD: + monster->SetSoftDeadShapes(v); + break; + case FIELD_ALIEN_STATIONARY: + monster->SetStationaryShape(v); + break; + case FIELD_ALIEN_MOVING: + monster->SetMovingShape(v); + break; + case FIELD_ALIEN_TELEPORT_IN: + monster->SetTeleportInShape(v); + break; + case FIELD_ALIEN_TELEPORT_OUT: + monster->SetTeleportOutShape(v); + break; + case FIELD_ALIEN_MELEE_ATTACK_SHAPE: + monster->GetMeleeAttack()->SetShape(v); + break; + case FIELD_ALIEN_RANGED_ATTACK_SHAPE: + monster->GetRangedAttack()->SetShape(v); + break; + case FIELD_ALIEN_RANDOM_SOUND_MASK: + monster->SetRandomSoundMask(v); + break; + case FIELD_ALIEN_ATTACK_FREQUENCY: + monster->SetAttackFrequency(v); + break; + case FIELD_ALIEN_ATTACK_REPETITIONS: + attack->SetRepetitions(v); + break; + case FIELD_ALIEN_ATTACK_ERROR: + attack->SetError(v / 512.0 * 360.0); + break; + case FIELD_ALIEN_ATTACK_RANGE: + attack->SetRange(v); + break; + case FIELD_ALIEN_ATTACK_SEQUENCE: + attack->SetShape(v); + break; + case FIELD_ALIEN_ATTACK_DX: + attack->SetDx(v); + break; + case FIELD_ALIEN_ATTACK_DY: + attack->SetDy(v); + break; + case FIELD_ALIEN_ATTACK_DZ: + attack->SetDz(v); + break; + case FIELD_ALIEN_SHRAPNEL_RADIUS: + monster->SetShrapnelRadius(v); + break; + case FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE: + monster->GetShrapnelDamage()->SetBase(v); + break; + case FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE: + monster->GetShrapnelDamage()->SetRandom(v); + break; + case FIELD_ALIEN_VITALITY: + monster->SetVitality(v); + break; + case FIELD_ALIEN_RADIUS: + monster->SetRadius(v); + break; + case FIELD_ALIEN_HEIGHT: + monster->SetHeight(v); + break; + case FIELD_ALIEN_SPEED: + monster->SetSpeed(v); + break; + case FIELD_ALIEN_TERMINAL_VELOCITY: + monster->SetTerminalVelocity(v); + break; + case FIELD_ALIEN_GRAVITY: + monster->SetGravity(v); + break; + case FIELD_ALIEN_MIN_LEDGE_JUMP: + monster->SetMinimumLedgeDelta(v); + break; + case FIELD_ALIEN_MAX_LEDGE_JUMP: + monster->SetMaximumLedgeDelta(v); + break; + case FIELD_ALIEN_HOVER_HEIGHT: + monster->SetPreferredHoverHeight(v); + break; + case FIELD_ALIEN_DOOR_RETRY_MASK: + monster->SetDoorRetryMask(v); + break; + case FIELD_ALIEN_VISUAL_RANGE: + monster->SetVisualRange(v); + break; + case FIELD_ALIEN_DARK_VISUAL_RANGE: + monster->SetDarkVisualRange(v); + break; + case FIELD_ALIEN_INTELLIGENCE: + monster->SetIntelligence(v); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditAlienMenus(wxCommandEvent& e) +{ + MonsterDefinition* monster = static_cast(GetDocument())->GetMonsterDefinition(GetSelection()); + + switch (e.GetId()) { + case MENU_ALIEN_ACTIVATION: + monster->SetActivationSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_FRIENDLY_ACTIVATION: + monster->SetFriendlyActivationSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_CLEAR: + monster->SetClearSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_KILL: + monster->SetKillSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_APOLOGY: + monster->SetApologySound(e.GetSelection() - 1); + break; + case MENU_ALIEN_FRIENDLY_FIRE: + monster->SetFriendlyFireSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_FLAMING: + monster->SetFlamingSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_RANDOM: + monster->SetRandomSound(e.GetSelection() - 1); + break; + case MENU_ALIEN_ATTACK_TYPE: + monster->GetMeleeAttack()->SetType(e.GetSelection() - 1); + break; + case MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS: + monster->GetRangedAttack()->SetType(e.GetSelection() - 1); + break; + case MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE: + monster->GetShrapnelDamage()->SetType(e.GetSelection() - 1); + break; + case MENU_ALIEN_RANGED_IMPACT_EFFECT: + monster->SetImpactEffect(e.GetSelection() - 1); + break; + case MENU_ALIEN_MELEE_IMPACT_EFFECT: + monster->SetMeleeImpactEffect(e.GetSelection() - 1); + break; + case MENU_ALIEN_CARRYING_ITEM: + monster->SetCarryingItemType(e.GetSelection() - 1); + break; + case MENU_ALIEN_CONTRAIL_EFFECT: + monster->SetContrailEffect(e.GetSelection() - 1); + break; + case MENU_ALIEN_CLASS: + monster->SetClass(1 << e.GetSelection()); + break; + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditEffectCheckboxes(wxCommandEvent& e) +{ + EffectDefinition* effect = static_cast(GetDocument())->GetEffectDefinition(GetSelection()); + + switch (e.GetId()) { + case CB_EFFECT_END_WHEN_ANIMATION_LOOPS: + effect->SetEndWhenAnimationLoops(e.IsChecked()); + break; + case CB_EFFECT_END_WHEN_TRANSFER_ANIMATION_LOOPS: + effect->SetEndWhenTransferAnimationLoops(e.IsChecked()); + break; + case CB_EFFECT_SOUND_ONLY: + effect->SetSoundOnly(e.IsChecked()); + break; + case CB_EFFECT_MEDIA_EFFECT: + effect->SetMediaEffect(e.IsChecked()); + break; + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditEffectDoubles(wxCommandEvent& e) +{ + EffectDefinition* effect = static_cast(GetDocument())->GetEffectDefinition(GetSelection()); + + double d = 0.0; + if (e.GetString().ToDouble(&d)) { + switch (e.GetId()) { + case FIELD_EFFECT_PITCH: + effect->SetSoundPitch(d); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditEffectFields(wxCommandEvent& e) +{ + EffectDefinition* effect = static_cast(GetDocument())->GetEffectDefinition(GetSelection()); + + long v = 0; + if (e.GetString().ToLong(&v)) { + switch (e.GetId()) { + case FIELD_EFFECT_COLLECTION: + if (v == -1) { + effect->SetCollection(31); + effect->SetColorTable(7); + eff_collection_field->ChangeValue(wxT("31")); + eff_color_table_field->ChangeValue(wxT("7")); + } else { + effect->SetCollection(v); + } + break; + case FIELD_EFFECT_COLOR_TABLE: + if (v == -1) { + effect->SetCollection(31); + effect->SetColorTable(7); + eff_collection_field->ChangeValue(wxT("31")); + eff_color_table_field->ChangeValue(wxT("7")); + } else { + effect->SetColorTable(v); + } + break; + case FIELD_EFFECT_SEQUENCE: + effect->SetShape(v); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditEffectMenus(wxCommandEvent& e) +{ + EffectDefinition* effect = static_cast(GetDocument())->GetEffectDefinition(GetSelection()); + + switch (e.GetId()) { + case MENU_EFFECT_DELAY_SOUND: + effect->SetDelaySound(e.GetSelection() - 1); + break; + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditShotCheckboxes(wxCommandEvent& e) +{ + ProjectileDefinition* projectile = static_cast(GetDocument())->GetProjectileDefinition(GetSelection()); + + if (e.GetId() == CB_SHOT_ALIEN_DAMAGE) { + projectile->GetDamage()->SetAlien(e.IsChecked()); + } else if (e.GetId() >= CB_SHOT_FLAGS && e.GetId() < CB_SHOT_FLAGS + 22) { + projectile->SetFlag(e.GetId() - CB_SHOT_FLAGS, e.IsChecked()); + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditShotFields(wxCommandEvent& e) +{ + ProjectileDefinition* projectile = static_cast(GetDocument())->GetProjectileDefinition(GetSelection()); + + long v = 0; + if (e.GetString().ToLong(&v)) { + switch (e.GetId()) { + case FIELD_SHOT_COLLECTION: + if (v == -1) { + projectile->SetCollection(31); + projectile->SetColorTable(7); + shots_collection_field->ChangeValue(wxT("31")); + shots_color_table_field->ChangeValue(wxT("7")); + } else { + projectile->SetCollection(v); + } + break; + case FIELD_SHOT_COLOR_TABLE: + if (v == -1) { + projectile->SetCollection(31); + projectile->SetColorTable(7); + shots_collection_field->ChangeValue(wxT("31")); + shots_color_table_field->ChangeValue(wxT("7")); + } else { + projectile->SetColorTable(v); + } + break; + case FIELD_SHOT_SEQUENCE: + projectile->SetShape(v); + break; + case FIELD_SHOT_DAMAGE_BASE: + projectile->GetDamage()->SetBase(v); + break; + case FIELD_SHOT_DAMAGE_RANDOM: + projectile->GetDamage()->SetRandom(v); + break; + case FIELD_SHOT_RADIUS: + projectile->SetRadius(v); + break; + case FIELD_SHOT_AREA_OF_EFFECT: + projectile->SetAreaOfEffect(v); + break; + case FIELD_SHOT_SPEED: + projectile->SetSpeed(v); + break; + case FIELD_SHOT_RANGE: + projectile->SetMaximumRange(v); + break; + case FIELD_SHOT_CONTRAIL_TICKS: + projectile->SetTicksBetweenContrails(v); + break; + case FIELD_SHOT_MAXIMUM_CONTRAILS: + projectile->SetMaximumContrails(v); + break; + } + } + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditShotDoubles(wxCommandEvent& e) +{ + ProjectileDefinition* projectile = static_cast(GetDocument())->GetProjectileDefinition(GetSelection()); + + double d = 0.0; + + if (e.GetString().ToDouble(&d)) { + switch (e.GetId()) { + case FIELD_SHOT_DAMAGE_SCALE: + projectile->GetDamage()->SetScale(d); + break; + case FIELD_SHOT_SOUND_PITCH: + projectile->SetSoundPitch(d); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditShotMenus(wxCommandEvent& e) +{ + ProjectileDefinition* projectile = static_cast(GetDocument())->GetProjectileDefinition(GetSelection()); + + switch (e.GetId()) { + case MENU_SHOT_DAMAGE_TYPE: + projectile->GetDamage()->SetType(e.GetSelection() - 1); + break; + case MENU_SHOT_FLYBY_SOUND: + projectile->SetFlybySound(e.GetSelection() - 1); + break; + case MENU_SHOT_REBOUND_SOUND: + projectile->SetReboundSound(e.GetSelection() - 1); + break; + case MENU_SHOT_DETONATION_EFFECT: + projectile->SetDetonationEffect(e.GetSelection() - 1); + break; + case MENU_SHOT_MEDIA_DETONATION_EFFECT: + projectile->SetMediaDetonationEffect(e.GetSelection() - 1); + break; + case MENU_SHOT_CONTRAIL: + projectile->SetContrailEffect(e.GetSelection() - 1); + break; + case MENU_SHOT_MEDIA_IMPACT: + projectile->SetMediaProjectilePromotion(e.GetSelection() - 1); + break; + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditPhysicsConstants(wxCommandEvent& e) +{ + PhysicsConstants* constants = static_cast(GetDocument())->GetPhysicsConstants(GetSelection()); + + double d = 0.0; + if (e.GetString().ToDouble(&d)) { + switch (e.GetId()) { + case FIELD_MAX_FORWARD_VELOCITY: + constants->SetMaximumForwardVelocity(d); + break; + case FIELD_MAX_BACKWARD_VELOCITY: + constants->SetMaximumBackwardVelocity(d); + break; + case FIELD_MAX_PERPENDICULAR_VELOCITY: + constants->SetMaximumPerpendicularVelocity(d); + break; + + case FIELD_ACCELERATION: + constants->SetAcceleration(d); + break; + case FIELD_DECELERATION: + constants->SetDeceleration(d); + break; + case FIELD_AIRBORNE_DECELERATION: + constants->SetAirborneDeceleration(d); + break; + case FIELD_GRAVITATIONAL_ACCELERATION: + constants->SetGravitationalAcceleration(d); + break; + case FIELD_CLIMBING_ACCELERATION: + constants->SetClimbingAcceleration(d); + break; + case FIELD_TERMINAL_VELOCITY: + constants->SetTerminalVelocity(d); + break; + case FIELD_EXTERNAL_DECELERATION: + constants->SetExternalDeceleration(d); + break; + + case FIELD_STEP_DELTA: + constants->SetStepDelta(d); + break; + case FIELD_STEP_AMPLITUDE: + constants->SetStepAmplitude(d); + break; + + case FIELD_RADIUS: + constants->SetRadius(d); + break; + case FIELD_HEIGHT: + constants->SetHeight(d); + break; + + case FIELD_ANGULAR_ACCELERATION: + constants->SetAngularAcceleration(d); + break; + case FIELD_ANGULAR_DECELERATION: + constants->SetAngularDeceleration(d); + break; + case FIELD_MAXIMUM_ANGULAR_VELOCITY: + constants->SetMaximumAngularVelocity(d); + break; + case FIELD_ANGULAR_RECENTERING_VELOCITY: + constants->SetAngularRecenteringVelocity(d); + break; + case FIELD_HEAD_ANGULAR_VELOCITY: + constants->SetFastAngularVelocity(d); + break; + case FIELD_HEAD_ANGULAR_MAXIMUM: + constants->SetFastAngularMaximum(d); + break; + case FIELD_MAXIMUM_ELEVATION: + constants->SetMaximumElevation(d); + break; + case FIELD_EXTERNAL_ANGULAR_DECELERATION: + constants->SetExternalAngularDeceleration(d); + break; + + case FIELD_DEAD_HEIGHT: + constants->SetDeadHeight(d); + break; + case FIELD_CAMERA_HEIGHT: + constants->SetCameraHeight(d); + break; + case FIELD_SPLASH_HEIGHT: + constants->SetSplashHeight(d); + break; + case FIELD_HALF_CAMERA_SEPARATION: + constants->SetHalfCameraSeparation(d); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditWeaponCheckboxes(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + int flag = e.GetId() - CB_WEAPON_FLAGS; + + weapon->SetFlag(flag >= 5 ? flag + 1: flag, e.IsChecked()); + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditWeaponFields(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + long v = 0; + if (e.GetString().ToLong(&v)) { + switch (e.GetId()) { + case FIELD_WEAPON_COLLECTION: + if (v == -1) { + weapon->SetCollection(31); + weapon->SetColorTable(7); + weapon_collection_field->ChangeValue(wxT("31")); + weapon_color_table_field->ChangeValue(wxT("7")); + } else { + weapon->SetCollection(v); + } + break; + case FIELD_WEAPON_COLOR_TABLE: + if (v == -1) { + weapon->SetCollection(31); + weapon->SetColorTable(7); + weapon_collection_field->ChangeValue(wxT("31")); + weapon_color_table_field->ChangeValue(wxT("7")); + } else { + weapon->SetColorTable(v); + } + break; + case FIELD_WEAPON_IDLE: + weapon->SetIdleShape(v); + break; + case FIELD_WEAPON_FIRING: + weapon->SetFiringShape(v); + break; + case FIELD_WEAPON_RELOADING: + weapon->SetReloadingShape(v); + break; + case FIELD_WEAPON_CHARGING: + weapon->SetChargingShape(v); + break; + case FIELD_WEAPON_CHARGED: + weapon->SetChargedShape(v); + break; + case FIELD_WEAPON_READY: + weapon->SetReadyTicks(v); + break; + case FIELD_WEAPON_AWAIT_RELOAD: + weapon->SetAwaitReloadTicks(v); + break; + case FIELD_WEAPON_LOADING: + weapon->SetLoadingTicks(v); + break; + case FIELD_WEAPON_FINISH_LOADING: + weapon->SetFinishLoadingTicks(v); + break; + case FIELD_WEAPON_FLASH_DECAY: + weapon->SetFiringIntensityDecayTicks(v); + break; + } + } + + static_cast(GetDocument())->Modify(true); + +} + +void PhysicsView::EditWeaponDoubles(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + double d = 0.0; + if (e.GetString().ToDouble(&d)) { + switch (e.GetId()) { + case FIELD_WEAPON_FLASH_INTENSITY: + weapon->SetFiringLightIntensity(d); + break; + case FIELD_WEAPON_IDLE_HEIGHT: + weapon->SetIdleHeight(d); + break; + case FIELD_WEAPON_BOB_AMPLITUDE: + weapon->SetBobAmplitude(d); + break; + case FIELD_WEAPON_KICK_HEIGHT: + weapon->SetKickHeight(d); + break; + case FIELD_WEAPON_RELOAD_HEIGHT: + weapon->SetReloadHeight(d); + break; + case FIELD_WEAPON_IDLE_WIDTH: + weapon->SetIdleWidth(d); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditWeaponMenus(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + switch (e.GetId()) { + case MENU_WEAPON_ITEM_TYPE: + weapon->SetItemType(e.GetSelection() - 1); + break; + case MENU_WEAPON_CLASS: + weapon->SetWeaponClass(e.GetSelection() - 1); + break; + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditTriggerFields(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + long v = 0; + if (e.GetString().ToLong(&v)) { + int id = e.GetId(); + TriggerDefinition* trigger = weapon->GetPrimaryTrigger(); + + if (id >= FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS) { + id -= NUM_TRIGGER_IDS; + trigger = weapon->GetSecondaryTrigger(); + } + + switch (id) { + case FIELD_TRIGGER_ROUNDS: + trigger->SetRoundsPerMagazine(v); + break; + case FIELD_TRIGGER_TICKS: + trigger->SetTicksPerRound(v); + break; + case FIELD_TRIGGER_RECOVERY: + trigger->SetRecoveryTicks(v); + break; + case FIELD_TRIGGER_CHARGING: + trigger->SetChargingTicks(v); + break; + case FIELD_TRIGGER_RECOIL: + trigger->SetRecoilMagnitude(v); + break; + case FIELD_TRIGGER_THETA: + trigger->SetThetaError(v); + break; + case FIELD_TRIGGER_DX: + trigger->SetDx(v); + break; + case FIELD_TRIGGER_DZ: + trigger->SetDz(v); + break; + case FIELD_TRIGGER_BURST_COUNT: + trigger->SetBurstCount(v); + break; + } + } + + static_cast(GetDocument())->Modify(true); +} + +void PhysicsView::EditTriggerMenus(wxCommandEvent& e) +{ + WeaponDefinition* weapon = static_cast(GetDocument())->GetWeaponDefinition(GetSelection()); + + int id = e.GetId(); + TriggerDefinition* trigger = weapon->GetPrimaryTrigger(); + + if (id >= FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS) { + id -= NUM_TRIGGER_IDS; + trigger = weapon->GetSecondaryTrigger(); + } + + switch (id) { + case MENU_TRIGGER_PROJECTILE: + trigger->SetProjectileType(e.GetSelection() - 1); + break; + case MENU_TRIGGER_AMMO_TYPE: + trigger->SetAmmunitionType(e.GetSelection() - 1); + break; + case MENU_TRIGGER_FIRING: + trigger->SetFiringSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_CLICK: + trigger->SetClickSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_CHARGING: + trigger->SetChargingSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_SHELL_CASING: + trigger->SetShellCasingSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_RELOADING: + trigger->SetReloadingSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_CHARGED: + trigger->SetChargedSound(e.GetSelection() - 1); + break; + case MENU_TRIGGER_SHELL_CASING_TYPE: + trigger->SetShellCasingType(e.GetSelection() - 1); + break; + } + + static_cast(GetDocument())->Modify(true); +} diff --git a/Physics/PhysicsElements.cpp b/Physics/PhysicsElements.cpp new file mode 100644 index 0000000..a8bf766 --- /dev/null +++ b/Physics/PhysicsElements.cpp @@ -0,0 +1,791 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include + +#include "PhysicsElements.h" + +BigEndianBuffer& PhysicsConstants::LoadObject(BigEndianBuffer& buffer) +{ + // everything is a 16.16 fixed, for whatever reason + mMaximumForwardVelocity = buffer.ReadFixed(); + mMaximumBackwardVelocity = buffer.ReadFixed(); + mMaximumPerpendicularVelocity= buffer.ReadFixed(); + + mAcceleration = buffer.ReadFixed(); + mDeceleration = buffer.ReadFixed(); + mAirborneDeceleration = buffer.ReadFixed(); + + mGravitationalAcceleration = buffer.ReadFixed(); + mClimbingAcceleration = buffer.ReadFixed(); + mTerminalVelocity = buffer.ReadFixed(); + + mExternalDeceleration = buffer.ReadFixed(); + + mAngularAcceleration = buffer.ReadFixed(); + mAngularDeceleration = buffer.ReadFixed(); + mMaximumAngularVelocity = buffer.ReadFixed(); + mAngularRecenteringVelocity = buffer.ReadFixed(); + + mFastAngularVelocity = buffer.ReadFixed(); + mFastAngularMaximum = buffer.ReadFixed(); + + mMaximumElevation = buffer.ReadFixed(); + mExternalAngularDeceleration = buffer.ReadFixed(); + + mStepDelta = buffer.ReadFixed(); + mStepAmplitude = buffer.ReadFixed(); + + mRadius = buffer.ReadFixed(); + mHeight = buffer.ReadFixed(); + mDeadHeight = buffer.ReadFixed(); + mCameraHeight = buffer.ReadFixed(); + mSplashHeight = buffer.ReadFixed(); + + mHalfCameraSeparation = buffer.ReadFixed(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& PhysicsConstants::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteFixed(mMaximumForwardVelocity); + buffer.WriteFixed(mMaximumBackwardVelocity); + buffer.WriteFixed(mMaximumPerpendicularVelocity); + + buffer.WriteFixed(mAcceleration); + buffer.WriteFixed(mDeceleration); + buffer.WriteFixed(mAirborneDeceleration); + + buffer.WriteFixed(mGravitationalAcceleration); + buffer.WriteFixed(mClimbingAcceleration); + buffer.WriteFixed(mTerminalVelocity); + + buffer.WriteFixed(mExternalDeceleration); + + buffer.WriteFixed(mAngularAcceleration); + buffer.WriteFixed(mAngularDeceleration); + buffer.WriteFixed(mMaximumAngularVelocity); + buffer.WriteFixed(mAngularRecenteringVelocity); + + buffer.WriteFixed(mFastAngularVelocity); + buffer.WriteFixed(mFastAngularMaximum); + + buffer.WriteFixed(mMaximumElevation); + buffer.WriteFixed(mExternalAngularDeceleration); + + buffer.WriteFixed(mStepDelta); + buffer.WriteFixed(mStepAmplitude); + + buffer.WriteFixed(mRadius); + buffer.WriteFixed(mHeight); + buffer.WriteFixed(mDeadHeight); + buffer.WriteFixed(mCameraHeight); + buffer.WriteFixed(mSplashHeight); + + buffer.WriteFixed(mHalfCameraSeparation); + + return buffer; +} + +BigEndianBuffer& AttackDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mType = buffer.ReadShort(); + mRepetitions = buffer.ReadShort(); + mError = buffer.ReadShort() * 360.0 / 512.0; + mRange = buffer.ReadShort(); + mAttackShape = buffer.ReadShort(); + + mDx = buffer.ReadShort(); + mDy = buffer.ReadShort(); + mDz = buffer.ReadShort(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& AttackDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteShort(mType); + buffer.WriteShort(mRepetitions); + buffer.WriteShort(std::floor(mError * 512.0 / 360.0 + 0.5)); + buffer.WriteShort(mRange); + buffer.WriteShort(mAttackShape); + + buffer.WriteShort(mDx); + buffer.WriteShort(mDy); + buffer.WriteShort(mDz); + + return buffer; +} + +BigEndianBuffer& DamageDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mType = buffer.ReadShort(); + mFlags = buffer.ReadShort(); + + mBase = buffer.ReadShort(); + mRandom = buffer.ReadShort(); + + mScale = buffer.ReadFixed(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& DamageDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteShort(mType); + buffer.WriteShort(mFlags); + + buffer.WriteShort(mBase); + buffer.WriteShort(mRandom); + + buffer.WriteFixed(mScale); + + return buffer; +} + +static unsigned short BuildCollection(unsigned short collection, unsigned short colorTable) +{ + if (collection == 31 && colorTable == 7) { + return 0xffff; + } else { + return collection | (colorTable << 5); + } +} + +BigEndianBuffer& EffectDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mCollection = buffer.ReadUShort(); + mColorTable = (mCollection >> 5) & 0x7; + mCollection &= 0x1f; + mShape = buffer.ReadShort(); + mSoundPitch = buffer.ReadFixed(); + mFlags = buffer.ReadUShort(); + mDelay = buffer.ReadShort(); + mDelaySound = buffer.ReadShort(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& EffectDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteUShort(BuildCollection(mCollection, mColorTable)); + buffer.WriteShort(mShape); + buffer.WriteFixed(mSoundPitch); + buffer.WriteUShort(mFlags); + buffer.WriteShort(mDelay); + buffer.WriteShort(mDelaySound); + + return buffer; +} + +BigEndianBuffer& MonsterDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mCollection = buffer.ReadUShort(); + mColorTable = (mCollection >> 5) & 0x7; + mCollection &= 0x1f; + + mVitality = buffer.ReadShort(); + mImmunities = buffer.ReadULong(); + mWeaknesses = buffer.ReadULong(); + mFlags = buffer.ReadULong(); + + mClass = buffer.ReadLong(); + mFriends = buffer.ReadLong(); + mEnemies = buffer.ReadLong(); + + mSoundPitch = buffer.ReadFixed(); + + mActivationSound = buffer.ReadShort(); + mFriendlyActivationSound = buffer.ReadShort(); + mClearSound = buffer.ReadShort(); + mKillSound = buffer.ReadShort(); + mApologySound = buffer.ReadShort(); + mFriendlyFireSound = buffer.ReadShort(); + mFlamingSound = buffer.ReadShort(); + mRandomSound = buffer.ReadShort(); + mRandomSoundMask = buffer.ReadShort(); + + mCarryingItemType = buffer.ReadShort(); + + mRadius = buffer.ReadShort(); + mHeight = buffer.ReadShort(); + mPreferredHoverHeight = buffer.ReadShort(); + mMinimumLedgeDelta = buffer.ReadShort(); + mMaximumLedgeDelta = buffer.ReadShort(); + mExternalVelocityScale = buffer.ReadFixed(); + mImpactEffect = buffer.ReadShort(); + mMeleeImpactEffect = buffer.ReadShort(); + mContrailEffect = buffer.ReadShort(); + + mHalfVisualArc = buffer.ReadShort(); + mHalfVerticalVisualArc = buffer.ReadShort(); + mVisualRange = buffer.ReadShort(); + mDarkVisualRange = buffer.ReadShort(); + mIntelligence = buffer.ReadShort(); + mSpeed = buffer.ReadShort(); + mGravity = buffer.ReadShort(); + mTerminalVelocity = buffer.ReadShort(); + mDoorRetryMask = buffer.ReadShort(); + mShrapnelRadius = buffer.ReadShort(); + + mShrapnelDamage.LoadObject(buffer); + if (!mShrapnelDamage.IsGood()) { + return buffer; + } + + mHitShapes = buffer.ReadShort(); + mHardDyingShape = buffer.ReadShort(); + mSoftDyingShape = buffer.ReadShort(); + mHardDeadShapes = buffer.ReadShort(); + mSoftDeadShapes = buffer.ReadShort(); + mStationaryShape = buffer.ReadShort(); + mMovingShape = buffer.ReadShort(); + mTeleportInShape = buffer.ReadShort(); + mTeleportOutShape = buffer.ReadShort(); + + mAttackFrequency = buffer.ReadShort(); + mMeleeAttack.LoadObject(buffer); + if (!mMeleeAttack.IsGood()) { + return buffer; + } + + mRangedAttack.LoadObject(buffer); + if (!mRangedAttack.IsGood()) { + return buffer; + } + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& MonsterDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteUShort(BuildCollection(mCollection, mColorTable)); + + buffer.WriteShort(mVitality); + buffer.WriteULong(mImmunities); + buffer.WriteULong(mWeaknesses); + buffer.WriteULong(mFlags); + + buffer.WriteLong(mClass); + buffer.WriteLong(mFriends); + buffer.WriteLong(mEnemies); + + buffer.WriteFixed(mSoundPitch); + + buffer.WriteShort(mActivationSound); + buffer.WriteShort(mFriendlyActivationSound); + buffer.WriteShort(mClearSound); + buffer.WriteShort(mKillSound); + buffer.WriteShort(mApologySound); + buffer.WriteShort(mFriendlyFireSound); + buffer.WriteShort(mFlamingSound); + buffer.WriteShort(mRandomSound); + buffer.WriteShort(mRandomSoundMask); + + buffer.WriteShort(mCarryingItemType); + + buffer.WriteShort(mRadius); + buffer.WriteShort(mHeight); + buffer.WriteShort(mPreferredHoverHeight); + buffer.WriteShort(mMinimumLedgeDelta); + buffer.WriteShort(mMaximumLedgeDelta); + buffer.WriteFixed(mExternalVelocityScale); + buffer.WriteShort(mImpactEffect); + buffer.WriteShort(mMeleeImpactEffect); + buffer.WriteShort(mContrailEffect); + + buffer.WriteShort(mHalfVisualArc); + buffer.WriteShort(mHalfVerticalVisualArc); + buffer.WriteShort(mVisualRange); + buffer.WriteShort(mDarkVisualRange); + buffer.WriteShort(mIntelligence); + buffer.WriteShort(mSpeed); + buffer.WriteShort(mGravity); + buffer.WriteShort(mTerminalVelocity); + buffer.WriteShort(mDoorRetryMask); + buffer.WriteShort(mShrapnelRadius); + + mShrapnelDamage.SaveObject(buffer); + + buffer.WriteShort(mHitShapes); + buffer.WriteShort(mHardDyingShape); + buffer.WriteShort(mSoftDyingShape); + buffer.WriteShort(mHardDeadShapes); + buffer.WriteShort(mSoftDeadShapes); + buffer.WriteShort(mStationaryShape); + buffer.WriteShort(mMovingShape); + buffer.WriteShort(mTeleportInShape); + buffer.WriteShort(mTeleportOutShape); + + buffer.WriteShort(mAttackFrequency); + mMeleeAttack.SaveObject(buffer); + mRangedAttack.SaveObject(buffer); + + return buffer; +} + +BigEndianBuffer& ProjectileDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mCollection = buffer.ReadUShort(); + mColorTable = (mCollection >> 5) & 0x7; + mCollection &= 0x1f; + mShape = buffer.ReadShort(); + + mDetonationEffect = buffer.ReadShort(); + mMediaDetonationEffect = buffer.ReadShort(); + mContrailEffect = buffer.ReadShort(); + mTicksBetweenContrails = buffer.ReadShort(); + mMaximumContrails = buffer.ReadShort(); + mMediaProjectilePromotion = buffer.ReadShort(); + + mRadius = buffer.ReadShort(); + mAreaOfEffect = buffer.ReadShort(); + mDamage.LoadObject(buffer); + if (!mDamage.IsGood()) { + return buffer; + } + + mFlags = buffer.ReadULong(); + + mSpeed = buffer.ReadShort(); + mMaximumRange = buffer.ReadShort(); + + mSoundPitch = buffer.ReadFixed(); + mFlybySound = buffer.ReadShort(); + mReboundSound = buffer.ReadShort(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& ProjectileDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteUShort(BuildCollection(mCollection, mColorTable)); + buffer.WriteShort(mShape); + + buffer.WriteShort(mDetonationEffect); + buffer.WriteShort(mMediaDetonationEffect); + buffer.WriteShort(mContrailEffect); + buffer.WriteShort(mTicksBetweenContrails); + buffer.WriteShort(mMaximumContrails); + buffer.WriteShort(mMediaProjectilePromotion); + + buffer.WriteShort(mRadius); + buffer.WriteShort(mAreaOfEffect); + mDamage.SaveObject(buffer); + + buffer.WriteULong(mFlags); + + buffer.WriteShort(mSpeed); + buffer.WriteShort(mMaximumRange); + + buffer.WriteFixed(mSoundPitch); + buffer.WriteShort(mFlybySound); + buffer.WriteShort(mReboundSound); + + return buffer; +} + +BigEndianBuffer& TriggerDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mRoundsPerMagazine = buffer.ReadShort(); + mAmmunitionType = buffer.ReadShort(); + mTicksPerRound = buffer.ReadShort(); + mRecoveryTicks = buffer.ReadShort(); + mChargingTicks = buffer.ReadShort(); + mRecoilMagnitude = buffer.ReadShort(); + + mFiringSound = buffer.ReadShort(); + mClickSound = buffer.ReadShort(); + mChargingSound = buffer.ReadShort(); + mShellCasingSound = buffer.ReadShort(); + mReloadingSound = buffer.ReadShort(); + mChargedSound = buffer.ReadShort(); + + mProjectileType = buffer.ReadShort(); + mThetaError = buffer.ReadShort(); + mDx = buffer.ReadShort(); + mDz = buffer.ReadShort(); + mShellCasingType = buffer.ReadShort(); + mBurstCount = buffer.ReadShort(); + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& TriggerDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteShort(mRoundsPerMagazine); + buffer.WriteShort(mAmmunitionType); + buffer.WriteShort(mTicksPerRound); + buffer.WriteShort(mRecoveryTicks); + buffer.WriteShort(mChargingTicks); + buffer.WriteShort(mRecoilMagnitude); + + buffer.WriteShort(mFiringSound); + buffer.WriteShort(mClickSound); + buffer.WriteShort(mChargingSound); + buffer.WriteShort(mShellCasingSound); + buffer.WriteShort(mReloadingSound); + buffer.WriteShort(mChargedSound); + + buffer.WriteShort(mProjectileType); + buffer.WriteShort(mThetaError); + buffer.WriteShort(mDx); + buffer.WriteShort(mDz); + buffer.WriteShort(mShellCasingType); + buffer.WriteShort(mBurstCount); + + return buffer; +} + +BigEndianBuffer& WeaponDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mItemType = buffer.ReadShort(); + mPowerupType = buffer.ReadShort(); + mWeaponClass = buffer.ReadShort(); + mFlags = buffer.ReadShort(); + + mFiringLightIntensity = buffer.ReadFixed(); + mFiringIntensityDecayTicks = buffer.ReadShort(); + + mIdleHeight = buffer.ReadFixed(); + mBobAmplitude = buffer.ReadFixed(); + mKickHeight = buffer.ReadFixed(); + mReloadHeight = buffer.ReadFixed(); + mIdleWidth = buffer.ReadFixed(); + mHorizontalAmplitude = buffer.ReadFixed(); + + mCollection = buffer.ReadUShort(); + mColorTable = (mCollection >> 5) & 0x7; + mCollection &= 0x1f; + + mIdleShape = buffer.ReadShort(); + mFiringShape = buffer.ReadShort(); + mReloadingShape = buffer.ReadShort(); + buffer.ReadShort(); // unused + mChargingShape = buffer.ReadShort(); + mChargedShape = buffer.ReadShort(); + + mReadyTicks = buffer.ReadShort(); + mAwaitReloadTicks = buffer.ReadShort(); + mLoadingTicks = buffer.ReadShort(); + mFinishLoadingTicks = buffer.ReadShort(); + mPowerupTicks = buffer.ReadShort(); + + mPrimaryTrigger.LoadObject(buffer); + if (!mPrimaryTrigger.IsGood()) { + return buffer; + } + + mSecondaryTrigger.LoadObject(buffer); + if (!mSecondaryTrigger.IsGood()) { + return buffer; + } + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& WeaponDefinition::SaveObject(BigEndianBuffer& buffer) const +{ + buffer.WriteShort(mItemType); + buffer.WriteShort(mPowerupType); + buffer.WriteShort(mWeaponClass); + buffer.WriteShort(mFlags); + + buffer.WriteFixed(mFiringLightIntensity); + buffer.WriteShort(mFiringIntensityDecayTicks); + + buffer.WriteFixed(mIdleHeight); + buffer.WriteFixed(mBobAmplitude); + buffer.WriteFixed(mKickHeight); + buffer.WriteFixed(mReloadHeight); + buffer.WriteFixed(mIdleWidth); + buffer.WriteFixed(mHorizontalAmplitude); + + buffer.WriteUShort(BuildCollection(mCollection, mColorTable)); + + buffer.WriteShort(mIdleShape); + buffer.WriteShort(mFiringShape); + buffer.WriteShort(mReloadingShape); + buffer.WriteShort(-1); // unused + buffer.WriteShort(mChargingShape); + buffer.WriteShort(mChargedShape); + + buffer.WriteShort(mReadyTicks); + buffer.WriteShort(mAwaitReloadTicks); + buffer.WriteShort(mLoadingTicks); + buffer.WriteShort(mFinishLoadingTicks); + buffer.WriteShort(mPowerupTicks); + + mPrimaryTrigger.SaveObject(buffer); + mSecondaryTrigger.SaveObject(buffer); + + return buffer; +} + +std::ostream& operator<<(std::ostream& s, const PhysicsConstants& constants) +{ + s << "Maximum Forward Velocity: " << constants.mMaximumForwardVelocity << std::endl; + s << "Maximum Backward Velocity: " << constants.mMaximumBackwardVelocity << std::endl; + s << "Maximum Perpendicular Velocity: " << constants.mMaximumPerpendicularVelocity << std::endl; + s << "Acceleration: " << constants.mAcceleration << std::endl; + s << "Deceleration: " << constants.mDeceleration << std::endl; + s << "Airborne Deceleration: " << constants.mAirborneDeceleration << std::endl; + s << "Gravitational Acceleration: " << constants.mGravitationalAcceleration << std::endl; + s << "Climbing Acceleration: " << constants.mClimbingAcceleration << std::endl; + s << "Terminal Velocity: " << constants.mTerminalVelocity << std::endl; + s << "External Deceleration: " << constants.mExternalDeceleration << std::endl; + s << "Angular Acceleration: " << constants.mAngularAcceleration << std::endl; + s << "Angular Deceleration: " << constants.mAngularDeceleration << std::endl; + s << "Maximum Angular Velocity: " << constants.mMaximumAngularVelocity << std::endl; + s << "Angular Recentering Velocity: " << constants.mAngularRecenteringVelocity << std::endl; + s << "Fast Angular Velocity: " << constants.mFastAngularVelocity << std::endl; + s << "Fast Angular Maximum: " << constants.mFastAngularMaximum << std::endl; + s << "Maximum Elevation: " << constants.mMaximumElevation << std::endl; + s << "Eternal Angular Deceleration: " << constants.mExternalAngularDeceleration << std::endl; + s << "Step Delta: " << constants.mStepDelta << std::endl; + s << "Step Amplitude: " << constants.mStepAmplitude << std::endl; + s << "Radius: " << constants.mRadius << std::endl; + s << "Height: " << constants.mHeight << std::endl; + s << "Dead Height: " << constants.mDeadHeight << std::endl; + s << "Camera Height: " << constants.mCameraHeight << std::endl; + s << "Splash Height: " << constants.mSplashHeight << std::endl; + s << "Half Camera Separation: " << constants.mHalfCameraSeparation << std::endl; + return s; +} + +std::ostream& operator<<(std::ostream& s, const AttackDefinition& attack) +{ + s << "Type: " << attack.mType << std::endl; + s << "Repetitions: " << attack.mRepetitions << std::endl; + s << "Error: " << attack.mError << std::endl; + s << "Range: " << attack.mRange << std::endl; + s << "Attack Shape: " << attack.mAttackShape << std::endl; + s << "dx: " << attack.mDx << std::endl; + s << "dy: " << attack.mDy << std::endl; + s << "dz: " << attack.mDz << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const DamageDefinition& damage) +{ + s << "Type: " << damage.mType << std::endl; + s << "Flags: " << damage.mFlags << std::endl; + s << "Base: " << damage.mBase << std::endl; + s << "Random: " << damage.mRandom << std::endl; + s << "Scale: " << damage.mScale << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const EffectDefinition& effect) +{ + s << "Collection: " << effect.mCollection << std::endl; + s << "Color Table: " << effect.mColorTable << std::endl; + s << "Shape: " << effect.mShape << std::endl; + s << "Sound Pitch: " << effect.mSoundPitch << std::endl; + s << "Flags: " << effect.mFlags << std::endl; + s << "Delay: " << effect.mDelay << std::endl; + s << "Delay Sound: " << effect.mDelaySound << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const MonsterDefinition& monster) +{ + s << "mCollection: " << monster.mCollection << std::endl; + s << "mColorTable: " << monster.mColorTable << std::endl; + + s << "mVitality: " << monster.mVitality << std::endl; + s << "mImmunities: " << monster.mImmunities << std::endl; + s << "mWeaknesses: " << monster.mWeaknesses << std::endl; + s << "mFlags: " << monster.mFlags << std::endl; + + s << "mClass: " << monster.mClass << std::endl; + s << "mFriends: " << monster.mFriends << std::endl; + s << "mEnemies: " << monster.mEnemies << std::endl; + + s << "mSoundPitch: " << monster.mSoundPitch << std::endl; + + s << "mActivationSound: " << monster.mActivationSound << std::endl; + s << "mFriendlyActivationSound: " << monster.mFriendlyActivationSound << std::endl; + s << "mClearSound: " << monster.mClearSound << std::endl; + s << "mKillSound: " << monster.mKillSound << std::endl; + s << "mApologySound: " << monster.mApologySound << std::endl; + s << "mFriendlyFireSound: " << monster.mFriendlyFireSound << std::endl; + s << "mFlamingSound: " << monster.mFlamingSound << std::endl; + s << "mRandomSound: " << monster.mRandomSound << std::endl; + s << "mRandomSoundMask: " << monster.mRandomSoundMask << std::endl; + + s << "mCarryingItemType: " << monster.mCarryingItemType << std::endl; + + s << "mRadius: " << monster.mRadius << std::endl; + s << "mHeight: " << monster.mHeight << std::endl; + s << "mPreferredHoverHeight: " << monster.mPreferredHoverHeight << std::endl; + s << "mMinimumLedgeDelta: " << monster.mMinimumLedgeDelta << std::endl; + s << "mMaximumLedgeDelta: " << monster.mMaximumLedgeDelta << std::endl; + s << "mExternalVelocityScale: " << monster.mExternalVelocityScale << std::endl; + s << "mImpactEffect: " << monster.mImpactEffect << std::endl; + s << "mMeleeImpactEffect: " << monster.mMeleeImpactEffect << std::endl; + s << "mContrailEffect: " << monster.mContrailEffect << std::endl; + + s << "mHalfVisualArc: " << monster.mHalfVisualArc << std::endl; + s << "mHalfVerticalVisualArc: " << monster.mHalfVerticalVisualArc << std::endl; + s << "mVisualRange: " << monster.mVisualRange << std::endl; + s << "mDarkVisualRange: " << monster.mDarkVisualRange << std::endl; + s << "mIntelligence: " << monster.mIntelligence << std::endl; + s << "mSpeed: " << monster.mSpeed << std::endl; + s << "mGravity: " << monster.mGravity << std::endl; + s << "mTerminalVelocity: " << monster.mTerminalVelocity << std::endl; + s << "mDoorRetryMask: " << monster.mDoorRetryMask << std::endl; + s << "mShrapnelRadius: " << monster.mShrapnelRadius << std::endl; + + s << "mShrapnelDamage: " << std::endl; + s << monster.mShrapnelDamage << std::endl; + + s << "mHitShapes: " << monster.mHitShapes << std::endl; + s << "mHardDyingShape: " << monster.mHardDyingShape << std::endl; + s << "mSoftDyingShape: " << monster.mSoftDyingShape << std::endl; + s << "mHardDeadShapes: " << monster.mHardDeadShapes << std::endl; + s << "mSoftDeadShapes: " << monster.mSoftDeadShapes << std::endl; + s << "mStationaryShape: " << monster.mStationaryShape << std::endl; + s << "mMovingShape: " << monster.mMovingShape << std::endl; + s << "mTeleportInShape: " << monster.mTeleportInShape << std::endl; + s << "mTeleportOutShape: " << monster.mTeleportOutShape << std::endl; + + s << "mAttackFrequency: " << monster.mAttackFrequency << std::endl; + s << "mMeleeAttack: " << std::endl; + s << monster.mMeleeAttack << std::endl; + s << "mRangedAttack: " << std::endl; + s << monster.mRangedAttack << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const ProjectileDefinition& projectile) +{ + s << "mCollection: " << projectile.mCollection << std::endl; + s << "mColorTable: " << projectile.mColorTable << std::endl; + s << "mShape: " << projectile.mShape << std::endl; + + s << "mDetonationEffect: " << projectile.mDetonationEffect << std::endl; + s << "mMediaDetonationEffect: " << projectile.mMediaDetonationEffect << std::endl; + s << "mContrailEffect: " << projectile.mContrailEffect << std::endl; + s << "mTicksBetweenContrails: " << projectile.mTicksBetweenContrails << std::endl; + s << "mMaximumContrails: " << projectile.mMaximumContrails << std::endl; + s << "mMediaProjectilePromotion: " << projectile.mMediaProjectilePromotion << std::endl; + + s << "mRadius: " << projectile.mRadius << std::endl; + s << "mAreaOfEffect: " << projectile.mAreaOfEffect << std::endl; + s << "mDamage" << std::endl; + s << projectile.mDamage; + + s << "mFlags: " << projectile.mFlags << std::endl; + + s << "mSpeed: " << projectile.mSpeed << std::endl; + s << "mMaximumRange: " << projectile.mMaximumRange << std::endl; + + s << "mSoundPitch: " << projectile.mSoundPitch << std::endl; + s << "mFlybySound: " << projectile.mFlybySound << std::endl; + s << "mReboundSound: " << projectile.mReboundSound << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const TriggerDefinition& trigger) +{ + s << "mRoundsPerMagazine: " << trigger.mRoundsPerMagazine << std::endl; + s << "mAmmunitionType: " << trigger.mAmmunitionType << std::endl; + s << "mTicksPerRound: " << trigger.mTicksPerRound << std::endl; + s << "mRecoveryTicks: " << trigger.mRecoveryTicks << std::endl; + s << "mChargingTicks: " << trigger.mChargingTicks << std::endl; + s << "mRecoilMagnitude: " << trigger.mRecoilMagnitude << std::endl; + + s << "mFiringSound: " << trigger.mFiringSound << std::endl; + s << "mClickSound: " << trigger.mClickSound << std::endl; + s << "mChargingSound: " << trigger.mChargingSound << std::endl; + s << "mShellCasingSound: " << trigger.mShellCasingSound << std::endl; + s << "mReloadingSound: " << trigger.mReloadingSound << std::endl; + s << "mChargedSound: " << trigger.mChargedSound << std::endl; + + s << "mProjectileType: " << trigger.mProjectileType << std::endl; + s << "mThetaError: " << trigger.mThetaError << std::endl; + s << "mDx: " << trigger.mDx << std::endl; + s << "mDz: " << trigger.mDz << std::endl; + s << "mShellCasingType: " << trigger.mShellCasingType << std::endl; + s << "mBurstCount: " << trigger.mBurstCount << std::endl; + + return s; +} + +std::ostream& operator<<(std::ostream& s, const WeaponDefinition& weapon) +{ + s << "mItemType: " << weapon.mItemType << std::endl; + s << "mPowerupType: " << weapon.mPowerupType << std::endl; + s << "mWeaponClass: " << weapon.mWeaponClass << std::endl; + s << "mFlags: " << weapon.mFlags << std::endl; + + s << "mFiringLightIntensity: " << weapon.mFiringLightIntensity << std::endl; + s << "mFiringIntensityDecayTicks: " << weapon.mFiringIntensityDecayTicks << std::endl; + + s << "mIdleHeight: " << weapon.mIdleHeight << std::endl; + s << "mBobAmplitude: " << weapon.mBobAmplitude << std::endl; + s << "mKickHeight: " << weapon.mKickHeight << std::endl; + s << "mReloadHeight: " << weapon.mReloadHeight << std::endl; + s << "mIdleWidth: " << weapon.mIdleWidth << std::endl; + s << "mHorizontalAmplitude: " << weapon.mHorizontalAmplitude << std::endl; + + s << "mCollection: " << weapon.mCollection << std::endl; + s << "mColorTable: " << weapon.mColorTable << std::endl; + + s << "mIdleShape: " << weapon.mIdleShape << std::endl; + s << "mFiringShape: " << weapon.mFiringShape << std::endl; + s << "mReloadingShape: " << weapon.mReloadingShape << std::endl; + s << "mChargingShape: " << weapon.mChargingShape << std::endl; + s << "mChargedShape: " << weapon.mChargedShape << std::endl; + + s << "mReadyTicks: " << weapon.mReadyTicks << std::endl; + s << "mAwaitReloadTicks: " << weapon.mAwaitReloadTicks << std::endl; + s << "mLoadingTicks: " << weapon.mLoadingTicks << std::endl; + s << "mFinishLoadingTicks: " << weapon.mFinishLoadingTicks << std::endl; + s << "mPowerupTicks: " << weapon.mPowerupTicks << std::endl; + + s << "mPrimaryTrigger: " << weapon.mPrimaryTrigger << std::endl; + s << "mSecondaryTrigger: " << weapon.mSecondaryTrigger << std::endl; + + return s; +} diff --git a/Physics/PhysicsElements.h b/Physics/PhysicsElements.h new file mode 100644 index 0000000..fafe89e --- /dev/null +++ b/Physics/PhysicsElements.h @@ -0,0 +1,816 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef PHYSICSELEMENTS_H +#define PHYSICSELEMENTS_H + +#include "../BigEndianBuffer.h" +#include + +class PhysicsElement +{ +private: + bool mVerboseLoading; + +protected: + // So that subclasses can change their status + bool mGoodData; + +public: + PhysicsElement(bool verbose) : mVerboseLoading(verbose), mGoodData(false) {} + ~PhysicsElement() { } + + bool IsGood() const { return mGoodData; } + bool IsVerbose() const { return mVerboseLoading; } +}; + +class PhysicsConstants : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const PhysicsConstants&); +private: + double mMaximumForwardVelocity; + double mMaximumBackwardVelocity; + double mMaximumPerpendicularVelocity; + + double mAcceleration; + double mDeceleration; + double mAirborneDeceleration; + + double mGravitationalAcceleration; + double mClimbingAcceleration; + double mTerminalVelocity; + + double mExternalDeceleration; + + double mAngularAcceleration; + double mAngularDeceleration; + double mMaximumAngularVelocity; + double mAngularRecenteringVelocity; + + double mFastAngularVelocity; + double mFastAngularMaximum; + + double mMaximumElevation; + double mExternalAngularDeceleration; + + double mStepDelta; + double mStepAmplitude; + + double mRadius; + double mHeight; + double mDeadHeight; + double mCameraHeight; + double mSplashHeight; + + double mHalfCameraSeparation; +public: + // accessors + double GetMaximumForwardVelocity() const { return mMaximumForwardVelocity; } + double GetMaximumBackwardVelocity() const { return mMaximumBackwardVelocity; } + double GetMaximumPerpendicularVelocity() const { return mMaximumPerpendicularVelocity; } + + double GetAcceleration() const { return mAcceleration; } + double GetDeceleration() const { return mDeceleration; } + double GetAirborneDeceleration() const { return mAirborneDeceleration; } + + double GetGravitationalAcceleration() const { return mGravitationalAcceleration; } + double GetClimbingAcceleration() const { return mClimbingAcceleration; } + double GetTerminalVelocity() const { return mTerminalVelocity; } + + double GetExternalDeceleration() const { return mExternalDeceleration; } + + double GetAngularAcceleration() const { return mAngularAcceleration; } + double GetAngularDeceleration() const { return mAngularDeceleration; } + double GetMaximumAngularVelocity() const { return mMaximumAngularVelocity; } + double GetAngularRecenteringVelocity() const { return mAngularRecenteringVelocity; } + + + double GetFastAngularVelocity() const { return mFastAngularVelocity; } + double GetFastAngularMaximum() const { return mFastAngularMaximum; } + + double GetMaximumElevation() const { return mMaximumElevation; } + double GetExternalAngularDeceleration() const { return mExternalAngularDeceleration; } + + double GetStepDelta() const { return mStepDelta; } + double GetStepAmplitude() const { return mStepAmplitude; } + + double GetRadius() const { return mRadius; } + double GetHeight() const { return mHeight; } + double GetDeadHeight() const { return mDeadHeight; } + double GetCameraHeight() const { return mCameraHeight; } + double GetSplashHeight() const { return mSplashHeight; } + + double GetHalfCameraSeparation() const { return mHalfCameraSeparation; } + + // mutators + void SetMaximumForwardVelocity(double v) { mMaximumForwardVelocity = v; } + void SetMaximumBackwardVelocity(double v) { mMaximumBackwardVelocity = v; } + void SetMaximumPerpendicularVelocity(double v) { mMaximumPerpendicularVelocity = v; } + + void SetAcceleration(double v) { mAcceleration = v; } + void SetDeceleration(double v) { mDeceleration = v; } + void SetAirborneDeceleration(double v) { mAirborneDeceleration = v; } + + void SetGravitationalAcceleration(double v) { mGravitationalAcceleration = v; } + void SetClimbingAcceleration(double v) { mClimbingAcceleration = v; } + void SetTerminalVelocity(double v) { mTerminalVelocity = v; } + + void SetExternalDeceleration(double v) { mExternalDeceleration = v; } + + void SetAngularAcceleration(double v) { mAngularAcceleration = v; } + void SetAngularDeceleration(double v) { mAngularDeceleration = v; } + void SetMaximumAngularVelocity(double v) { mMaximumAngularVelocity = v; } + void SetAngularRecenteringVelocity(double v) { mAngularRecenteringVelocity = v; } + + void SetFastAngularVelocity(double v) { mFastAngularVelocity = v; } + void SetFastAngularMaximum(double v) { mFastAngularMaximum = v; } + + void SetMaximumElevation(double v) { mMaximumElevation = v; } + void SetExternalAngularDeceleration(double v) { mExternalAngularDeceleration = v; } + + void SetStepDelta(double v) { mStepDelta = v; } + void SetStepAmplitude(double v) { mStepAmplitude = v; } + + void SetRadius(double v) { mRadius = v; } + void SetHeight(double v) { mHeight = v; } + void SetDeadHeight(double v) { mDeadHeight = v; } + void SetCameraHeight(double v) { mCameraHeight = v; } + void SetSplashHeight(double v) { mSplashHeight = v; } + + void SetHalfCameraSeparation(double v) { mHalfCameraSeparation = v; } + + + PhysicsConstants(bool verbose = false) : PhysicsElement(verbose) { } + ~PhysicsConstants() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); + + static const int kSize = 104; +}; + +class AttackDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const AttackDefinition&); +private: + short mType; + short mRepetitions; + double mError; + short mRange; + short mAttackShape; + short mDx, mDy, mDz; + +public: + // accessors + short GetType() { return mType; } + short GetRepetitions() { return mRepetitions; } + double GetError() { return mError; } + short GetRange() { return mRange; } + short GetShape() { return mAttackShape; } + short GetDx() { return mDx; } + short GetDy() { return mDy; } + short GetDz() { return mDz; } + + // mutators + void SetType(short v) { mType = v; } + void SetRepetitions(short v) { mRepetitions = v; } + void SetError(double d) { mError = d; } + void SetRange(short v) { mRange = v; } + void SetShape(short v) { mAttackShape = v; } + void SetDx(short v) { mDx = v; } + void SetDy(short v) { mDy = v; } + void SetDz(short v) { mDz = v; } + + AttackDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~AttackDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +class DamageDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const DamageDefinition&); +private: + short mType; + short mFlags; + short mBase; + short mRandom; + double mScale; + + enum { + kAlienDamage = 0x01 + }; + +public: + // accessors + short GetType() { return mType; } + short GetBase() { return mBase; } + bool GetAlien() { return mFlags & kAlienDamage; } + short GetRandom() { return mRandom; } + double GetScale() { return mScale; } + + // mutators + void SetType(short v) { mType = v; } + void SetAlien(bool b) { + if (b) mFlags |= kAlienDamage; + else mFlags &= ~kAlienDamage; + } + + void SetBase(short v) { mBase = v; } + void SetRandom(short v) { mRandom = v; } + void SetScale(double d) { mScale = d; } + + DamageDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~DamageDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +class EffectDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const EffectDefinition&); +private: + unsigned short mCollection; + unsigned short mColorTable; + short mShape; + double mSoundPitch; + unsigned short mFlags; + short mDelay; + short mDelaySound; + + enum { + kEndWhenAnimationLoops = 0x0001, + kEndWhenTransferAnimationLoops = 0x0002, + kSoundOnly = 0x0004, + kMakeTwinVisible = 0x0008, + kMediaEffect = 0x0010 + }; + +public: + // accessors + unsigned short GetCollection() { return mCollection; } + unsigned short GetColorTable() { return mColorTable; } + short GetShape() { return mShape; } + double GetSoundPitch() { return mSoundPitch; } + short GetDelay() { return mDelay; } + short GetDelaySound() { return mDelaySound; } + + bool GetEndWhenAnimationLoops() { return mFlags & kEndWhenAnimationLoops; } + bool GetEndWhenTransferAnimationLoops() { return mFlags & kEndWhenTransferAnimationLoops; } + bool GetSoundOnly() { return mFlags & kSoundOnly; } + bool GetMediaEffect() { return mFlags & kMediaEffect; } + + // mutators + void SetCollection(unsigned short v) { mCollection = v; } + void SetColorTable(unsigned short v) { mColorTable = v; } + void SetShape(short v) { mShape = v; } + void SetSoundPitch(double v) { mSoundPitch = v; } + void SetDelay(short v) { mDelay = v; } + void SetDelaySound(short v) { mDelaySound = v; } + + void SetEndWhenAnimationLoops(bool v) { + if (v) mFlags |= kEndWhenAnimationLoops; + else mFlags &= ~kEndWhenAnimationLoops; + } + + void SetEndWhenTransferAnimationLoops(bool v) { + if (v) mFlags |= kEndWhenTransferAnimationLoops; + else mFlags &= ~kEndWhenTransferAnimationLoops; + } + + void SetSoundOnly(bool v) { + if (v) mFlags |= kSoundOnly; + else mFlags &= ~kSoundOnly; + } + + void SetMediaEffect(bool v) { + if (v) mFlags |= kMediaEffect; + else mFlags &= ~kMediaEffect; + } + + EffectDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~EffectDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); + + static const int kSize = 14; +}; + +class MonsterDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const MonsterDefinition&); +private: + unsigned short mCollection; + unsigned short mColorTable; + + short mVitality; + unsigned long mImmunities; + unsigned long mWeaknesses; + unsigned long mFlags; + + long mClass; + long mFriends; + long mEnemies; + + double mSoundPitch; + + short mActivationSound; + short mFriendlyActivationSound; + short mClearSound; + short mKillSound; + short mApologySound; + short mFriendlyFireSound; + short mFlamingSound; + short mRandomSound; + short mRandomSoundMask; + + short mCarryingItemType; + + short mRadius; + short mHeight; + short mPreferredHoverHeight; + short mMinimumLedgeDelta; + short mMaximumLedgeDelta; + double mExternalVelocityScale; + short mImpactEffect; + short mMeleeImpactEffect; + short mContrailEffect; + + short mHalfVisualArc; + short mHalfVerticalVisualArc; + short mVisualRange; + short mDarkVisualRange; + short mIntelligence; + short mSpeed; + short mGravity; + short mTerminalVelocity; + short mDoorRetryMask; + short mShrapnelRadius; + + DamageDefinition mShrapnelDamage; + + // sequence IDs + short mHitShapes; + short mHardDyingShape; + short mSoftDyingShape; + short mHardDeadShapes; + short mSoftDeadShapes; + short mStationaryShape; + short mMovingShape; + short mTeleportInShape; + short mTeleportOutShape; + + short mAttackFrequency; + AttackDefinition mMeleeAttack; + AttackDefinition mRangedAttack; + +public: + // accessors + unsigned short GetCollection() { return mCollection; } + unsigned short GetColorTable() { return mColorTable; } + + short GetVitality() { return mVitality; } + bool GetImmunity(int index) { return mImmunities & (1 << index); } + bool GetWeakness(int index) { return mWeaknesses & (1 << index); } + bool GetFlag(int index) { return mFlags & (1 << index); } + + long GetClass() { return mClass; } + bool GetFriend(int index) { return mFriends & (1 << index); } + bool GetEnemy(int index) { return mEnemies & (1 << index); } + + double GetSoundPitch() { return mSoundPitch; } + + short GetActivationSound() { return mActivationSound; } + short GetFriendlyActivationSound() { return mFriendlyActivationSound; } + short GetClearSound() { return mClearSound; } + short GetKillSound() { return mKillSound; } + short GetApologySound() { return mApologySound; } + short GetFriendlyFireSound() { return mFriendlyFireSound; } + short GetFlamingSound() { return mFlamingSound; } + short GetRandomSound() { return mRandomSound; } + short GetRandomSoundMask() { return mRandomSoundMask; } + + short GetCarryingItemType() { return mCarryingItemType; } + + short GetRadius() { return mRadius; } + short GetHeight() { return mHeight; } + short GetPreferredHoverHeight() { return mPreferredHoverHeight; } + short GetMinimumLedgeDelta() { return mMinimumLedgeDelta; } + short GetMaximumLedgeDelta() { return mMaximumLedgeDelta; } + double GetExternalVelocityScale() { return mExternalVelocityScale; } + short GetImpactEffect() { return mImpactEffect; } + short GetMeleeImpactEffect() { return mMeleeImpactEffect; } + short GetContrailEffect() { return mContrailEffect; } + + short GetVisualRange() { return mVisualRange; } + short GetDarkVisualRange() { return mDarkVisualRange; } + short GetIntelligence() { return mIntelligence; } + short GetSpeed() { return mSpeed; } + short GetGravity() { return mGravity; } + short GetTerminalVelocity() { return mTerminalVelocity; } + short GetDoorRetryMask() { return mDoorRetryMask; } + short GetShrapnelRadius() { return mShrapnelRadius; } + + DamageDefinition* GetShrapnelDamage() { return &mShrapnelDamage; } + + short GetHitShapes() { return mHitShapes; } + short GetHardDyingShape() { return mHardDyingShape; } + short GetSoftDyingShape() { return mSoftDyingShape; } + short GetHardDeadShapes() { return mHardDeadShapes; } + short GetSoftDeadShapes() { return mSoftDeadShapes; } + short GetStationaryShape() { return mStationaryShape; } + short GetMovingShape() { return mMovingShape; } + short GetTeleportInShape() { return mTeleportInShape; } + short GetTeleportOutShape() { return mTeleportOutShape; } + + short GetAttackFrequency() { return mAttackFrequency; } + AttackDefinition* GetMeleeAttack() { return &mMeleeAttack; } + AttackDefinition* GetRangedAttack() { return &mRangedAttack; } + + // mutators + void SetCollection(unsigned short v) { mCollection = v; } + void SetColorTable(unsigned short v) { mColorTable = v; } + + void SetVitality(short v) { mVitality = v; } + void SetImmunity(int index, bool b) { + if (b) mImmunities |= (1 << index); + else mImmunities &= ~(1 << index); + } + + void SetWeakness(int index, bool b) { + if (b) mWeaknesses |= (1 << index); + else mWeaknesses &= ~(1 << index); + } + + void SetFlag(int index, bool b) { + if (b) mFlags |= (1 << index); + else mFlags &= ~(1 << index); + } + + void SetClass(long v) { mClass = v; } + + void SetFriend(int index, bool b) { + if (b) mFriends |= (1 << index); + else mFriends &= ~(1 << index); + } + + void SetEnemy(int index, bool b) { + if (b) mEnemies |= (1 << index); + else mEnemies &= ~(1 << index); + } + + void SetSoundPitch(double d) { mSoundPitch = d; } + + void SetRadius(short v) { mRadius = v; } + void SetHeight(short v) { mHeight = v; } + void SetPreferredHoverHeight(short v) { mPreferredHoverHeight = v; } + void SetMinimumLedgeDelta(short v) { mMinimumLedgeDelta = v; } + void SetMaximumLedgeDelta(short v) { mMaximumLedgeDelta = v; } + void SetExternalVelocityScale(double d) { mExternalVelocityScale = d; } + void SetImpactEffect(short v) { mImpactEffect = v; } + void SetMeleeImpactEffect(short v) { mMeleeImpactEffect = v; } + void SetContrailEffect(short v) { mContrailEffect = v; } + + void SetVisualRange(short v) { mVisualRange = v; } + void SetDarkVisualRange(short v) { mDarkVisualRange = v; } + void SetIntelligence(short v) { mIntelligence = v; } + void SetSpeed(short v) { mSpeed = v; } + void SetGravity(short v) { mGravity = v; } + void SetTerminalVelocity(short v) { mTerminalVelocity = v; } + void SetDoorRetryMask(short v) { mDoorRetryMask = v; } + void SetShrapnelRadius(short v) { mShrapnelRadius = v; } + + + void SetActivationSound(short v) { mActivationSound = v; } + void SetFriendlyActivationSound(short v) { mFriendlyActivationSound = v; } + void SetClearSound(short v) { mClearSound = v; } + void SetKillSound(short v) { mKillSound = v; } + void SetApologySound(short v) { mApologySound = v; } + void SetFriendlyFireSound(short v) { mFriendlyFireSound = v; } + void SetFlamingSound(short v) { mFlamingSound = v; } + void SetRandomSound(short v) { mRandomSound = v; } + void SetRandomSoundMask(short v) { mRandomSoundMask = v; } + + void SetCarryingItemType(short v) { mCarryingItemType = v; } + + void SetHitShapes(short v) { mHitShapes = v; } + void SetHardDyingShape(short v) { mHardDyingShape = v; } + void SetSoftDyingShape(short v) { mSoftDyingShape = v; } + void SetHardDeadShapes(short v) { mHardDeadShapes = v; } + void SetSoftDeadShapes(short v) { mSoftDeadShapes = v; } + void SetStationaryShape(short v) { mStationaryShape = v; } + void SetMovingShape(short v) { mMovingShape = v; } + void SetTeleportInShape(short v) { mTeleportInShape = v; } + void SetTeleportOutShape(short v) { mTeleportOutShape = v; } + + void SetAttackFrequency(short v) { mAttackFrequency = v; } + + MonsterDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~MonsterDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); + + static const int kSize = 156; +}; + +class ProjectileDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const ProjectileDefinition&); +private: + unsigned short mCollection; + unsigned short mColorTable; + short mShape; + + short mDetonationEffect; + short mMediaDetonationEffect; + short mContrailEffect; + short mTicksBetweenContrails; + short mMaximumContrails; + short mMediaProjectilePromotion; + + short mRadius; + short mAreaOfEffect; + DamageDefinition mDamage; + + unsigned long mFlags; + + short mSpeed; + short mMaximumRange; + + double mSoundPitch; + short mFlybySound; + short mReboundSound; + +public: + // accessors + unsigned short GetCollection() { return mCollection; } + unsigned short GetColorTable() { return mColorTable; } + short GetShape() { return mShape; } + + short GetDetonationEffect() { return mDetonationEffect; } + short GetMediaDetonationEffect() { return mMediaDetonationEffect; } + short GetContrailEffect() { return mContrailEffect; } + short GetTicksBetweenContrails() { return mTicksBetweenContrails; } + short GetMaximumContrails() { return mMaximumContrails; } + short GetMediaProjectilePromotion() { return mMediaProjectilePromotion; } + + short GetRadius() { return mRadius; } + short GetAreaOfEffect() { return mAreaOfEffect; } + + DamageDefinition* GetDamage() { return &mDamage; } + + bool GetFlag(int flag_index) { return mFlags & (1 << flag_index); } + + short GetSpeed() { return mSpeed; } + short GetMaximumRange() { return mMaximumRange; } + + double GetSoundPitch() { return mSoundPitch; } + short GetFlybySound() { return mFlybySound; } + short GetReboundSound() { return mReboundSound; } + + // mutators + void SetCollection(unsigned short v) { mCollection = v; } + void SetColorTable(unsigned short v) { mColorTable = v; } + void SetShape(short v) { mShape = v; } + + void SetDetonationEffect(short v) { mDetonationEffect = v; } + void SetMediaDetonationEffect(short v) { mMediaDetonationEffect = v; } + void SetContrailEffect(short v) { mContrailEffect = v; } + void SetTicksBetweenContrails(short v) { mTicksBetweenContrails = v; } + void SetMaximumContrails(short v) { mMaximumContrails = v; } + void SetMediaProjectilePromotion(short v) { mMediaProjectilePromotion = v; } + + void SetRadius(short v) { mRadius = v; } + void SetAreaOfEffect(short v) { mAreaOfEffect = v; } + + void SetFlag(int flag_index, bool f) { + if (f) mFlags |= (1 << flag_index); + else mFlags &= ~(1 << flag_index); + } + + void SetSpeed(short v) { mSpeed = v; } + void SetMaximumRange(short v) { mMaximumRange = v; } + + void SetSoundPitch(double v) { mSoundPitch = v; } + void SetFlybySound(short v) { mFlybySound = v; } + void SetReboundSound(short v) { mReboundSound = v; } + + ProjectileDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~ProjectileDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); + + static const int kSize = 48; +}; + +class TriggerDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const TriggerDefinition&); +private: + short mRoundsPerMagazine; + short mAmmunitionType; + short mTicksPerRound; + short mRecoveryTicks; + short mChargingTicks; + short mRecoilMagnitude; + + short mFiringSound; + short mClickSound; + short mChargingSound; + short mShellCasingSound; + short mReloadingSound; + short mChargedSound; + + short mProjectileType; + short mThetaError; + short mDx; + short mDz; + short mShellCasingType; + short mBurstCount; +public: + // accessors + short GetRoundsPerMagazine() { return mRoundsPerMagazine; } + short GetAmmunitionType() { return mAmmunitionType; } + short GetTicksPerRound() { return mTicksPerRound; } + short GetRecoveryTicks() { return mRecoveryTicks; } + short GetChargingTicks() { return mChargingTicks; } + short GetRecoilMagnitude() { return mRecoilMagnitude; } + + short GetFiringSound() { return mFiringSound; } + short GetClickSound() { return mClickSound; } + short GetChargingSound() { return mChargingSound; } + short GetShellCasingSound() { return mShellCasingSound; } + short GetReloadingSound() { return mReloadingSound; } + short GetChargedSound() { return mChargedSound; } + + short GetProjectileType() { return mProjectileType; } + short GetThetaError() { return mThetaError; } + short GetDx() { return mDx; } + short GetDz() { return mDz; } + short GetShellCasingType() { return mShellCasingType; } + short GetBurstCount() { return mBurstCount; } + + // mutators + void SetRoundsPerMagazine(short v) { mRoundsPerMagazine = v; } + void SetAmmunitionType(short v) { mAmmunitionType = v; } + void SetTicksPerRound(short v) { mTicksPerRound = v; } + void SetRecoveryTicks(short v) { mRecoveryTicks = v; } + void SetChargingTicks(short v) { mChargingTicks = v; } + void SetRecoilMagnitude(short v) { mRecoilMagnitude = v; } + + void SetFiringSound(short v) { mFiringSound = v; } + void SetClickSound(short v) { mClickSound = v; } + void SetChargingSound(short v) { mChargingSound = v; } + void SetShellCasingSound(short v) { mShellCasingSound = v; } + void SetReloadingSound(short v) { mReloadingSound = v; } + void SetChargedSound(short v) { mChargedSound = v; } + + void SetProjectileType(short v) { mProjectileType = v; } + void SetThetaError(short v) { mThetaError = v; } + void SetDx(short v) { mDx = v; } + void SetDz(short v) { mDz = v; } + void SetShellCasingType(short v) { mShellCasingType = v; } + void SetBurstCount(short v) { mBurstCount = v; } + + TriggerDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~TriggerDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +class WeaponDefinition : public PhysicsElement +{ + friend std::ostream& operator<<(std::ostream&, const WeaponDefinition&); +private: + short mItemType; + short mPowerupType; + short mWeaponClass; + short mFlags; + + double mFiringLightIntensity; + short mFiringIntensityDecayTicks; + + double mIdleHeight; + double mBobAmplitude; + double mKickHeight; + double mReloadHeight; + double mIdleWidth; + double mHorizontalAmplitude; + + unsigned short mCollection; + unsigned short mColorTable; + + short mIdleShape; + short mFiringShape; + short mReloadingShape; + // short unused + short mChargingShape; + short mChargedShape; + + short mReadyTicks; + short mAwaitReloadTicks; + short mLoadingTicks; + short mFinishLoadingTicks; + short mPowerupTicks; + + TriggerDefinition mPrimaryTrigger; + TriggerDefinition mSecondaryTrigger; +public: + // accessors + short GetItemType() { return mItemType; } + short GetPowerupType() { return mPowerupType; } + short GetWeaponClass() { return mWeaponClass; } + bool GetFlag(int index) { return mFlags & (1 << index); } + + double GetFiringLightIntensity() { return mFiringLightIntensity; } + short GetFiringIntensityDecayTicks() { return mFiringIntensityDecayTicks; } + + double GetIdleHeight() { return mIdleHeight; } + double GetBobAmplitude() { return mBobAmplitude; } + double GetKickHeight() { return mKickHeight; } + double GetReloadHeight() { return mReloadHeight; } + double GetIdleWidth() { return mIdleWidth; } + double GetHorizontalAmplitude() { return mHorizontalAmplitude; } + + unsigned short GetCollection() { return mCollection; } + unsigned short GetColorTable() { return mColorTable; } + + short GetIdleShape() { return mIdleShape; } + short GetFiringShape() { return mFiringShape; } + short GetReloadingShape() { return mReloadingShape; } + short GetChargingShape() { return mChargingShape; } + short GetChargedShape() { return mChargedShape; } + + short GetReadyTicks() { return mReadyTicks; } + short GetAwaitReloadTicks() { return mAwaitReloadTicks; } + short GetLoadingTicks() { return mLoadingTicks; } + short GetFinishLoadingTicks() { return mFinishLoadingTicks; } + + TriggerDefinition* GetPrimaryTrigger() { return &mPrimaryTrigger; } + TriggerDefinition* GetSecondaryTrigger() { return &mSecondaryTrigger; } + + // mutators + void SetItemType(short v) { mItemType = v; } + void SetPowerupType(short v) { mPowerupType = v; } + void SetWeaponClass(short v) { mWeaponClass = v; } + void SetFlag(int index, bool v) { + if (v) mFlags |= (1 << index); + else mFlags &= ~(1 << index); + } + + void SetFiringLightIntensity(double v) { mFiringLightIntensity = v; } + void SetFiringIntensityDecayTicks(short v) { mFiringIntensityDecayTicks = v; } + + void SetIdleHeight(double v) { mIdleHeight = v; } + void SetBobAmplitude(double v) { mBobAmplitude = v; } + void SetKickHeight(double v) { mKickHeight = v; } + void SetReloadHeight(double v) { mReloadHeight = v; } + void SetIdleWidth(double v) { mIdleWidth = v; } + void SetHorizontalAmplitude(double v) { mHorizontalAmplitude = v; } + + void SetCollection(unsigned short v) { mCollection = v; } + void SetColorTable(unsigned short v) { mColorTable = v; } + + void SetIdleShape(short v) { mIdleShape = v; } + void SetFiringShape(short v) { mFiringShape = v; } + void SetReloadingShape(short v) { mReloadingShape = v; } + void SetChargingShape(short v) { mChargingShape = v; } + void SetChargedShape(short v) { mChargedShape = v; } + + void SetReadyTicks(short v) { mReadyTicks = v; } + void SetAwaitReloadTicks(short v) { mAwaitReloadTicks = v; } + void SetLoadingTicks(short v) { mLoadingTicks = v; } + void SetFinishLoadingTicks(short v) { mFinishLoadingTicks = v; } + + + WeaponDefinition(bool verbose = false) : PhysicsElement(verbose) { } + ~WeaponDefinition() { } + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer) const; + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); + + static const int kSize = 134; +}; + +#endif diff --git a/Physics/PhysicsTreeItemData.cpp b/Physics/PhysicsTreeItemData.cpp new file mode 100644 index 0000000..9fe64ed --- /dev/null +++ b/Physics/PhysicsTreeItemData.cpp @@ -0,0 +1,28 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "PhysicsTreeItemData.h" + +PhysicsTreeItemData::PhysicsTreeItemData(int id, int sect) : id(id), section(sect) +{ + +} + +PhysicsTreeItemData::~PhysicsTreeItemData() +{ + +} diff --git a/Physics/PhysicsTreeItemData.h b/Physics/PhysicsTreeItemData.h new file mode 100644 index 0000000..3717c67 --- /dev/null +++ b/Physics/PhysicsTreeItemData.h @@ -0,0 +1,55 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef PHYSICSTREEITEMDATA_H +#define PHYSICSTREEITEMDATA_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif +#include "wx/treectrl.h" + +enum { + TREESECTION_MONSTERS = 1, + TREESECTION_MONSTERS_APPEARANCE, + TREESECTION_MONSTERS_COMBAT, + TREESECTION_MONSTERS_CONSTANTS, + TREESECTION_MONSTERS_BEHAVIOR, + TREESECTION_MONSTERS_IMMUNITIES, + TREESECTION_EFFECTS, + TREESECTION_PROJECTILES, + TREESECTION_PHYSICS, + TREESECTION_WEAPONS, + TREESECTION_WEAPONS_SETTINGS, + TREESECTION_WEAPONS_TRIGGERS, +}; + +class PhysicsTreeItemData : public wxTreeItemData { +private: + int id; + int section; + +public: + PhysicsTreeItemData(int id=-1, int sect=-1); + ~PhysicsTreeItemData(); + + int ID(void) const { return id; } + int Section(void) const { return section; } +}; + +#endif diff --git a/Physics/PhysicsView.cpp b/Physics/PhysicsView.cpp new file mode 100644 index 0000000..35eed18 --- /dev/null +++ b/Physics/PhysicsView.cpp @@ -0,0 +1,1465 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "PhysicsView.h" +#include "PhysicsTreeItemData.h" + +#include "../DefaultNames.h" + +const wxSize choiceSize(200, -1); + + +void PhysicsView::CreateAliens() +{ + aliens_appearance_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxStaticBoxSizer* appearance_sizer = new wxStaticBoxSizer(wxHORIZONTAL, main_panel, _("Appearance")); + + wxFlexGridSizer* appearance_grid_sizer = new wxFlexGridSizer(2); + appearance_grid_sizer->AddGrowableCol(0); + appearance_grid_sizer->SetHGap(10); + appearance_grid_sizer->SetVGap(4); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Graphic Collection:")), 0, wxALIGN_CENTER_VERTICAL); + alien_collection_field = new wxTextCtrl(main_panel, FIELD_ALIEN_COLLECTION); + appearance_grid_sizer->Add(alien_collection_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Color Table:")), 0, wxALIGN_CENTER_VERTICAL); + alien_color_table_field = new wxTextCtrl(main_panel, FIELD_ALIEN_COLOR_TABLE); + appearance_grid_sizer->Add(alien_color_table_field, 0, wxALIGN_CENTER_VERTICAL); + + wxStaticText* sequence_label = new wxStaticText(main_panel, wxID_ANY, _("Sequence IDs:")); +// wxFont font = sequence_label->GetFont(); +// font.SetWeight(wxFONTWEIGHT_BOLD); +// sequence_label->SetFont(font); + appearance_grid_sizer->Add(sequence_label, 0, wxALIGN_CENTER_VERTICAL); + appearance_grid_sizer->AddSpacer(30); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Hit:")), 0, wxALIGN_CENTER_VERTICAL); + alien_hit_field = new wxTextCtrl(main_panel, FIELD_ALIEN_HIT); + appearance_grid_sizer->Add(alien_hit_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Hard Dying:")), 0, wxALIGN_CENTER_VERTICAL); + alien_hard_dying_field = new wxTextCtrl(main_panel, FIELD_ALIEN_HARD_DYING); + appearance_grid_sizer->Add(alien_hard_dying_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Soft Dying:")), 0, wxALIGN_CENTER_VERTICAL); + alien_soft_dying_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SOFT_DYING); + appearance_grid_sizer->Add(alien_soft_dying_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Hard Dead:")), 0, wxALIGN_CENTER_VERTICAL); + alien_hard_dead_field = new wxTextCtrl(main_panel, FIELD_ALIEN_HARD_DEAD); + appearance_grid_sizer->Add(alien_hard_dead_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Soft Dead:")), 0, wxALIGN_CENTER_VERTICAL); + alien_soft_dead_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SOFT_DEAD); + appearance_grid_sizer->Add(alien_soft_dead_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Stationary:")), 0, wxALIGN_CENTER_VERTICAL); + alien_stationary_field = new wxTextCtrl(main_panel, FIELD_ALIEN_STATIONARY); + appearance_grid_sizer->Add(alien_stationary_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Moving:")), 0, wxALIGN_CENTER_VERTICAL); + alien_moving_field = new wxTextCtrl(main_panel, FIELD_ALIEN_MOVING); + appearance_grid_sizer->Add(alien_moving_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Teleport In:")), 0, wxALIGN_CENTER_VERTICAL); + alien_teleport_in_field = new wxTextCtrl(main_panel, FIELD_ALIEN_TELEPORT_IN); + appearance_grid_sizer->Add(alien_teleport_in_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Teleport Out:")), 0, wxALIGN_CENTER_VERTICAL); + alien_teleport_out_field = new wxTextCtrl(main_panel, FIELD_ALIEN_TELEPORT_OUT); + appearance_grid_sizer->Add(alien_teleport_out_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Melee Attack:")), 0, wxALIGN_CENTER_VERTICAL); + alien_melee_attack_shape_field = new wxTextCtrl(main_panel, FIELD_ALIEN_MELEE_ATTACK_SHAPE); + appearance_grid_sizer->Add(alien_melee_attack_shape_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ranged Attack:")), 0, wxALIGN_CENTER_VERTICAL); + alien_ranged_attack_shape_field = new wxTextCtrl(main_panel, FIELD_ALIEN_RANGED_ATTACK_SHAPE); + appearance_grid_sizer->Add(alien_ranged_attack_shape_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_sizer->Add(appearance_grid_sizer); + + aliens_appearance_sizer->Add(appearance_sizer); + aliens_appearance_sizer->AddSpacer(10); + + wxStaticBoxSizer* sounds_sizer = new wxStaticBoxSizer(wxHORIZONTAL, main_panel, _("Sounds")); + + wxFlexGridSizer* sounds_grid_sizer = new wxFlexGridSizer(2); + sounds_grid_sizer->AddGrowableCol(0); + sounds_grid_sizer->SetHGap(10); + sounds_grid_sizer->SetVGap(4); + + std::vector sound_strings = DefaultNames::Instance()->GetArray(wxT("sound")); + sound_strings.insert(sound_strings.begin(), GetName(wxT("sound"), -1)); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Activation:")), 0, wxALIGN_CENTER_VERTICAL); + alien_activation_choice = new wxChoice(main_panel, MENU_ALIEN_ACTIVATION, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_activation_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Friendly Activation:")), 0, wxALIGN_CENTER_VERTICAL); + alien_friendly_activation_choice = new wxChoice(main_panel, MENU_ALIEN_FRIENDLY_ACTIVATION, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_friendly_activation_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Clear:")), 0, wxALIGN_CENTER_VERTICAL); + alien_clear_choice = new wxChoice(main_panel, MENU_ALIEN_CLEAR, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_clear_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Kill:")), 0, wxALIGN_CENTER_VERTICAL); + alien_kill_choice = new wxChoice(main_panel, MENU_ALIEN_KILL, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_kill_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Apology:")), 0, wxALIGN_CENTER_VERTICAL); + alien_apology_choice = new wxChoice(main_panel, MENU_ALIEN_APOLOGY, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_apology_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Friendly Fire:")), 0, wxALIGN_CENTER_VERTICAL); + alien_friendly_fire_choice = new wxChoice(main_panel, MENU_ALIEN_FRIENDLY_FIRE, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_friendly_fire_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Flaming:")), 0, wxALIGN_CENTER_VERTICAL); + alien_flaming_choice = new wxChoice(main_panel, MENU_ALIEN_FLAMING, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_flaming_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Random:")), 0, wxALIGN_CENTER_VERTICAL); + alien_random_choice = new wxChoice(main_panel, MENU_ALIEN_RANDOM, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(alien_random_choice, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->AddSpacer(10); + sounds_grid_sizer->AddSpacer(10); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Random Sound Mask:")), 0, wxALIGN_CENTER_VERTICAL); + alien_random_sound_mask_field = new wxTextCtrl(main_panel, FIELD_ALIEN_RANDOM_SOUND_MASK); + sounds_grid_sizer->Add(alien_random_sound_mask_field, 0, wxALIGN_CENTER_VERTICAL); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sound Pitch:")), 0, wxALIGN_CENTER_VERTICAL); + alien_sound_pitch_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SOUND_PITCH); + sounds_grid_sizer->Add(alien_sound_pitch_field, 0, wxALIGN_CENTER_VERTICAL); + + sounds_sizer->Add(sounds_grid_sizer); + + aliens_appearance_sizer->Add(sounds_sizer); + + mainbox->Add(aliens_appearance_sizer, 5, wxALL, 10); + mainbox->Show(aliens_appearance_sizer, false); + + aliens_combat_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxFlexGridSizer* combat_grid_sizer = new wxFlexGridSizer(2); + combat_grid_sizer->SetHGap(10); + combat_grid_sizer->SetVGap(10); + + wxBoxSizer* attack_frequency_sizer = new wxBoxSizer(wxHORIZONTAL); + + attack_frequency_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Attack Frequency:")), 1, wxALIGN_CENTER_VERTICAL); + attack_frequency_sizer->AddSpacer(10); + alien_attack_frequency_field = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_FREQUENCY); + attack_frequency_sizer->Add(alien_attack_frequency_field, 0, wxALIGN_CENTER_VERTICAL); + + combat_grid_sizer->Add(attack_frequency_sizer); + combat_grid_sizer->AddSpacer(0); + + std::vector shot_strings = DefaultNames::Instance()->GetArray(wxT("shot")); + shot_strings.insert(shot_strings.begin(), GetName(wxT("shot"), -1)); + + for (int i = 0; i < 2; ++i) { + int id_offset = i * NUM_ALIEN_ATTACK_CONTROLS; + wxStaticBoxSizer* attack_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, i == 0 ? _("Melee Attack") : _("Ranged Attack")); + wxFlexGridSizer* attack_grid_sizer = new wxFlexGridSizer(2); + attack_grid_sizer->AddGrowableCol(0); + attack_grid_sizer->SetHGap(10); + attack_grid_sizer->SetVGap(4); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Type:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_type_choices[i] = new wxChoice(main_panel, MENU_ALIEN_ATTACK_TYPE + id_offset, wxDefaultPosition, choiceSize, shot_strings.size(), &shot_strings[0]); + attack_grid_sizer->Add(alien_attack_type_choices[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Repetitions:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_repetitions_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_REPETITIONS + id_offset); + attack_grid_sizer->Add(alien_attack_repetitions_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Error:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_error_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_ERROR + id_offset); + attack_grid_sizer->Add(alien_attack_error_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Range:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_range_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_RANGE + id_offset); + attack_grid_sizer->Add(alien_attack_range_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sequence ID:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_sequence_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_SEQUENCE + id_offset); + attack_grid_sizer->Add(alien_attack_sequence_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("dx:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_dx_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_DX + id_offset); + attack_grid_sizer->Add(alien_attack_dx_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("dy:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_dy_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_DY + id_offset); + attack_grid_sizer->Add(alien_attack_dy_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("dz:")), 0, wxALIGN_CENTER_VERTICAL); + alien_attack_dz_fields[i] = new wxTextCtrl(main_panel, FIELD_ALIEN_ATTACK_DZ + id_offset); + attack_grid_sizer->Add(alien_attack_dz_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + attack_sizer->Add(attack_grid_sizer, 0, wxEXPAND); + + combat_grid_sizer->Add(attack_sizer, 0, wxEXPAND); + } + + wxStaticBoxSizer* shrapnel_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Shrapnel")); + wxFlexGridSizer* shrapnel_grid_sizer = new wxFlexGridSizer(2); + shrapnel_grid_sizer->AddGrowableCol(0); + shrapnel_grid_sizer->SetHGap(10); + shrapnel_grid_sizer->SetVGap(4); + + shrapnel_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Shrapnel Radius:")), 0, wxALIGN_CENTER_VERTICAL); + alien_shrapnel_radius_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SHRAPNEL_RADIUS); + shrapnel_grid_sizer->Add(alien_shrapnel_radius_field, 0, wxALIGN_CENTER_VERTICAL); + + std::vector damage_strings = DefaultNames::Instance()->GetArray(wxT("damage")); + damage_strings.insert(damage_strings.begin(), _("None")); + + shrapnel_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Damage Type:")), 0, wxALIGN_CENTER_VERTICAL); + alien_shrapnel_damage_type_choice = new wxChoice(main_panel, MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE, wxDefaultPosition, choiceSize, damage_strings.size(), &damage_strings[0]); + shrapnel_grid_sizer->Add(alien_shrapnel_damage_type_choice, 0, wxALIGN_CENTER_VERTICAL); + + shrapnel_sizer->Add(shrapnel_grid_sizer, 0, wxEXPAND); + + alien_shrapnel_alien_damage_checkbox = new wxCheckBox(main_panel, CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE, _("Alien Damage (varies with level)")); + shrapnel_sizer->Add(alien_shrapnel_alien_damage_checkbox, 0, wxEXPAND | wxTOP, 5); + + wxFlexGridSizer* shrapnel_grid_sizer2 = new wxFlexGridSizer(2); + shrapnel_grid_sizer2->AddGrowableCol(0); + shrapnel_grid_sizer2->SetHGap(10); + shrapnel_grid_sizer2->SetVGap(4); + + // make the fields line up with the grid above + shrapnel_grid_sizer2->AddSpacer(0); + shrapnel_grid_sizer2->Add(choiceSize.GetWidth(), 0); + + shrapnel_grid_sizer2->Add(new wxStaticText(main_panel, wxID_ANY, _("Base Damage:")), 0, wxALIGN_CENTER_VERTICAL); + alien_shrapnel_base_damage_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE); + shrapnel_grid_sizer2->Add(alien_shrapnel_base_damage_field, 0, wxALIGN_CENTER_VERTICAL); + + shrapnel_grid_sizer2->Add(new wxStaticText(main_panel, wxID_ANY, _("Random Damage:")), 0, wxALIGN_CENTER_VERTICAL); + alien_shrapnel_random_damage_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE); + shrapnel_grid_sizer2->Add(alien_shrapnel_random_damage_field, 0, wxALIGN_CENTER_VERTICAL); + + shrapnel_grid_sizer2->Add(new wxStaticText(main_panel, wxID_ANY, _("Scale:")), 0, wxALIGN_CENTER_VERTICAL); + alien_shrapnel_damage_scale_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE); + shrapnel_grid_sizer2->Add(alien_shrapnel_damage_scale_field, 0, wxALIGN_CENTER_VERTICAL); + + shrapnel_sizer->Add(shrapnel_grid_sizer2, 0, wxEXPAND); + + combat_grid_sizer->Add(shrapnel_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* impact_effects_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Impact Effects (hits on monster)")); + wxFlexGridSizer* impact_effects_grid_sizer = new wxFlexGridSizer(2); + impact_effects_grid_sizer->AddGrowableCol(0); + impact_effects_grid_sizer->SetHGap(10); + impact_effects_grid_sizer->SetVGap(4); + + std::vector effect_strings = DefaultNames::Instance()->GetArray(wxT("effect")); + effect_strings.insert(effect_strings.begin(), GetName(wxT("sound"), -1)); + + impact_effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ranged:")), 0, wxALIGN_CENTER_VERTICAL); + alien_ranged_impact_effect_choice = new wxChoice(main_panel, MENU_ALIEN_RANGED_IMPACT_EFFECT, wxDefaultPosition, choiceSize, effect_strings.size(), &effect_strings[0]); + impact_effects_grid_sizer->Add(alien_ranged_impact_effect_choice, 0, wxALIGN_CENTER_VERTICAL); + + impact_effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Melee:")), 0, wxALIGN_CENTER_VERTICAL); + alien_melee_impact_effect_choice = new wxChoice(main_panel, MENU_ALIEN_MELEE_IMPACT_EFFECT, wxDefaultPosition, choiceSize, effect_strings.size(), &effect_strings[0]); + impact_effects_grid_sizer->Add(alien_melee_impact_effect_choice, 0, wxALIGN_CENTER_VERTICAL); + + impact_effects_sizer->Add(impact_effects_grid_sizer, 0, wxEXPAND); + + combat_grid_sizer->Add(impact_effects_sizer, 0, wxEXPAND); + + aliens_combat_sizer->Add(combat_grid_sizer); + + mainbox->Add(aliens_combat_sizer, 5, wxALL, 10); + mainbox->Show(aliens_combat_sizer, false); + + aliens_constants_sizer = new wxBoxSizer(wxVERTICAL); + + wxFlexGridSizer* constants_grid_sizer = new wxFlexGridSizer(2); + constants_grid_sizer->SetHGap(10); + constants_grid_sizer->SetVGap(10); + + wxFlexGridSizer* vitality_grid_sizer = new wxFlexGridSizer(2); + vitality_grid_sizer->AddGrowableCol(0); + vitality_grid_sizer->SetHGap(10); + + vitality_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Vitality:")), 0, wxALIGN_CENTER_VERTICAL); + alien_vitality_field = new wxTextCtrl(main_panel, FIELD_ALIEN_VITALITY); + vitality_grid_sizer->Add(alien_vitality_field, 0, wxALIGN_CENTER_VERTICAL); + + constants_grid_sizer->Add(vitality_grid_sizer, 0, wxEXPAND); + + wxFlexGridSizer* radius_height_sizer = new wxFlexGridSizer(2); + radius_height_sizer->AddGrowableCol(0); + radius_height_sizer->SetHGap(10); + radius_height_sizer->SetVGap(4); + + radius_height_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Radius:")), 0, wxALIGN_CENTER_VERTICAL); + alien_radius_field = new wxTextCtrl(main_panel, FIELD_ALIEN_RADIUS); + radius_height_sizer->Add(alien_radius_field, 0, wxALIGN_CENTER_VERTICAL); + + radius_height_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Height:")), 0, wxALIGN_CENTER_VERTICAL); + alien_height_field = new wxTextCtrl(main_panel, FIELD_ALIEN_HEIGHT); + radius_height_sizer->Add(alien_height_field, 0, wxALIGN_CENTER_VERTICAL); + + constants_grid_sizer->Add(radius_height_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* movement_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Movement")); + wxFlexGridSizer* movement_grid_sizer = new wxFlexGridSizer(2); + movement_grid_sizer->AddGrowableCol(0); + movement_grid_sizer->SetHGap(10); + movement_grid_sizer->SetVGap(4); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Speed:")), 0, wxALIGN_CENTER_VERTICAL); + alien_speed_field = new wxTextCtrl(main_panel, FIELD_ALIEN_SPEED); + movement_grid_sizer->Add(alien_speed_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Terminal Velocity:")), 0, wxALIGN_CENTER_VERTICAL); + alien_terminal_velocity_field = new wxTextCtrl(main_panel, FIELD_ALIEN_TERMINAL_VELOCITY); + movement_grid_sizer->Add(alien_terminal_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Gravity:")), 0, wxALIGN_CENTER_VERTICAL); + alien_gravity_field = new wxTextCtrl(main_panel, FIELD_ALIEN_GRAVITY); + movement_grid_sizer->Add(alien_gravity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->AddSpacer(10); + movement_grid_sizer->AddSpacer(10); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Min. Ledge Jump:")), 0, wxALIGN_CENTER_VERTICAL); + alien_min_ledge_jump_field = new wxTextCtrl(main_panel, FIELD_ALIEN_MIN_LEDGE_JUMP); + movement_grid_sizer->Add(alien_min_ledge_jump_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Max. Ledge Jump:")), 0, wxALIGN_CENTER_VERTICAL); + alien_max_ledge_jump_field = new wxTextCtrl(main_panel, FIELD_ALIEN_MAX_LEDGE_JUMP); + movement_grid_sizer->Add(alien_max_ledge_jump_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("External Velocity Scale:")), 0, wxALIGN_CENTER_VERTICAL); + alien_ext_velocity_scale_field = new wxTextCtrl(main_panel, FIELD_ALIEN_EXT_VELOCITY_SCALE); + movement_grid_sizer->Add(alien_ext_velocity_scale_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Hover Height:")), 0, wxALIGN_CENTER_VERTICAL); + alien_hover_height_field = new wxTextCtrl(main_panel, FIELD_ALIEN_HOVER_HEIGHT); + movement_grid_sizer->Add(alien_hover_height_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->AddSpacer(10); + movement_grid_sizer->AddSpacer(10); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Door Retry Mask:")), 0, wxALIGN_CENTER_VERTICAL); + alien_door_retry_mask_field = new wxTextCtrl(main_panel, FIELD_ALIEN_DOOR_RETRY_MASK); + movement_grid_sizer->Add(alien_door_retry_mask_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_sizer->Add(movement_grid_sizer, 0, wxEXPAND); + + constants_grid_sizer->Add(movement_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* perception_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Perception")); + wxFlexGridSizer* perception_grid_sizer = new wxFlexGridSizer(2); + perception_grid_sizer->AddGrowableCol(0); + perception_grid_sizer->SetHGap(10); + perception_grid_sizer->SetVGap(4); + + perception_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Visual Range:")), 0, wxALIGN_CENTER_VERTICAL); + alien_visual_range_field = new wxTextCtrl(main_panel, FIELD_ALIEN_VISUAL_RANGE); + perception_grid_sizer->Add(alien_visual_range_field, 0, wxALIGN_CENTER_VERTICAL); + + perception_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Dark Visual Range:")), 0, wxALIGN_CENTER_VERTICAL); + alien_dark_visual_range_field = new wxTextCtrl(main_panel, FIELD_ALIEN_DARK_VISUAL_RANGE); + perception_grid_sizer->Add(alien_dark_visual_range_field, 0, wxALIGN_CENTER_VERTICAL); + + perception_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Intelligence:")), 0, wxALIGN_CENTER_VERTICAL); + alien_intelligence_field = new wxTextCtrl(main_panel, FIELD_ALIEN_INTELLIGENCE); + perception_grid_sizer->Add(alien_intelligence_field, 0, wxALIGN_CENTER_VERTICAL); + + perception_sizer->Add(perception_grid_sizer, 0, wxEXPAND); + + constants_grid_sizer->Add(perception_sizer, 0, wxEXPAND); + + aliens_constants_sizer->Add(constants_grid_sizer); + aliens_constants_sizer->AddSpacer(10); + + wxFlexGridSizer* carrying_grid_sizer = new wxFlexGridSizer(2); + carrying_grid_sizer->AddGrowableCol(0); + carrying_grid_sizer->SetHGap(10); + carrying_grid_sizer->SetVGap(4); + + std::vector item_strings = DefaultNames::Instance()->GetArray(wxT("item")); + item_strings.insert(item_strings.begin(), _("None")); + + carrying_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Carrying Item Type:")), 0, wxALIGN_CENTER_VERTICAL); + alien_carrying_item_choice = new wxChoice(main_panel, MENU_ALIEN_CARRYING_ITEM, wxDefaultPosition, choiceSize, item_strings.size(), &item_strings[0]); + carrying_grid_sizer->Add(alien_carrying_item_choice, 0, wxALIGN_CENTER_VERTICAL); + + carrying_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Contrail Effect:")), 0, wxALIGN_CENTER_VERTICAL); + alien_contrail_effect_choice = new wxChoice(main_panel, MENU_ALIEN_CONTRAIL_EFFECT, wxDefaultPosition, choiceSize, effect_strings.size(), &effect_strings[0]); + carrying_grid_sizer->Add(alien_contrail_effect_choice, 0, wxALIGN_CENTER_VERTICAL); + + aliens_constants_sizer->Add(carrying_grid_sizer); + + mainbox->Add(aliens_constants_sizer, 5, wxALL, 10); + mainbox->Show(aliens_constants_sizer, false); + + aliens_behavior_sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* class_sizer = new wxBoxSizer(wxHORIZONTAL); + + std::vector class_strings = DefaultNames::Instance()->GetArray(wxT("class")); + + class_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Class:")), 0, wxALIGN_CENTER_VERTICAL); + alien_class_choice = new wxChoice(main_panel, MENU_ALIEN_CLASS, wxDefaultPosition, choiceSize, class_strings.size(), &class_strings[0]); + class_sizer->AddSpacer(10); + class_sizer->Add(alien_class_choice, 0, wxALIGN_CENTER_VERTICAL); + + aliens_behavior_sizer->Add(class_sizer); + + wxStaticBoxSizer* friends_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Friends")); + wxGridSizer* friends_grid_sizer = new wxGridSizer(4); + friends_grid_sizer->SetVGap(2); + + for (int i = 0; i < 16; ++i) { + alien_friends_checkboxes[i] = new wxCheckBox(main_panel, CB_ALIEN_FRIENDS + i, GetName(wxT("class"), i)); + + } + + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 4; ++row) { + friends_grid_sizer->Add(alien_friends_checkboxes[row * 4 + col], 0, wxALIGN_CENTER_VERTICAL); + } + } + + friends_sizer->Add(friends_grid_sizer, 0, wxEXPAND); + + aliens_behavior_sizer->AddSpacer(10); + aliens_behavior_sizer->Add(friends_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* enemies_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Enemies")); + wxGridSizer* enemies_grid_sizer = new wxGridSizer(4); + enemies_grid_sizer->SetVGap(2); + + for (int i = 0; i < 16; ++i) { + alien_enemies_checkboxes[i] = new wxCheckBox(main_panel, CB_ALIEN_ENEMIES + i, GetName(wxT("class"), i)); + } + + for (int col = 0; col < 4; ++col) { + for (int row = 0; row < 4; ++row) { + enemies_grid_sizer->Add(alien_enemies_checkboxes[row * 4 + col], 0, wxALIGN_CENTER_VERTICAL); + } + } + + enemies_sizer->Add(enemies_grid_sizer, 0, wxEXPAND); + + aliens_behavior_sizer->AddSpacer(10); + aliens_behavior_sizer->Add(enemies_sizer, 0, wxEXPAND); + + const wxString flags_strings[] = { + _("Flies"), + _("Is Alien"), + _("Major"), + _("Minor"), + _("Cannot Skip"), + _("Floats"), + _("Cannot Attack"), + _("Uses Sniper Ledges"), + _("Invisible"), + _("Subtly Invisible"), + _("Kamikaze"), + _("Berserker"), + _("Enlarged"), + _("Delayed Hard Death"), + _("Fires Symmetrically"), + _("Nuclear Hard Death"), + _("Can't Fire Backwards"), + _("Die in Flames"), + _("Stay with Clear Shot"), + _("Tiny"), + _("Attacks Immediately"), + _("Not Afraid of Water"), + _("Not Afraid of Sewage"), + _("Not Afraid of Lava"), + _("Not Afraid of Goo"), + _("Can Teleport Under Liquid"), + _("Chooses Weapon Randomly"), + }; + + const int flags_layout[] = { + 0, 8, 17, + 1, 9, 18, + 2, 10, 19, + 3, 11, 20, + 4, 12, 21, + 5, 13, 22, + 6, 14, 23, + 7, 15, 24, + 26, 16, 25 + }; + + wxStaticBoxSizer* flags_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Flags")); + wxGridSizer* flags_grid_sizer = new wxGridSizer(3); + flags_grid_sizer->SetVGap(2); + + for (int i = 0; i < 27; ++i) { + alien_flags_checkboxes[i] = new wxCheckBox(main_panel, CB_ALIEN_FLAGS + i, flags_strings[i]); + } + + for (int i = 0; i < 27; ++i) { + flags_grid_sizer->Add(alien_flags_checkboxes[flags_layout[i]], 0, wxALIGN_CENTER_VERTICAL); + } + + flags_sizer->Add(flags_grid_sizer, 0, wxEXPAND); + + aliens_behavior_sizer->AddSpacer(10); + aliens_behavior_sizer->Add(flags_sizer, 0, wxEXPAND); + + mainbox->Add(aliens_behavior_sizer, 5, wxALL, 10); + mainbox->Show(aliens_behavior_sizer, false); + + aliens_immunities_sizer = new wxBoxSizer(wxVERTICAL); + + wxStaticBoxSizer* immunities_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Immunities")); + wxGridSizer* immunities_grid_sizer = new wxGridSizer(4); + immunities_grid_sizer->SetVGap(2); + + for (int i = 0; i < 24; ++i) { + alien_immunities_checkboxes[i] = new wxCheckBox(main_panel, CB_ALIEN_IMMUNITIES + i, GetName(wxT("damage"), i)); + } + + for (int i = 0; i < 6; ++i) { + for (int j = 0; j < 4; ++j) { + immunities_grid_sizer->Add(alien_immunities_checkboxes[j * 6 + i], 0, wxALIGN_CENTER_VERTICAL); + } + } + + immunities_sizer->Add(immunities_grid_sizer, 0, wxEXPAND); + + aliens_immunities_sizer->Add(immunities_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* weaknesses_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Weaknesses")); + wxGridSizer* weaknesses_grid_sizer = new wxGridSizer(4); + weaknesses_grid_sizer->SetVGap(2); + + for (int i = 0; i < 24; ++i) { + alien_weaknesses_checkboxes[i] = new wxCheckBox(main_panel, CB_ALIEN_WEAKNESSES + i, GetName(wxT("damage"), i)); + } + + for (int i = 0; i < 6; ++i) { + for (int j = 0; j < 4; ++j) { + weaknesses_grid_sizer->Add(alien_weaknesses_checkboxes[j * 6 + i], 0, wxALIGN_CENTER_VERTICAL); + } + } + + weaknesses_sizer->Add(weaknesses_grid_sizer, 0, wxEXPAND); + + aliens_immunities_sizer->AddSpacer(10); + aliens_immunities_sizer->Add(weaknesses_sizer, 0, wxEXPAND); + + mainbox->Add(aliens_immunities_sizer, 5, wxALL, 10); + mainbox->Show(aliens_immunities_sizer, false); +} + +void PhysicsView::CreateEffects() +{ + effects_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxStaticBoxSizer* effects_static_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Effect")); + + wxFlexGridSizer* effects_grid_sizer = new wxFlexGridSizer(2); + effects_grid_sizer->AddGrowableCol(0); + effects_grid_sizer->SetHGap(10); + effects_grid_sizer->SetVGap(4); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Graphic collection:")), 0, wxALIGN_CENTER_VERTICAL); + eff_collection_field = new wxTextCtrl(main_panel, FIELD_EFFECT_COLLECTION); + effects_grid_sizer->Add(eff_collection_field, 0, wxALIGN_CENTER_VERTICAL); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Color table:")), 0, wxALIGN_CENTER_VERTICAL); + eff_color_table_field = new wxTextCtrl(main_panel, FIELD_EFFECT_COLOR_TABLE); + effects_grid_sizer->Add(eff_color_table_field, 0, wxALIGN_CENTER_VERTICAL); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sequence:")), 0, wxALIGN_CENTER_VERTICAL); + eff_sequence_field = new wxTextCtrl(main_panel, FIELD_EFFECT_SEQUENCE); + effects_grid_sizer->Add(eff_sequence_field, 0, wxALIGN_CENTER_VERTICAL); + + effects_grid_sizer->AddSpacer(10); + effects_grid_sizer->AddSpacer(10); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sound pitch:")), 0, wxALIGN_CENTER_VERTICAL); + eff_pitch_field = new wxTextCtrl(main_panel, FIELD_EFFECT_PITCH); + effects_grid_sizer->Add(eff_pitch_field, 0, wxALIGN_CENTER_VERTICAL); + + effects_grid_sizer->AddSpacer(10); + effects_grid_sizer->AddSpacer(10); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Delay:")), 0, wxALIGN_CENTER_VERTICAL); + eff_delay_field = new wxTextCtrl(main_panel, wxID_ANY); + eff_delay_field->Disable(); + effects_grid_sizer->Add(eff_delay_field, 0, wxALIGN_CENTER_VERTICAL); + + std::vector delay_sound_choices = DefaultNames::Instance()->GetArray(wxT("sound")); + delay_sound_choices.insert(delay_sound_choices.begin(), GetName(wxT("sound"), -1)); + + effects_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Delay sound:")), 0, wxALIGN_CENTER_VERTICAL); + eff_delay_sound_choice = new wxChoice(main_panel, MENU_EFFECT_DELAY_SOUND, wxDefaultPosition, choiceSize, delay_sound_choices.size(), &delay_sound_choices[0]); + effects_grid_sizer->Add(eff_delay_sound_choice, 0, wxALIGN_CENTER_VERTICAL); + + effects_static_sizer->Add(effects_grid_sizer); + + effects_static_sizer->AddSpacer(10); + + eff_end_when_animation_loops_checkbox = new wxCheckBox(main_panel, CB_EFFECT_END_WHEN_ANIMATION_LOOPS, _("End when animation loops")); + effects_static_sizer->Add(eff_end_when_animation_loops_checkbox); + + eff_end_when_transfer_animation_loops_checkbox = new wxCheckBox(main_panel, CB_EFFECT_END_WHEN_TRANSFER_ANIMATION_LOOPS, _("End when transfer animation loops")); + effects_static_sizer->AddSpacer(2); + effects_static_sizer->Add(eff_end_when_transfer_animation_loops_checkbox); + + eff_sound_only_checkbox = new wxCheckBox(main_panel, CB_EFFECT_SOUND_ONLY, _("Sound only")); + effects_static_sizer->AddSpacer(2); + effects_static_sizer->Add(eff_sound_only_checkbox); + + eff_media_effect_checkbox = new wxCheckBox(main_panel, CB_EFFECT_MEDIA_EFFECT, _("Media effect")); + effects_static_sizer->AddSpacer(2); + effects_static_sizer->Add(eff_media_effect_checkbox); + + effects_sizer->Add(effects_static_sizer); + + mainbox->Add(effects_sizer, 5, wxALL, 10); + mainbox->Show(effects_sizer, false); +} + +void PhysicsView::CreatePhysicsConstants() +{ + // physics constants + physics_sizer = new wxFlexGridSizer(2); + physics_sizer->SetHGap(10); + physics_sizer->SetVGap(20); + + wxStaticBoxSizer* movement_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Movement")); + wxFlexGridSizer* movement_grid_sizer = new wxFlexGridSizer(2); + + movement_grid_sizer->AddGrowableCol(0); + movement_grid_sizer->SetHGap(10); + movement_grid_sizer->SetVGap(4); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Max. forward velocity:")), 0, wxALIGN_CENTER_VERTICAL); + max_forward_velocity_field = new wxTextCtrl(main_panel, FIELD_MAX_FORWARD_VELOCITY); + movement_grid_sizer->Add(max_forward_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Max. backward velocity:")), 0, wxALIGN_CENTER_VERTICAL); + max_backward_velocity_field = new wxTextCtrl(main_panel, FIELD_MAX_BACKWARD_VELOCITY); + movement_grid_sizer->Add(max_backward_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Max. perpendicular velocity:")), 0, wxALIGN_CENTER_VERTICAL); + max_perpendicular_velocity_field = new wxTextCtrl(main_panel, FIELD_MAX_PERPENDICULAR_VELOCITY); + movement_grid_sizer->Add(max_perpendicular_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->AddSpacer(10); + movement_grid_sizer->AddSpacer(10); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Acceleration:")), 0, wxALIGN_CENTER_VERTICAL); + acceleration_field = new wxTextCtrl(main_panel, FIELD_ACCELERATION); + movement_grid_sizer->Add(acceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Deceleration:")), 0, wxALIGN_CENTER_VERTICAL); + deceleration_field = new wxTextCtrl(main_panel, FIELD_DECELERATION); + movement_grid_sizer->Add(deceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Airborne deceleration:")), 0, wxALIGN_CENTER_VERTICAL); + airborne_deceleration_field = new wxTextCtrl(main_panel, FIELD_AIRBORNE_DECELERATION); + movement_grid_sizer->Add(airborne_deceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Gravitational acceleration:")), 0, wxALIGN_CENTER_VERTICAL); + gravitational_acceleration_field = new wxTextCtrl(main_panel, FIELD_GRAVITATIONAL_ACCELERATION); + movement_grid_sizer->Add(gravitational_acceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Climbing acceleration:")), 0, wxALIGN_CENTER_VERTICAL); + climbing_acceleration_field = new wxTextCtrl(main_panel, FIELD_CLIMBING_ACCELERATION); + movement_grid_sizer->Add(climbing_acceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Terminal velocity:")), 0, wxALIGN_CENTER_VERTICAL); + terminal_velocity_field = new wxTextCtrl(main_panel, FIELD_TERMINAL_VELOCITY); + movement_grid_sizer->Add(terminal_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("External deceleration:")), 0, wxALIGN_CENTER_VERTICAL); + external_deceleration_field = new wxTextCtrl(main_panel, FIELD_EXTERNAL_DECELERATION); + movement_grid_sizer->Add(external_deceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + movement_sizer->Add(movement_grid_sizer, 0, wxEXPAND); + physics_sizer->Add(movement_sizer, 0, wxEXPAND); + + wxBoxSizer* steps_player_size_sizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* steps_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Steps")); + wxFlexGridSizer* steps_grid_sizer = new wxFlexGridSizer(2); + steps_grid_sizer->AddGrowableCol(0); + steps_grid_sizer->SetHGap(10); + steps_grid_sizer->SetVGap(4); + + steps_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Step delta:")), 0, wxALIGN_CENTER_VERTICAL); + step_delta_field = new wxTextCtrl(main_panel, FIELD_STEP_DELTA); + steps_grid_sizer->Add(step_delta_field, 0, wxALIGN_CENTER_VERTICAL); + + steps_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Step amplitude:")), 0, wxALIGN_CENTER_VERTICAL); + step_amplitude_field = new wxTextCtrl(main_panel, FIELD_STEP_AMPLITUDE); + steps_grid_sizer->Add(step_amplitude_field, 0, wxALIGN_CENTER_VERTICAL); + + steps_sizer->Add(steps_grid_sizer, 0, wxEXPAND); + + steps_player_size_sizer->Add(steps_sizer, 0, wxEXPAND); + steps_player_size_sizer->AddSpacer(10); + + wxStaticBoxSizer* size_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Player Size")); + wxFlexGridSizer* size_grid_sizer = new wxFlexGridSizer(2); + size_grid_sizer->AddGrowableCol(0); + size_grid_sizer->SetHGap(10); + size_grid_sizer->SetVGap(4); + + size_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Radius:")), 0, wxALIGN_CENTER_VERTICAL); + radius_field = new wxTextCtrl(main_panel, FIELD_RADIUS); + size_grid_sizer->Add(radius_field, 0, wxALIGN_CENTER_VERTICAL); + + size_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Height:")), 0, wxALIGN_CENTER_VERTICAL); + height_field = new wxTextCtrl(main_panel, FIELD_HEIGHT); + size_grid_sizer->Add(height_field, 0, wxALIGN_CENTER_VERTICAL); + + size_sizer->Add(size_grid_sizer, 0, wxEXPAND); + + steps_player_size_sizer->Add(size_sizer, 0, wxEXPAND); + steps_player_size_sizer->AddStretchSpacer(); + + physics_sizer->Add(steps_player_size_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* turning_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Turning/Head Movement")); + wxFlexGridSizer* turning_grid_sizer = new wxFlexGridSizer(2); + turning_grid_sizer->AddGrowableCol(0); + turning_grid_sizer->SetHGap(10); + turning_grid_sizer->SetVGap(4); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Angular acceleration:")), 0, wxALIGN_CENTER_VERTICAL); + angular_acceleration_field = new wxTextCtrl(main_panel, FIELD_ANGULAR_ACCELERATION); + turning_grid_sizer->Add(angular_acceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Angular deceleration:")), 0, wxALIGN_CENTER_VERTICAL); + angular_deceleration_field = new wxTextCtrl(main_panel, FIELD_ANGULAR_DECELERATION); + turning_grid_sizer->Add(angular_deceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Maximum angular velocity:")), 0, wxALIGN_CENTER_VERTICAL); + maximum_angular_velocity_field = new wxTextCtrl(main_panel, FIELD_MAXIMUM_ANGULAR_VELOCITY); + turning_grid_sizer->Add(maximum_angular_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Angular recentering velocity:")), 0, wxALIGN_CENTER_VERTICAL); + angular_recentering_velocity_field = new wxTextCtrl(main_panel, FIELD_ANGULAR_RECENTERING_VELOCITY); + turning_grid_sizer->Add(angular_recentering_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Head angular velocity:")), 0, wxALIGN_CENTER_VERTICAL); + head_angular_velocity_field = new wxTextCtrl(main_panel, FIELD_HEAD_ANGULAR_VELOCITY); + turning_grid_sizer->Add(head_angular_velocity_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Head angular maximum:")), 0, wxALIGN_CENTER_VERTICAL); + head_angular_maximum_field = new wxTextCtrl(main_panel, FIELD_HEAD_ANGULAR_MAXIMUM); + turning_grid_sizer->Add(head_angular_maximum_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Maximum elevation:")), 0, wxALIGN_CENTER_VERTICAL); + maximum_elevation_field = new wxTextCtrl(main_panel, FIELD_MAXIMUM_ELEVATION); + turning_grid_sizer->Add(maximum_elevation_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("External angular deceleration:")), 0, wxALIGN_CENTER_VERTICAL); + external_angular_deceleration_field = new wxTextCtrl(main_panel, FIELD_EXTERNAL_ANGULAR_DECELERATION); + turning_grid_sizer->Add(external_angular_deceleration_field, 0, wxALIGN_CENTER_VERTICAL); + + turning_sizer->Add(turning_grid_sizer, 0, wxEXPAND); + physics_sizer->Add(turning_sizer, 0); + + wxStaticBoxSizer* camera_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Heights (for camera)")); + wxFlexGridSizer* camera_grid_sizer = new wxFlexGridSizer(2); + camera_grid_sizer->AddGrowableCol(0); + camera_grid_sizer->SetHGap(10); + camera_grid_sizer->SetVGap(4); + + camera_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Dead height:")), 0, wxALIGN_CENTER_VERTICAL); + dead_height_field = new wxTextCtrl(main_panel, FIELD_DEAD_HEIGHT); + camera_grid_sizer->Add(dead_height_field, 0, wxALIGN_CENTER_VERTICAL); + + camera_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Camera height:")), 0, wxALIGN_CENTER_VERTICAL); + camera_height_field = new wxTextCtrl(main_panel, FIELD_CAMERA_HEIGHT); + camera_grid_sizer->Add(camera_height_field, 0, wxALIGN_CENTER_VERTICAL); + + camera_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Splash height:")), 0, wxALIGN_CENTER_VERTICAL); + splash_height_field = new wxTextCtrl(main_panel, FIELD_SPLASH_HEIGHT); + camera_grid_sizer->Add(splash_height_field, 0, wxALIGN_CENTER_VERTICAL); + + camera_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Half camera separation:")), 0, wxALIGN_CENTER_VERTICAL); + half_camera_separation_field = new wxTextCtrl(main_panel, FIELD_HALF_CAMERA_SEPARATION); + camera_grid_sizer->Add(half_camera_separation_field, 0, wxALIGN_CENTER_VERTICAL); + + camera_sizer->Add(camera_grid_sizer, 0, wxEXPAND); + camera_sizer->AddStretchSpacer(); + physics_sizer->Add(camera_sizer, 0); + + mainbox->Add(physics_sizer, 5, wxALL, 10); + mainbox->Show(physics_sizer, false); +} + +void PhysicsView::CreateShots() +{ + shots_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxStaticBoxSizer* shots_static_sizer = new wxStaticBoxSizer(wxHORIZONTAL, main_panel, _("Shot")); + + wxBoxSizer* column_1_sizer = new wxBoxSizer(wxVERTICAL); + + wxFlexGridSizer* shape_sizer = new wxFlexGridSizer(2); + shape_sizer->AddGrowableCol(1); + shape_sizer->SetHGap(10); + shape_sizer->SetVGap(4); + + shape_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Graphic Collection:")), 0, wxALIGN_CENTER_VERTICAL); + shots_collection_field = new wxTextCtrl(main_panel, FIELD_SHOT_COLLECTION); + shape_sizer->Add(shots_collection_field, 0, wxALIGN_CENTER_VERTICAL); + + shape_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Color Table:")), 0, wxALIGN_CENTER_VERTICAL); + shots_color_table_field = new wxTextCtrl(main_panel, FIELD_SHOT_COLOR_TABLE); + shape_sizer->Add(shots_color_table_field, 0, wxALIGN_CENTER_VERTICAL); + + shape_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sequence:")), 0, wxALIGN_CENTER_VERTICAL); + shots_sequence_field = new wxTextCtrl(main_panel, FIELD_SHOT_SEQUENCE); + shape_sizer->Add(shots_sequence_field, 0, wxALIGN_CENTER_VERTICAL); + + column_1_sizer->Add(shape_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* damage_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Damage")); + + wxFlexGridSizer* damage_grid_sizer = new wxFlexGridSizer(2); + damage_grid_sizer->AddGrowableCol(0); + damage_grid_sizer->SetHGap(10); + damage_grid_sizer->SetVGap(5); + + damage_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Damage Type:")), 0, wxALIGN_CENTER_VERTICAL); + + std::vector damage_strings = DefaultNames::Instance()->GetArray(wxT("damage")); + damage_strings.insert(damage_strings.begin(), _("None")); + + shots_damage_type_choice = new wxChoice(main_panel, MENU_SHOT_DAMAGE_TYPE, wxDefaultPosition, choiceSize, damage_strings.size(), &damage_strings[0]); + damage_grid_sizer->Add(shots_damage_type_choice, 0, wxALIGN_CENTER_VERTICAL); + + damage_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Damage Base:")), 0, wxALIGN_CENTER_VERTICAL); + shots_damage_base_field = new wxTextCtrl(main_panel, FIELD_SHOT_DAMAGE_BASE); + damage_grid_sizer->Add(shots_damage_base_field, 0, wxALIGN_CENTER_VERTICAL); + + damage_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Damage Random:")), 0, wxALIGN_CENTER_VERTICAL); + shots_damage_random_field = new wxTextCtrl(main_panel, FIELD_SHOT_DAMAGE_RANDOM); + damage_grid_sizer->Add(shots_damage_random_field, 0, wxALIGN_CENTER_VERTICAL); + + damage_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Damage Scale:")), 0, wxALIGN_CENTER_VERTICAL); + shots_damage_scale_field = new wxTextCtrl(main_panel, FIELD_SHOT_DAMAGE_SCALE); + damage_grid_sizer->Add(shots_damage_scale_field, 0, wxALIGN_CENTER_VERTICAL); + + damage_sizer->Add(damage_grid_sizer, 0, wxEXPAND); + + shots_alien_damage_checkbox = new wxCheckBox(main_panel, CB_SHOT_ALIEN_DAMAGE, _("Alien Damage (varies with level)")); + damage_sizer->Add(shots_alien_damage_checkbox, 0, wxTOP, 5); + + column_1_sizer->Add(damage_sizer, 0, wxEXPAND | wxALL, 10); + + wxFlexGridSizer* shots_grid_sizer = new wxFlexGridSizer(2); + shots_grid_sizer->AddGrowableCol(0); + shots_grid_sizer->SetHGap(10); + shots_grid_sizer->SetVGap(4); + + std::vector sound_strings = DefaultNames::Instance()->GetArray(wxT("sound")); + sound_strings.insert(sound_strings.begin(), GetName(wxT("sound"), -1)); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Flyby Sound:")), 0, wxALIGN_CENTER_VERTICAL); + shots_flyby_sound_choice = new wxChoice(main_panel, MENU_SHOT_FLYBY_SOUND, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + shots_grid_sizer->Add(shots_flyby_sound_choice, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Rebound Sound:")), 0, wxALIGN_CENTER_VERTICAL); + shots_rebound_sound_choice = new wxChoice(main_panel, MENU_SHOT_REBOUND_SOUND, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + shots_grid_sizer->Add(shots_rebound_sound_choice, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Sound Pitch:")), 0, wxALIGN_CENTER_VERTICAL); + shots_sound_pitch_field = new wxTextCtrl(main_panel, FIELD_SHOT_SOUND_PITCH); + shots_grid_sizer->Add(shots_sound_pitch_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->AddSpacer(5); + shots_grid_sizer->AddSpacer(5); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Radius:")), 0, wxALIGN_CENTER_VERTICAL); + shots_radius_field = new wxTextCtrl(main_panel, FIELD_SHOT_RADIUS); + shots_grid_sizer->Add(shots_radius_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Area of Effect:")), 0, wxALIGN_CENTER_VERTICAL); + shots_area_of_effect_field = new wxTextCtrl(main_panel, FIELD_SHOT_AREA_OF_EFFECT); + shots_grid_sizer->Add(shots_area_of_effect_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Speed:")), 0, wxALIGN_CENTER_VERTICAL); + shots_speed_field = new wxTextCtrl(main_panel, FIELD_SHOT_SPEED); + shots_grid_sizer->Add(shots_speed_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Maximum Range:")), 0, wxALIGN_CENTER_VERTICAL); + shots_range_field = new wxTextCtrl(main_panel, FIELD_SHOT_RANGE); + shots_grid_sizer->Add(shots_range_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->AddSpacer(5); + shots_grid_sizer->AddSpacer(5); + + std::vector effect_strings = DefaultNames::Instance()->GetArray(wxT("effect")); + effect_strings.insert(effect_strings.begin(), GetName(wxT("sound"), -1)); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Detonation Effect:")), 0, wxALIGN_CENTER_VERTICAL); + shots_detonation_effect_choice = new wxChoice(main_panel, MENU_SHOT_DETONATION_EFFECT, wxDefaultPosition, choiceSize, effect_strings.size(), &effect_strings[0]); + shots_grid_sizer->Add(shots_detonation_effect_choice, 0, wxALIGN_CENTER_VERTICAL); + + static const wxString media_effect_strings[] = { + _("None"), + _("Small Splash"), + _("Medium Splash"), + }; + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Media Detonation Effect:")), 0, wxALIGN_CENTER_VERTICAL); + shots_media_detonation_effect_choice = new wxChoice(main_panel, MENU_SHOT_MEDIA_DETONATION_EFFECT, wxDefaultPosition, choiceSize, 3, media_effect_strings); + shots_grid_sizer->Add(shots_media_detonation_effect_choice, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->AddSpacer(5); + shots_grid_sizer->AddSpacer(5); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Contrail:")), 0, wxALIGN_CENTER_VERTICAL); + shots_contrail_choice = new wxChoice(main_panel, MENU_SHOT_CONTRAIL, wxDefaultPosition, choiceSize, effect_strings.size(), &effect_strings[0]); + shots_grid_sizer->Add(shots_contrail_choice, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ticks between contrails:")), 0, wxALIGN_CENTER_VERTICAL); + shots_contrail_ticks_field = new wxTextCtrl(main_panel, FIELD_SHOT_CONTRAIL_TICKS); + shots_grid_sizer->Add(shots_contrail_ticks_field, 0, wxALIGN_CENTER_VERTICAL); + + shots_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Maximum contrails:")), 0, wxALIGN_CENTER_VERTICAL); + shots_maximum_contrails_field = new wxTextCtrl(main_panel, FIELD_SHOT_MAXIMUM_CONTRAILS); + shots_grid_sizer->Add(shots_maximum_contrails_field, 0, wxALIGN_CENTER_VERTICAL); + + column_1_sizer->Add(shots_grid_sizer); + + shots_static_sizer->Add(column_1_sizer, 0, wxEXPAND); + shots_static_sizer->AddSpacer(10); + + wxBoxSizer* column_2_sizer = new wxBoxSizer(wxVERTICAL); + + wxStaticBoxSizer* flags_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Flags")); + + static const wxString flags_strings[] = { + _("Guided"), + _("Stop when animation loops"), + _("Persistent"), + _("Alien"), + _("Affected by gravity"), + _("No horizontal error"), + _("No vertical error"), + _("Can toggle control panels"), + _("Positive vertical error"), + _("Melee projectile"), + _("Persistent and virulent"), + _("Usually pass transparent side"), + _("Sometimes pass transparent side"), + _("Doubly affected by gravity"), + _("Rebounds from floor"), + _("Penetrates liquids"), + _("Becomes item on detonation"), + _("Bleeding projectile"), + _("Horizontal wander"), + _("Vertical wander"), + _("Affected by half gravity"), + _("Penetrates liquid boundary (inf)") + }; + + + for (int i = 0; i < 22; ++i) { + shots_flags_checkboxes[i] = new wxCheckBox(main_panel, CB_SHOT_FLAGS + i, flags_strings[i]); + if (i > 0) { + flags_sizer->Add(shots_flags_checkboxes[i], 0, wxTOP, 2); + } else { + flags_sizer->Add(shots_flags_checkboxes[i]); + } + } + + column_2_sizer->Add(flags_sizer, 0, wxEXPAND | wxTOP | wxRIGHT | wxBOTTOM, 10); + + wxBoxSizer* media_impact_sizer = new wxBoxSizer(wxHORIZONTAL); + + media_impact_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Media impact:")), 0, wxALIGN_CENTER_VERTICAL); + media_impact_sizer->AddSpacer(10); + + std::vector shot_strings = DefaultNames::Instance()->GetArray(wxT("shot")); + shot_strings.insert(shot_strings.begin(), GetName(wxT("shot"), -1)); + + shots_media_impact_choice = new wxChoice(main_panel, MENU_SHOT_MEDIA_IMPACT, wxDefaultPosition, choiceSize, shot_strings.size(), &shot_strings[0]); + media_impact_sizer->Add(shots_media_impact_choice, 0, wxALIGN_CENTER_VERTICAL); + + column_2_sizer->Add(media_impact_sizer); + + shots_static_sizer->Add(column_2_sizer, 0, wxEXPAND); + + shots_sizer->Add(shots_static_sizer); + + mainbox->Add(shots_sizer, 5, wxALL, 10); + mainbox->Show(shots_sizer, false); +} + +void PhysicsView::CreateWeapons() +{ + weapons_definitions_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* column_1_sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* item_type_sizer = new wxBoxSizer(wxHORIZONTAL); + + std::vector item_strings = DefaultNames::Instance()->GetArray(wxT("item")); + item_strings.insert(item_strings.begin(), _("None")); + + item_type_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Item Type:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_item_type_choice = new wxChoice(main_panel, MENU_WEAPON_ITEM_TYPE, wxDefaultPosition, choiceSize, item_strings.size(), &item_strings[0]); + item_type_sizer->AddSpacer(10); + item_type_sizer->Add(weapon_item_type_choice, 0, wxALIGN_CENTER_VERTICAL); + + column_1_sizer->Add(item_type_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* appearance_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Appearance")); + wxFlexGridSizer* appearance_grid_sizer = new wxFlexGridSizer(2); + appearance_grid_sizer->AddGrowableCol(0); + appearance_grid_sizer->SetHGap(10); + appearance_grid_sizer->SetVGap(4); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Graphic Collection:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_collection_field = new wxTextCtrl(main_panel, FIELD_WEAPON_COLLECTION); + appearance_grid_sizer->Add(weapon_collection_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Color Table:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_color_table_field = new wxTextCtrl(main_panel, FIELD_WEAPON_COLOR_TABLE); + appearance_grid_sizer->Add(weapon_color_table_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Idle:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_idle_field = new wxTextCtrl(main_panel, FIELD_WEAPON_IDLE); + appearance_grid_sizer->Add(weapon_idle_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Firing:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_firing_field = new wxTextCtrl(main_panel, FIELD_WEAPON_FIRING); + appearance_grid_sizer->Add(weapon_firing_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Reloading:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_reloading_field = new wxTextCtrl(main_panel, FIELD_WEAPON_RELOADING); + appearance_grid_sizer->Add(weapon_reloading_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Charging:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_charging_field = new wxTextCtrl(main_panel, FIELD_WEAPON_CHARGING); + appearance_grid_sizer->Add(weapon_charging_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Charged:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_charged_field = new wxTextCtrl(main_panel, FIELD_WEAPON_CHARGED); + appearance_grid_sizer->Add(weapon_charged_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_grid_sizer->AddSpacer(10); + appearance_grid_sizer->AddSpacer(10); + + appearance_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Flash Intensity:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_flash_intensity_field = new wxTextCtrl(main_panel, FIELD_WEAPON_FLASH_INTENSITY); + appearance_grid_sizer->Add(weapon_flash_intensity_field, 0, wxALIGN_CENTER_VERTICAL); + + appearance_sizer->Add(appearance_grid_sizer, 0, wxEXPAND); + + column_1_sizer->AddSpacer(10); + column_1_sizer->Add(appearance_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* timing_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Timing (all in ticks)")); + wxFlexGridSizer* timing_grid_sizer = new wxFlexGridSizer(2); + timing_grid_sizer->AddGrowableCol(0); + timing_grid_sizer->SetHGap(10); + timing_grid_sizer->SetVGap(4); + + timing_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ready:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_ready_field = new wxTextCtrl(main_panel, FIELD_WEAPON_READY); + timing_grid_sizer->Add(weapon_ready_field, 0, wxALIGN_CENTER_VERTICAL); + + timing_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Await Reload:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_await_reload_field = new wxTextCtrl(main_panel, FIELD_WEAPON_AWAIT_RELOAD); + timing_grid_sizer->Add(weapon_await_reload_field, 0, wxALIGN_CENTER_VERTICAL); + + timing_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Loading:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_loading_field = new wxTextCtrl(main_panel, FIELD_WEAPON_LOADING); + timing_grid_sizer->Add(weapon_loading_field, 0, wxALIGN_CENTER_VERTICAL); + + timing_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Finish Loading:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_finish_loading_field = new wxTextCtrl(main_panel, FIELD_WEAPON_FINISH_LOADING); + timing_grid_sizer->Add(weapon_finish_loading_field, 0, wxALIGN_CENTER_VERTICAL); + + timing_grid_sizer->AddSpacer(10); + timing_grid_sizer->AddSpacer(10); + + timing_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Flash Decay:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_flash_decay_field = new wxTextCtrl(main_panel, FIELD_WEAPON_FLASH_DECAY); + timing_grid_sizer->Add(weapon_flash_decay_field, 0, wxALIGN_CENTER_VERTICAL); + + timing_sizer->Add(timing_grid_sizer, 0, wxEXPAND); + + column_1_sizer->AddSpacer(10); + column_1_sizer->Add(timing_sizer, 0, wxEXPAND); + + weapons_definitions_sizer->Add(column_1_sizer); + + wxBoxSizer* column_2_sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* weapon_class_sizer = new wxBoxSizer(wxHORIZONTAL); + + const wxString weapon_class_names[] = { + _("None"), + _("Melee"), + _("Single Function"), + _("Dual Function"), + _("Two-Fisted"), + _("Multipurpose") + }; + + weapon_class_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Weapon Class:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_class_choice = new wxChoice(main_panel, MENU_WEAPON_CLASS, wxDefaultPosition, choiceSize, 6, weapon_class_names); + weapon_class_sizer->AddSpacer(10); + weapon_class_sizer->Add(weapon_class_choice, 0, wxALIGN_CENTER_VERTICAL); + + column_2_sizer->Add(weapon_class_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* height_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Height and Idle")); + wxFlexGridSizer* height_grid_sizer = new wxFlexGridSizer(2); + height_grid_sizer->AddGrowableCol(0); + height_grid_sizer->SetHGap(10); + height_grid_sizer->SetVGap(4); + + height_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Idle Height:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_idle_height_field = new wxTextCtrl(main_panel, FIELD_WEAPON_IDLE_HEIGHT); + height_grid_sizer->Add(weapon_idle_height_field, 0, wxALIGN_CENTER_VERTICAL); + + height_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Bob Amplitude:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_bob_amplitude_field = new wxTextCtrl(main_panel, FIELD_WEAPON_BOB_AMPLITUDE); + height_grid_sizer->Add(weapon_bob_amplitude_field, 0, wxALIGN_CENTER_VERTICAL); + + height_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Kick Height:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_kick_height_field = new wxTextCtrl(main_panel, FIELD_WEAPON_KICK_HEIGHT); + height_grid_sizer->Add(weapon_kick_height_field, 0, wxALIGN_CENTER_VERTICAL); + + height_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Reload Height:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_reload_height_field = new wxTextCtrl(main_panel, FIELD_WEAPON_RELOAD_HEIGHT); + height_grid_sizer->Add(weapon_reload_height_field, 0, wxALIGN_CENTER_VERTICAL); + + height_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Idle Width:")), 0, wxALIGN_CENTER_VERTICAL); + weapon_idle_width_field = new wxTextCtrl(main_panel, FIELD_WEAPON_IDLE_WIDTH); + height_grid_sizer->Add(weapon_idle_width_field, 0, wxALIGN_CENTER_VERTICAL); + + height_sizer->Add(height_grid_sizer, 0, wxEXPAND); + + column_2_sizer->AddSpacer(10); + column_2_sizer->Add(height_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* flags_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Flags")); + static const wxString flags_strings[] = { + _("Automatic"), + _("Disappears after use"), + _("Plays instant shell casing sound"), + _("Overloads"), + _("Random ammo on pickup"), + _("Reloads in one hand"), + _("Fires out of phase"), + _("Fires under liquids"), + _("Triggers share ammo"), + _("Angular flipping on 2nd trigger") + }; + + for (int i = 0; i < 10; ++i) { + weapon_flags_checkboxes[i] = new wxCheckBox(main_panel, CB_WEAPON_FLAGS + i, flags_strings[i]); + if (i > 0) { + flags_sizer->Add(weapon_flags_checkboxes[i], 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2); + } else { + flags_sizer->Add(weapon_flags_checkboxes[i], 0, wxALIGN_CENTER_VERTICAL); + } + } + + column_2_sizer->AddSpacer(10); + column_2_sizer->Add(flags_sizer, 0, wxEXPAND); + + weapons_definitions_sizer->AddSpacer(10); + weapons_definitions_sizer->Add(column_2_sizer); + + mainbox->Add(weapons_definitions_sizer, 5, wxALL, 10); + mainbox->Show(weapons_definitions_sizer, false); + + weapons_triggers_sizer = new wxBoxSizer(wxVERTICAL); + + static const wxString trigger_names[] = { + _("Main Trigger"), + _("Secondary Trigger") + }; + + std::vector shot_strings = DefaultNames::Instance()->GetArray(wxT("shot")); + shot_strings.insert(shot_strings.begin(), _("None")); + + std::vector sound_strings = DefaultNames::Instance()->GetArray(wxT("sound")); + sound_strings.insert(sound_strings.begin(), _("None")); + + for (int i = 0; i < 2; ++i) { + int id_offset = i * NUM_TRIGGER_IDS; + wxStaticBoxSizer* static_box_sizer = new wxStaticBoxSizer(wxHORIZONTAL, main_panel, trigger_names[i]); + wxBoxSizer* column_1_sizer = new wxBoxSizer(wxVERTICAL); + + wxFlexGridSizer* left_grid_sizer = new wxFlexGridSizer(2); + left_grid_sizer->AddGrowableCol(0); + left_grid_sizer->SetHGap(10); + left_grid_sizer->SetVGap(4); + + left_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Projectile:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_projectile_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_PROJECTILE + id_offset, wxDefaultPosition, choiceSize, shot_strings.size(), &shot_strings[0]); + left_grid_sizer->Add(trigger_projectile_choices[i]); + + left_grid_sizer->AddSpacer(10); + left_grid_sizer->AddSpacer(10); + + left_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Rounds/magazine:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_rounds_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_ROUNDS + id_offset); + left_grid_sizer->Add(trigger_rounds_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + column_1_sizer->Add(left_grid_sizer, 0, wxEXPAND); + + wxStaticBoxSizer* sounds_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, _("Sounds")); + wxFlexGridSizer* sounds_grid_sizer = new wxFlexGridSizer(2); + sounds_grid_sizer->AddGrowableCol(0); + sounds_grid_sizer->SetHGap(10); + sounds_grid_sizer->SetVGap(4); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Firing:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_firing_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_FIRING + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_firing_choices[i]); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Click:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_click_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_CLICK + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_click_choices[i]); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Charging:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_charging_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_CHARGING + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_charging_choices[i]); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Shell Casing:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_shell_casing_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_SHELL_CASING + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_shell_casing_choices[i]); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Reloading:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_reloading_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_RELOADING + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_reloading_choices[i]); + + sounds_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Charged:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_charged_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_CHARGED + id_offset, wxDefaultPosition, choiceSize, sound_strings.size(), &sound_strings[0]); + sounds_grid_sizer->Add(trigger_charged_choices[i]); + + sounds_sizer->Add(sounds_grid_sizer); + + column_1_sizer->Add(sounds_sizer, 0, wxEXPAND | wxALL, 10); + + static_box_sizer->Add(column_1_sizer, 0, wxEXPAND); + + wxFlexGridSizer* right_grid_sizer = new wxFlexGridSizer(2); + right_grid_sizer->AddGrowableCol(0); + right_grid_sizer->SetHGap(10); + right_grid_sizer->SetVGap(4); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ammo Type:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_ammo_type_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_AMMO_TYPE + id_offset, wxDefaultPosition, choiceSize, item_strings.size(), &item_strings[0]); + right_grid_sizer->Add(trigger_ammo_type_choices[i]); + + right_grid_sizer->AddSpacer(10); + right_grid_sizer->AddSpacer(10); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Ticks/round:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_ticks_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_TICKS + id_offset); + right_grid_sizer->Add(trigger_ticks_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Recovery Ticks:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_recovery_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_RECOVERY + id_offset); + right_grid_sizer->Add(trigger_recovery_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Charging Ticks:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_charging_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_CHARGING + id_offset); + right_grid_sizer->Add(trigger_charging_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Recoil Magnitude:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_recoil_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_RECOIL + id_offset); + right_grid_sizer->Add(trigger_recoil_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Theta Error:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_theta_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_THETA + id_offset); + right_grid_sizer->Add(trigger_theta_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("dx:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_dx_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_DX + id_offset); + right_grid_sizer->Add(trigger_dx_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("dz:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_dz_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_DZ + id_offset); + right_grid_sizer->Add(trigger_dz_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Burst Count:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_burst_count_fields[i] = new wxTextCtrl(main_panel, FIELD_TRIGGER_BURST_COUNT + id_offset); + right_grid_sizer->Add(trigger_burst_count_fields[i], 0, wxALIGN_CENTER_VERTICAL); + + right_grid_sizer->AddSpacer(10); + right_grid_sizer->AddSpacer(10); + + static const wxString shell_casing_type_strings[] = { + _("None"), + _("Assault Rifle"), + _("Pistol Center"), + _("Pistol Left"), + _("Pistol Right"), + _("SMG") + }; + + right_grid_sizer->Add(new wxStaticText(main_panel, wxID_ANY, _("Shell casing type:")), 0, wxALIGN_CENTER_VERTICAL); + trigger_shell_casing_type_choices[i] = new wxChoice(main_panel, MENU_TRIGGER_SHELL_CASING_TYPE + id_offset, wxDefaultPosition, choiceSize, 6, shell_casing_type_strings); + right_grid_sizer->Add(trigger_shell_casing_type_choices[i]); + + static_box_sizer->AddSpacer(20); + static_box_sizer->Add(right_grid_sizer, 0, wxEXPAND); + + if (i == 1) { + weapons_triggers_sizer->AddSpacer(10); + } + + weapons_triggers_sizer->Add(static_box_sizer); + } + + mainbox->Add(weapons_triggers_sizer, 5, wxALL, 10); + mainbox->Show(weapons_triggers_sizer, false); +} + +bool PhysicsView::OnCreate(wxDocument* doc, long flags) +{ + wxString frameTitle = wxT("ShapeFusion : Physics : "); + frameTitle.Append(doc->GetFilename()); + + mFrame = wxGetApp().CreateChildFrame(doc, this, frameTitle, wxDefaultPosition, wxDefaultSize); + + mainbox = new wxBoxSizer(wxHORIZONTAL); + main_panel = new wxPanel(mFrame); + main_panel->Show(); + tree = new wxTreeCtrl(main_panel, -1, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT); + tree->DeleteAllItems(); + wxTreeItemId treeroot = tree->AddRoot(doc->GetFilename()); + mainbox->Add(tree, 2, wxEXPAND); + + // empty space + dummy_sizer = new wxBoxSizer(wxVERTICAL); + wxPanel* dummy_panel = new wxPanel(main_panel); + dummy_sizer->Add(dummy_panel, 1, wxEXPAND); + mainbox->Add(dummy_sizer, 5); + + CreateAliens(); + CreateEffects(); + CreatePhysicsConstants(); + CreateShots(); + CreateWeapons(); + + mainbox->Show(dummy_sizer, false); + mainbox->Show(weapons_triggers_sizer, true); + + mainbox->Layout(); + main_panel->SetSizer(mainbox); + mainbox->SetSizeHints(mFrame); + mainbox->Fit(mFrame); + + menubar = mFrame->GetMenuBar(); + + mainbox->Show(dummy_sizer, true); + mainbox->Show(weapons_triggers_sizer, false); + + // because we changed size + mFrame->Centre(wxBOTH); + + mFrame->Show(true); + Activate(true); + + return true; +} + +void PhysicsView::OnUpdate(wxView*, wxObject*) +{ + wxTreeItemId aliens = tree->AppendItem(tree->GetRootItem(), _("Aliens"), -1, -1, new PhysicsTreeItemData()); + unsigned int monster_count = static_cast(GetDocument())->MonsterCount(); + for (unsigned int i = 0; i < monster_count; ++i) { + wxTreeItemId alien = tree->AppendItem(aliens, GetName(wxT("alien"), i), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS)); + + tree->AppendItem(alien, _("Appearance and Sounds"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS_APPEARANCE)); + tree->AppendItem(alien, _("Combat Settings"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS_COMBAT)); + tree->AppendItem(alien, _("Physical Constants"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS_CONSTANTS)); + tree->AppendItem(alien, _("Behavior Settings"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS_BEHAVIOR)); + tree->AppendItem(alien, _("Immunities and Weaknesses"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_MONSTERS_IMMUNITIES)); + } + + wxTreeItemId effects = tree->AppendItem(tree->GetRootItem(), _("Effects"), -1, -1, new PhysicsTreeItemData()); + unsigned int effect_count = static_cast(GetDocument())->EffectCount(); + for (unsigned int i = 0; i < effect_count; ++i) { + tree->AppendItem(effects, GetName(wxT("effect"), i), -1, -1, new PhysicsTreeItemData(i, TREESECTION_EFFECTS)); + } + + wxTreeItemId shots = tree->AppendItem(tree->GetRootItem(), _("Shots"), -1, -1, new PhysicsTreeItemData()); + unsigned int projectile_count = static_cast(GetDocument())->ProjectileCount(); + for (unsigned int i = 0; i < projectile_count; ++i) { + tree->AppendItem(shots, GetName(wxT("shot"), i), -1 ,-1, new PhysicsTreeItemData(i, TREESECTION_PROJECTILES)); + } + + wxTreeItemId physics = tree->AppendItem(tree->GetRootItem(), _("Physics"), -1, -1, new PhysicsTreeItemData()); + tree->AppendItem(physics, _("Walking"), -1, -1, new PhysicsTreeItemData(0, TREESECTION_PHYSICS)); + tree->AppendItem(physics, _("Running"), -1, -1, new PhysicsTreeItemData(1, TREESECTION_PHYSICS)); + + wxTreeItemId weapons = tree->AppendItem(tree->GetRootItem(), _("Weapons"), -1, -1, new PhysicsTreeItemData()); + unsigned int weapon_count = static_cast(GetDocument())->WeaponCount(); + for (unsigned i = 0; i < weapon_count; ++i) { + wxTreeItemId weapon = tree->AppendItem(weapons, GetName(wxT("weapon"), i), -1, -1, new PhysicsTreeItemData(i, TREESECTION_WEAPONS)); + + tree->AppendItem(weapon, _("Weapon Definition"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_WEAPONS_SETTINGS)); + tree->AppendItem(weapon, _("Trigger Settings"), -1, -1, new PhysicsTreeItemData(i, TREESECTION_WEAPONS_TRIGGERS)); + } +} + +void PhysicsView::OnDraw(wxDC* dc) +{ +} + +bool PhysicsView::OnClose(bool deleteWindow) +{ + if (!GetDocument()->Close()) + return false; + Activate(false); + if (deleteWindow) { + delete mFrame; + return true; + } + return true; +} + diff --git a/Physics/PhysicsView.h b/Physics/PhysicsView.h new file mode 100644 index 0000000..d772d7a --- /dev/null +++ b/Physics/PhysicsView.h @@ -0,0 +1,515 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __PHYSICSVIEW_H__ +#define __PHYSICSVIEW_H__ + +#include "wx/docview.h" +#include "wx/treectrl.h" +#include "PhysicsDocument.h" +#include "../ShapeFusionApp.h" + +class PhysicsView : public wxView +{ + DECLARE_DYNAMIC_CLASS(PhysicsView) + +private: + enum { + FIELD_ALIEN_COLLECTION, + FIELD_ALIEN_COLOR_TABLE, + FIELD_ALIEN_HIT, + FIELD_ALIEN_HARD_DYING, + FIELD_ALIEN_SOFT_DYING, + FIELD_ALIEN_HARD_DEAD, + FIELD_ALIEN_SOFT_DEAD, + FIELD_ALIEN_STATIONARY, + FIELD_ALIEN_MOVING, + FIELD_ALIEN_TELEPORT_IN, + FIELD_ALIEN_TELEPORT_OUT, + FIELD_ALIEN_MELEE_ATTACK_SHAPE, + FIELD_ALIEN_RANGED_ATTACK_SHAPE, + + MENU_ALIEN_ACTIVATION, + MENU_ALIEN_FRIENDLY_ACTIVATION, + MENU_ALIEN_CLEAR, + MENU_ALIEN_KILL, + MENU_ALIEN_APOLOGY, + MENU_ALIEN_FRIENDLY_FIRE, + MENU_ALIEN_FLAMING, + MENU_ALIEN_RANDOM, + + FIELD_ALIEN_RANDOM_SOUND_MASK, + FIELD_ALIEN_SOUND_PITCH, + + FIELD_ALIEN_ATTACK_FREQUENCY, + + MENU_ALIEN_ATTACK_TYPE, + FIELD_ALIEN_ATTACK_REPETITIONS, + FIELD_ALIEN_ATTACK_ERROR, + FIELD_ALIEN_ATTACK_RANGE, + FIELD_ALIEN_ATTACK_SEQUENCE, + FIELD_ALIEN_ATTACK_DX, + FIELD_ALIEN_ATTACK_DY, + FIELD_ALIEN_ATTACK_DZ, + NUM_ALIEN_ATTACK_CONTROLS = 8, + + FIELD_ALIEN_SHRAPNEL_RADIUS = MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS * 2, + MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE, + FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE, + FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE, + FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE, + CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE, + + MENU_ALIEN_RANGED_IMPACT_EFFECT, + MENU_ALIEN_MELEE_IMPACT_EFFECT, + + FIELD_ALIEN_VITALITY, + FIELD_ALIEN_RADIUS, + FIELD_ALIEN_HEIGHT, + + FIELD_ALIEN_SPEED, + FIELD_ALIEN_TERMINAL_VELOCITY, + FIELD_ALIEN_GRAVITY, + + FIELD_ALIEN_MIN_LEDGE_JUMP, + FIELD_ALIEN_MAX_LEDGE_JUMP, + FIELD_ALIEN_EXT_VELOCITY_SCALE, + FIELD_ALIEN_HOVER_HEIGHT, + FIELD_ALIEN_DOOR_RETRY_MASK, + + FIELD_ALIEN_VISUAL_RANGE, + FIELD_ALIEN_DARK_VISUAL_RANGE, + FIELD_ALIEN_INTELLIGENCE, + + MENU_ALIEN_CARRYING_ITEM, + MENU_ALIEN_CONTRAIL_EFFECT, + + MENU_ALIEN_CLASS, + CB_ALIEN_FRIENDS, + CB_ALIEN_ENEMIES = CB_ALIEN_FRIENDS + 16, + CB_ALIEN_FLAGS = CB_ALIEN_ENEMIES + 16, + CB_ALIEN_IMMUNITIES = CB_ALIEN_FLAGS + 27, + CB_ALIEN_WEAKNESSES = CB_ALIEN_IMMUNITIES + 24, + + FIELD_EFFECT_COLLECTION = CB_ALIEN_WEAKNESSES + 24, + FIELD_EFFECT_COLOR_TABLE, + FIELD_EFFECT_SEQUENCE, + FIELD_EFFECT_PITCH, + MENU_EFFECT_DELAY_SOUND, + CB_EFFECT_END_WHEN_ANIMATION_LOOPS, + CB_EFFECT_END_WHEN_TRANSFER_ANIMATION_LOOPS, + CB_EFFECT_SOUND_ONLY, + CB_EFFECT_MEDIA_EFFECT, + + CB_SHOT_FLAGS, + CB_SHOT_ALIEN_DAMAGE = CB_SHOT_FLAGS + 22, + + FIELD_SHOT_COLLECTION, + FIELD_SHOT_COLOR_TABLE, + FIELD_SHOT_SEQUENCE, + FIELD_SHOT_DAMAGE_BASE, + FIELD_SHOT_DAMAGE_RANDOM, + FIELD_SHOT_RADIUS, + FIELD_SHOT_AREA_OF_EFFECT, + FIELD_SHOT_SPEED, + FIELD_SHOT_RANGE, + FIELD_SHOT_CONTRAIL_TICKS, + FIELD_SHOT_MAXIMUM_CONTRAILS, + + FIELD_SHOT_DAMAGE_SCALE, + FIELD_SHOT_SOUND_PITCH, + + MENU_SHOT_DAMAGE_TYPE, + MENU_SHOT_FLYBY_SOUND, + MENU_SHOT_REBOUND_SOUND, + MENU_SHOT_DETONATION_EFFECT, + MENU_SHOT_MEDIA_DETONATION_EFFECT, + MENU_SHOT_CONTRAIL, + MENU_SHOT_MEDIA_IMPACT, + + FIELD_MAX_FORWARD_VELOCITY, + FIELD_MAX_BACKWARD_VELOCITY, + FIELD_MAX_PERPENDICULAR_VELOCITY, + + FIELD_ACCELERATION, + FIELD_DECELERATION, + FIELD_AIRBORNE_DECELERATION, + FIELD_GRAVITATIONAL_ACCELERATION, + FIELD_CLIMBING_ACCELERATION, + FIELD_TERMINAL_VELOCITY, + FIELD_EXTERNAL_DECELERATION, + + FIELD_STEP_DELTA, + FIELD_STEP_AMPLITUDE, + + FIELD_RADIUS, + FIELD_HEIGHT, + + FIELD_ANGULAR_ACCELERATION, + FIELD_ANGULAR_DECELERATION, + FIELD_MAXIMUM_ANGULAR_VELOCITY, + FIELD_ANGULAR_RECENTERING_VELOCITY, + FIELD_HEAD_ANGULAR_VELOCITY, + FIELD_HEAD_ANGULAR_MAXIMUM, + FIELD_MAXIMUM_ELEVATION, + FIELD_EXTERNAL_ANGULAR_DECELERATION, + + FIELD_DEAD_HEIGHT, + FIELD_CAMERA_HEIGHT, + FIELD_SPLASH_HEIGHT, + FIELD_HALF_CAMERA_SEPARATION, + + CB_WEAPON_FLAGS, + + FIELD_WEAPON_COLLECTION = CB_WEAPON_FLAGS + 10, + FIELD_WEAPON_COLOR_TABLE, + FIELD_WEAPON_IDLE, + FIELD_WEAPON_FIRING, + FIELD_WEAPON_RELOADING, + FIELD_WEAPON_CHARGING, + FIELD_WEAPON_CHARGED, + FIELD_WEAPON_READY, + FIELD_WEAPON_AWAIT_RELOAD, + FIELD_WEAPON_LOADING, + FIELD_WEAPON_FINISH_LOADING, + FIELD_WEAPON_FLASH_DECAY, + + FIELD_WEAPON_FLASH_INTENSITY, + FIELD_WEAPON_IDLE_HEIGHT, + FIELD_WEAPON_BOB_AMPLITUDE, + FIELD_WEAPON_KICK_HEIGHT, + FIELD_WEAPON_RELOAD_HEIGHT, + FIELD_WEAPON_IDLE_WIDTH, + + MENU_WEAPON_ITEM_TYPE, + MENU_WEAPON_CLASS, + + FIELD_TRIGGER_ROUNDS, + FIELD_TRIGGER_TICKS, + FIELD_TRIGGER_RECOVERY, + FIELD_TRIGGER_CHARGING, + FIELD_TRIGGER_RECOIL, + FIELD_TRIGGER_THETA, + FIELD_TRIGGER_DX, + FIELD_TRIGGER_DZ, + FIELD_TRIGGER_BURST_COUNT, + MENU_TRIGGER_PROJECTILE, + MENU_TRIGGER_AMMO_TYPE, + MENU_TRIGGER_FIRING, + MENU_TRIGGER_CLICK, + MENU_TRIGGER_CHARGING, + MENU_TRIGGER_SHELL_CASING, + MENU_TRIGGER_RELOADING, + MENU_TRIGGER_CHARGED, + MENU_TRIGGER_SHELL_CASING_TYPE, + NUM_TRIGGER_IDS = 18, + LAST_TRIGGER_ID = MENU_TRIGGER_SHELL_CASING_TYPE + NUM_TRIGGER_IDS, + }; + + wxBoxSizer* mainbox; + wxPanel* main_panel; + wxMenuBar* menubar; + wxTreeCtrl* tree; + wxBoxSizer* dummy_sizer; + + wxBoxSizer* aliens_appearance_sizer; + + wxTextCtrl* alien_collection_field; + wxTextCtrl* alien_color_table_field; + wxTextCtrl* alien_hit_field; + wxTextCtrl* alien_hard_dying_field; + wxTextCtrl* alien_soft_dying_field; + wxTextCtrl* alien_hard_dead_field; + wxTextCtrl* alien_soft_dead_field; + wxTextCtrl* alien_stationary_field; + wxTextCtrl* alien_moving_field; + wxTextCtrl* alien_teleport_in_field; + wxTextCtrl* alien_teleport_out_field; + wxTextCtrl* alien_melee_attack_shape_field; + wxTextCtrl* alien_ranged_attack_shape_field; + + wxChoice* alien_activation_choice; + wxChoice* alien_friendly_activation_choice; + wxChoice* alien_clear_choice; + wxChoice* alien_kill_choice; + wxChoice* alien_apology_choice; + wxChoice* alien_friendly_fire_choice; + wxChoice* alien_flaming_choice; + wxChoice* alien_random_choice; + + wxTextCtrl* alien_random_sound_mask_field; + wxTextCtrl* alien_sound_pitch_field; + + wxBoxSizer* aliens_combat_sizer; + + wxTextCtrl* alien_attack_frequency_field; + + wxChoice* alien_attack_type_choices[2]; + wxTextCtrl* alien_attack_repetitions_fields[2]; + wxTextCtrl* alien_attack_error_fields[2]; + wxTextCtrl* alien_attack_range_fields[2]; + wxTextCtrl* alien_attack_sequence_fields[2]; + wxTextCtrl* alien_attack_dx_fields[2]; + wxTextCtrl* alien_attack_dy_fields[2]; + wxTextCtrl* alien_attack_dz_fields[2]; + + wxTextCtrl* alien_shrapnel_radius_field; + wxChoice* alien_shrapnel_damage_type_choice; + wxTextCtrl* alien_shrapnel_base_damage_field; + wxTextCtrl* alien_shrapnel_random_damage_field; + wxTextCtrl* alien_shrapnel_damage_scale_field; + wxCheckBox* alien_shrapnel_alien_damage_checkbox; + + wxChoice* alien_ranged_impact_effect_choice; + wxChoice* alien_melee_impact_effect_choice; + + wxBoxSizer* aliens_constants_sizer; + + wxTextCtrl* alien_vitality_field; + wxTextCtrl* alien_radius_field; + wxTextCtrl* alien_height_field; + + wxTextCtrl* alien_speed_field; + wxTextCtrl* alien_terminal_velocity_field; + wxTextCtrl* alien_gravity_field; + + wxTextCtrl* alien_min_ledge_jump_field; + wxTextCtrl* alien_max_ledge_jump_field; + wxTextCtrl* alien_ext_velocity_scale_field; + wxTextCtrl* alien_hover_height_field; + wxTextCtrl* alien_door_retry_mask_field; + + wxTextCtrl* alien_visual_range_field; + wxTextCtrl* alien_dark_visual_range_field; + wxTextCtrl* alien_intelligence_field; + + wxChoice* alien_carrying_item_choice; + wxChoice* alien_contrail_effect_choice; + + wxBoxSizer* aliens_behavior_sizer; + + wxChoice* alien_class_choice; + + wxCheckBox* alien_friends_checkboxes[16]; + wxCheckBox* alien_enemies_checkboxes[16]; + wxCheckBox* alien_flags_checkboxes[27]; + + wxBoxSizer* aliens_immunities_sizer; + + wxCheckBox* alien_immunities_checkboxes[24]; + wxCheckBox* alien_weaknesses_checkboxes[24]; + + wxBoxSizer* effects_sizer; + + wxTextCtrl* eff_collection_field; + wxTextCtrl* eff_color_table_field; + wxTextCtrl* eff_sequence_field; + wxTextCtrl* eff_pitch_field; + + wxTextCtrl* eff_delay_field; + + wxChoice* eff_delay_sound_choice; + + wxCheckBox* eff_end_when_animation_loops_checkbox; + wxCheckBox* eff_end_when_transfer_animation_loops_checkbox; + wxCheckBox* eff_sound_only_checkbox; + wxCheckBox* eff_media_effect_checkbox; + + wxFlexGridSizer* physics_sizer; + + wxTextCtrl* max_forward_velocity_field; + wxTextCtrl* max_backward_velocity_field; + wxTextCtrl* max_perpendicular_velocity_field; + + wxTextCtrl* acceleration_field; + wxTextCtrl* deceleration_field; + wxTextCtrl* airborne_deceleration_field; + wxTextCtrl* gravitational_acceleration_field; + wxTextCtrl* climbing_acceleration_field; + wxTextCtrl* terminal_velocity_field; + wxTextCtrl* external_deceleration_field; + + wxTextCtrl* step_delta_field; + wxTextCtrl* step_amplitude_field; + + wxTextCtrl* radius_field; + wxTextCtrl* height_field; + + wxTextCtrl* angular_acceleration_field; + wxTextCtrl* angular_deceleration_field; + wxTextCtrl* maximum_angular_velocity_field; + wxTextCtrl* angular_recentering_velocity_field; + wxTextCtrl* head_angular_velocity_field; + wxTextCtrl* head_angular_maximum_field; + wxTextCtrl* maximum_elevation_field; + wxTextCtrl* external_angular_deceleration_field; + + wxTextCtrl* dead_height_field; + wxTextCtrl* camera_height_field; + wxTextCtrl* splash_height_field; + wxTextCtrl* half_camera_separation_field; + + wxBoxSizer* shots_sizer; + + wxTextCtrl* shots_collection_field; + wxTextCtrl* shots_color_table_field; + wxTextCtrl* shots_sequence_field; + + wxChoice* shots_damage_type_choice; + wxTextCtrl* shots_damage_base_field; + wxTextCtrl* shots_damage_random_field; + wxTextCtrl* shots_damage_scale_field; + wxCheckBox* shots_alien_damage_checkbox; + + wxChoice* shots_flyby_sound_choice; + wxChoice* shots_rebound_sound_choice; + wxTextCtrl* shots_sound_pitch_field; + wxTextCtrl* shots_radius_field; + wxTextCtrl* shots_area_of_effect_field; + wxTextCtrl* shots_speed_field; + wxTextCtrl* shots_range_field; + wxChoice* shots_detonation_effect_choice; + wxChoice* shots_media_detonation_effect_choice; + wxChoice* shots_contrail_choice; + wxTextCtrl* shots_contrail_ticks_field; + wxTextCtrl* shots_maximum_contrails_field; + + wxCheckBox* shots_flags_checkboxes[22]; + + wxChoice* shots_media_impact_choice; + + wxBoxSizer* weapons_definitions_sizer; + + wxChoice* weapon_item_type_choice; + + wxTextCtrl* weapon_collection_field; + wxTextCtrl* weapon_color_table_field; + wxTextCtrl* weapon_idle_field; + wxTextCtrl* weapon_firing_field; + wxTextCtrl* weapon_reloading_field; + wxTextCtrl* weapon_charging_field; + wxTextCtrl* weapon_charged_field; + wxTextCtrl* weapon_flash_intensity_field; + + wxTextCtrl* weapon_ready_field; + wxTextCtrl* weapon_await_reload_field; + wxTextCtrl* weapon_loading_field; + wxTextCtrl* weapon_finish_loading_field; + wxTextCtrl* weapon_flash_decay_field; + + wxChoice* weapon_class_choice; + + wxTextCtrl* weapon_idle_height_field; + wxTextCtrl* weapon_bob_amplitude_field; + wxTextCtrl* weapon_kick_height_field; + wxTextCtrl* weapon_reload_height_field; + wxTextCtrl* weapon_idle_width_field; + + wxCheckBox* weapon_flags_checkboxes[10]; + + wxBoxSizer* weapons_triggers_sizer; + + wxChoice* trigger_projectile_choices[2]; + wxTextCtrl* trigger_rounds_fields[2]; + wxChoice* trigger_ammo_type_choices[2]; + + wxChoice* trigger_firing_choices[2]; + wxChoice* trigger_click_choices[2]; + wxChoice* trigger_charging_choices[2]; + wxChoice* trigger_shell_casing_choices[2]; + wxChoice* trigger_reloading_choices[2]; + wxChoice* trigger_charged_choices[2]; + + wxTextCtrl* trigger_ticks_fields[2]; + wxTextCtrl* trigger_recovery_fields[2]; + wxTextCtrl* trigger_charging_fields[2]; + wxTextCtrl* trigger_recoil_fields[2]; + wxTextCtrl* trigger_theta_fields[2]; + wxTextCtrl* trigger_dx_fields[2]; + wxTextCtrl* trigger_dz_fields[2]; + wxTextCtrl* trigger_burst_count_fields[2]; + + wxChoice* trigger_shell_casing_type_choices[2]; + +protected: + DECLARE_EVENT_TABLE(); + +public: + PhysicsView() { } + ~PhysicsView(){ } + + bool OnCreate(wxDocument* doc, long flags); + void OnDraw(wxDC* dc); + void OnUpdate(wxView* sender, wxObject* hint = (wxObject *) NULL); + bool OnClose(bool deletewindow = false); + + // control callbacks + void OnTreeSelect(wxTreeEvent& e); + +private: + void CreateAliens(); + void CreateEffects(); + void CreatePhysicsConstants(); + void CreateShots(); + void CreateWeapons(); + + void OnSelectAlienAppearance(int index); + void OnSelectAlienCombat(int index); + void OnSelectAlienConstants(int index); + void OnSelectAlienBehavior(int index); + void OnSelectAlienImmunities(int index); + void OnSelectPhysicsConstants(int index); + void OnSelectEffect(int index); + void OnSelectShot(int index); + void OnSelectWeaponDefinition(int index); + void OnSelectWeaponTriggers(int index); + + short GetSelection(); // index of current tree selection + + void MenuEditCopy(wxCommandEvent&); + void MenuEditPaste(wxCommandEvent&); + + void EditAlienCheckboxes(wxCommandEvent& e); + void EditAlienDoubles(wxCommandEvent& e); + void EditAlienFields(wxCommandEvent& e); + void EditAlienMenus(wxCommandEvent& e); + + void EditEffectCheckboxes(wxCommandEvent& e); + void EditEffectFields(wxCommandEvent& e); + void EditEffectDoubles(wxCommandEvent& e); + void EditEffectMenus(wxCommandEvent& e); + + void EditShotCheckboxes(wxCommandEvent& e); + void EditShotFields(wxCommandEvent& e); + void EditShotDoubles(wxCommandEvent& e); + void EditShotMenus(wxCommandEvent& e); + + void EditPhysicsConstants(wxCommandEvent& e); + + void EditWeaponCheckboxes(wxCommandEvent& e); + void EditWeaponFields(wxCommandEvent& e); + void EditWeaponDoubles(wxCommandEvent& e); + void EditWeaponMenus(wxCommandEvent& e); + + void EditTriggerFields(wxCommandEvent& e); + void EditTriggerMenus(wxCommandEvent& e); + + wxFrame* mFrame; +}; + +#endif diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..86ba6c3 --- /dev/null +++ b/README.txt @@ -0,0 +1,218 @@ +ShapeFusion 0.5 +http://shapefusion.sourceforge.net + +An editor for Marathon II, Marathon Infinity and AlephOne scenarios + +Copyright 2000-2008 Tito Dal Canton and Etienne Samson + + +What is ShapeFusion? +-------------------- +ShapeFusion is a scenario editor for the AlephOne game engine, also +compatible with Bungie's original Marathon II and Marathon Infinity engines. +An AlephOne scenario is made of several files; ShapeFusion is devoted to +editing the "Shapes" file, which stores most of the scenario graphics and +animation data. It's *not* a tool for editing maps. In case you ever used +Bungie tools for editing Marathon scenarios, it's enough to say that +ShapeFusion is meant as a replacement for Anvil, or better for its Shapes +editor. Such a replacement is mainly needed because Anvil is proprietary, +non-free and Mac-only software, which makes it very difficult to use on +modern platforms. Thanks to Etienne Samson, since version 0.4 ShapeFusion +can open Sounds files too; the Sounds editor is in progress and I hope it will +reach the level of the Shapes counterpart soon. + +As for the license, ShapeFusion is free software, released under the terms of +the GNU General Public License. For more information see the COPYING file +that comes with ShapeFusion. + +Supported platforms +------------------- +ShapeFusion is being developed on Linux and continuously tested on Linux, +MacOS X and Windows. Thanks to wxWidgets it should compile and work on other +systems too, but I've never tried it. ShapeFusion could *in theory* compile +and work also on MacOS Classic, but I have no plans on this side. If you build +ShapeFusion on systems different from Linux, MacOS X and Windows, please let +me know (screenshots and binary builds are appreciated!). + +Building +-------- +You'll need wxWidgets (at least version 2.8.x) to compile ShapeFusion. + +On Linux systems you can test the presence of wxWidgets by running the command +'wx-config --version'. If that command is available and gives you the right +version, everything should work; otherwise install wxWidgets following your +Linux distribution rules. To compile ShapeFusion, just run the following inside +the source directory: + + ./configure + make + +When compilation is complete, simply run the 'shapefusion' +executable (you can put it anywhere in your PATH). I finally suggest you place +the attached DefaultNames.txt file in the /usr/local/share/shapefusion +directory, so that collections and sounds will get Infinity-like names. + +On MacOS X you should be able to use the provided Xcode project +(ShapeFusion.xcodeproj). You'll need both the MacOS X developer tools and +wxWidgets (which will take some time to build). Once in the ShapeFusion +Xcode project, before building you must change the WX_SRC_ROOT variable to +point to your wxWidgets source directory. Note that MacOS X binary builds are +released together with each source release: they should work out-of-the-box +without the need to install anything else. In case you're wondering why they +are so large in size, it is because they carry the whole wxWidgets library +together with ShapeFusion itself. + +Overview of the Shapes editor window +------------------------------------ +When you open a Shapes file, the window shows its collection slots on the left. +In standard Marathon Shapes there are always 32 of them; however, ShapeFusion +tries to be flexible and can open "extended" Shapes files with more collections, +like Damage Inc ones. Collection names are read from the DefaultNames.txt file +if it is available, otherwise they are set to simple numbers. Each collection +slot can be opened revealing two sub-slots, the 8 bit and true color versions. +They represent two independent versions of the same collection: the first will +be used if the game is played on low-color displays, the second is for modern +high-color displays (including the OpenGL mode in AlephOne). Each sub-slot can +finally be opened to reveal its real content: bitmaps, color tables, frames and +sequences. The contrast with Anvil is clear. Anvil tries to obfuscate some +aspects of the Shapes file organization, but I feel that this creates a lot of +confusion in the user. In my opinion, it makes more sense to treat Shapes files +as they really are: archives of collections. The ShapeFusion window tries to +reflect this idea. + +Bitmaps, color tables and frames are displayed as lists of preview thumbnails. +Selecting one of them will pop up an edit panel for that item. Sequences are +listed by their name since they can't be easily represented with thumbnails; +however, selecting a sequence will pop up an edit panel like for other items. + +The logic behind ShapeFusion is that each collection is made of four sets of +entities: color tables, bitmaps, frames and sequences. If you follow this +order, entities coming after reference entities coming before: a sequence +references a set of frames, a frame references a bitmap, a bitmap naturally +references a color table since it's indexed. So editing a sequence involves +picking frames from the collection frame set, and editing a frame involves +selecting a bitmap from the collection bitmap set. Get it? ;-) Of course you +don't have to follow this flow, especially if you are only adjusting some +settings. + +The View menu contains display settings such as thumbnail size. Nothing here +affects what's inside the Shapes file. + +You may edit the DefaultNames.txt file at your will to provide collection and +sound names that are more suited to your scenario. The syntax should be pretty +self-explanatory. Under Linux/Unix this file should go into +/usr/local/share/shapefusion; under MacOS X it should be embedded into the +application package (Contents/Resources); under Windows it should sit next to +the ShapeFusion executable. + +Overview of the Sounds editor window +------------------------------------ +TODO + +Notes +----- +Please be careful when editing your scenario with ShapeFusion. We had no big +problems so far, but it's still under development and it may corrupt your +files, so be sure to keep backup copies. You should not use versions before +0.3, as they are affected by a bug regarding frames minimum light intensity +value. If you think your files got corrupted by ShapeFusion, please let us +know what happened. + +Object indexes start from 0, not 1. So if you have 12 bitmaps, the first is +bitmap 0 (not 1) and the last is bitmap 11 (not 12). + +Bitmaps are exported as 8-bit Windows bitmap (.bmp) files. They get the color +table that is currently used for viewing, as selected in the View menu. + +When you import a bitmap, ShapeFusion tries to map its colors to the collection +color table as best as it can. Although the algorithm often yields good results, +you can help it a lot by converting the bitmap to indexed before (using +PhotoShop or Gimp, for example) so that it contains just colors belonging to +the collection color table. + +In ShapeFusion, a frame can be referenced by many sequences. This may sound +strange at first, but in Shapes file format logic it's perfectly legal and I +think it makes sense too. However it can create a bit of confusion if you +forget it. Keep in mind that a famous Anvil bug is based on this very +confusion. But in Anvil it's a bug, in ShapeFusion it's a feature ;-) + +If you open an "original" Shapes file (e.g. from Marathon II) and then save it +without touching anything, it won't probably have exactly the same size. In +other words, it won't be exactly the same file. However I've never been able +to tell the difference, apart from looking at the size. The original engines, +AlephOne and ShapeFusion itself seem to behave perfectly with both files. The +size mismatch has probably to do with data structure alignments: ShapeFusion +ignores alignments when writing files, it just packs structure after structure +and so produces generally smaller files. + +Shapes files are known to rarely contain strange data, like negative sequence +ticks_per_frame. Maybe this comes from some broken Shapes editor, but it could +be just Anvil. ShapeFusion doesn't handle this invalid data very well, but I +plan to implement some consistency checks in the future. + +Feedback +-------- +You can send screenshots, bug reports and any comment to tito(at)dalcanton.it. +Better yet, you can join the ShapeFusion development mailing list +(see http://www.sourceforge.net/projects/shapefusion for details) and report +things there. + +History +------- +ShapeFusion was born in 2000 as a MacOS Classic application. Working releases +were produced, but then I moved to other projects and the development ended +while ShapeFusion was still far from being a complete editor. + +With the death of the Classic platform and the spread of AlephOne on different +operating systems I became more and more attracted by the idea of porting +ShapeFusion to other systems too. This couldn't be done easily with the +original MacOS code, so eventually I started to rewrite everything using the +portable wxWidgets toolkit. I also had the opportunity to rework the user +interface, since I never liked the Anvil approach that I was trying to follow +in the original ShapeFusion. Etienne joined the project at this stage. + +The new editor is not yet complete, but it's a great improvement at least on +the technical side (stability, code organization, portability). Adding new +features and fixing existing ones will be much easier with respect to the old +version. + +Changelog +--------- +0.5 + Collection and sound names are now read from a simple external text file. + First release supporting Windows officially. + ShapeFusion now requires at least wxWidgets 2.8.x. + Fixed a bug that prevented opening shapes files on Windows. + Fixed a file I/O bug that prevented BMP exporting on Windows. + Code cleanup and minor fixes. + +0.4 + Switched to multidocument wxWidgets framework (major code rewrite). + Implemented a preliminary Sounds editor. + Implemented the color table editor. + Improved the color quantization algorithm used when importing bitmaps. + Bitmap masks can be exported to separate bmp files. + Bitmaps are now exported to 8-bit bmp files. + Lots of small changes and fixes. + +0.3 + Improved functionality of the sequence editor. + Implemented bitmap and frame deletion. + Frame and sequence user interface cleanup. + One can now edit frame scale factors. + Fixed a serious bug regarding frames minimum light intensity value. + Assorted changes and fixes. + +0.2 + Work done on the color table section and on color table exporting features. + Improved color reduction when importing RGB bitmaps. + Implemented "Save all bitmaps". + Implemented preliminary version of a true sequence editor. + Implemented sequence deleting. + Fixed sequence name charset issue that prevented some names from being displayed. + BitmapBrowser and FrameBrowser speed optimizations. + Assorted changes and fixes. + +0.1 + First release of the new version using wxWidgets. + diff --git a/Resources/shapefusion.icns b/Resources/shapefusion.icns new file mode 100644 index 0000000000000000000000000000000000000000..066df538fe3a029f34e6190c8e83ba895cc1b26c GIT binary patch literal 218316 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�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�|r_OOYM_ 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

p@t!25!WaC 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 J01QI@002D4|BwIx literal 0 HcmV?d00001 diff --git a/Resources/shapefusion.ico b/Resources/shapefusion.ico new file mode 100644 index 0000000000000000000000000000000000000000..a1fa9e14bfd8cd99fab0906194a79a5b58b113d0 GIT binary patch literal 65794 zcmV)uK$gD%00964000000096X06gme05$*s03aX$0096X04Nav0CMX901yxW0096X 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 z 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�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 literal 0 HcmV?d00001 diff --git a/Resources/shapefusion.rc b/Resources/shapefusion.rc new file mode 100644 index 0000000..a82ddf7 --- /dev/null +++ b/Resources/shapefusion.rc @@ -0,0 +1,26 @@ +#define wxUSE_NO_MANIFEST 1 +#include + +1 VERSIONINFO +FILEVERSION 0, 5, 0, 0 +PRODUCTVERSION 0, 5, 0, 0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "AppName", "ShapeFusion" + VALUE "FileVersion", "0.5" + VALUE "FileDescription", "ShapeFusion for Win32" + VALUE "LegalCopyright", "GNU General Public License" + VALUE "License", "GNU General Public License (For details, see the file COPYING)" + VALUE "OriginalFilename", "ShapeFusion.exe" + VALUE "URL", "http://shapefusion.sourceforge.net" + } + } +} + +AppIcon ICON "shapefusion.ico" diff --git a/Resources/shapefusion.svg b/Resources/shapefusion.svg new file mode 100644 index 0000000..3ee56ee --- /dev/null +++ b/Resources/shapefusion.svg @@ -0,0 +1,1361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShapeFusion-Info.plist b/ShapeFusion-Info.plist new file mode 100644 index 0000000..c64f5dd --- /dev/null +++ b/ShapeFusion-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + CFBundleExecutable + ShapeFusion + CFBundleIconFile + shapefusion + CFBundleIdentifier + com.titodalcanton.shapefusion + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ShpF + CFBundleVersion + 0.5 + CFBundleShortVersionString + 0.5 + + diff --git a/ShapeFusion.xcodeproj/project.pbxproj b/ShapeFusion.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c9eaf96 --- /dev/null +++ b/ShapeFusion.xcodeproj/project.pbxproj @@ -0,0 +1,592 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 1F33454A0BC95CA300A15A32 /* LittleEndianBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F3345480BC95CA300A15A32 /* LittleEndianBuffer.cpp */; }; + 1F536BAC0B93426B00F51E49 /* BitmapBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B7E0AB0AE4B00896399 /* BitmapBrowser.cpp */; }; + 1F536BAD0B93426C00F51E49 /* BitmapView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B7D0AB0AE4B00896399 /* BitmapView.cpp */; }; + 1F536BAE0B93426C00F51E49 /* CTBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B7C0AB0AE4B00896399 /* CTBrowser.cpp */; }; + 1F536BAF0B93426D00F51E49 /* FrameBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B7B0AB0AE4B00896399 /* FrameBrowser.cpp */; }; + 1F536BB00B93426E00F51E49 /* FrameView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B7A0AB0AE4B00896399 /* FrameView.cpp */; }; + 1F536BB10B93426F00F51E49 /* SequenceView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F0966E020B551E4900820E4F /* SequenceView.cpp */; }; + 1F9857330B8A2CDC00D0395F /* ShapeFusionMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F98572F0B8A2CDC00D0395F /* ShapeFusionMain.cpp */; }; + 1F9857340B8A2CDC00D0395F /* ShapeFusionMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F9857310B8A2CDC00D0395F /* ShapeFusionMenus.cpp */; }; + 1F9857EA0B8A39BF00D0395F /* ShapesDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F9857E60B8A39BF00D0395F /* ShapesDocument.cpp */; }; + 1F9857EB0B8A39BF00D0395F /* ShapesView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F9857E80B8A39BF00D0395F /* ShapesView.cpp */; }; + 1F9FB4F10BF99DF000E8DBBD /* CTView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F9FB4EF0BF99DF000E8DBBD /* CTView.cpp */; }; + 1FAD07400B94409100E04604 /* ShapesElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FAD073D0B94409100E04604 /* ShapesElements.cpp */; }; + 1FAD85D20BB1E9410024D113 /* SoundsDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FAD85CC0BB1E9410024D113 /* SoundsDocument.cpp */; }; + 1FAD85D30BB1E9410024D113 /* SoundsElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FAD85CE0BB1E9410024D113 /* SoundsElements.cpp */; }; + 1FAD85D40BB1E9410024D113 /* SoundsView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FAD85D00BB1E9410024D113 /* SoundsView.cpp */; }; + 1FD3571A0BA21F2000360AA5 /* ShapesTreeItemData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FD357180BA21F2000360AA5 /* ShapesTreeItemData.cpp */; }; + 1FD941E10B92D5CD00DD1EEC /* BigEndianBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F096F44E0AD2DD97005A633A /* BigEndianBuffer.cpp */; }; + 1FE8DF890B9C4431003EF856 /* COPYING.txt in Resources */ = {isa = PBXBuildFile; fileRef = 1FE8DF870B9C4431003EF856 /* COPYING.txt */; }; + 1FE8DF8A0B9C4431003EF856 /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = 1FE8DF880B9C4431003EF856 /* README.txt */; }; + 1FEDD4640B9C3F9D00D69B62 /* utilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FEDD4610B9C3F9D00D69B62 /* utilities.cpp */; }; + 4DE10B410CC3992D00BAEC76 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F08B4C360AB0B06D00896399 /* Carbon.framework */; }; + 4DE10B4A0CC39BF200BAEC76 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F08B4C760AB0B7E300896399 /* IOKit.framework */; }; + 4DE10B4B0CC39BF400BAEC76 /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F08B4C370AB0B09A00896399 /* System.framework */; }; + 4DE10B4E0CC39C2E00BAEC76 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DE10B4D0CC39C2E00BAEC76 /* libiconv.dylib */; }; + 4DE10B500CC39C4200BAEC76 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DE10B4F0CC39C4200BAEC76 /* QuickTime.framework */; }; + 4DE10B530CC39C8E00BAEC76 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DE10B520CC39C8E00BAEC76 /* Cocoa.framework */; }; + 4DE10B570CC39CAB00BAEC76 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DE10B560CC39CAB00BAEC76 /* libz.dylib */; }; + AE0270E314C51B4F0093B508 /* PhysicsDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE0270DE14C51B4F0093B508 /* PhysicsDocument.cpp */; }; + AE0270E414C51B4F0093B508 /* PhysicsEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE0270DF14C51B4F0093B508 /* PhysicsEditor.cpp */; }; + AE0270E514C51B4F0093B508 /* PhysicsElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE0270E014C51B4F0093B508 /* PhysicsElements.cpp */; }; + AE0270E614C51B4F0093B508 /* PhysicsTreeItemData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE0270E114C51B4F0093B508 /* PhysicsTreeItemData.cpp */; }; + AE0270E714C51B4F0093B508 /* PhysicsView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE0270E214C51B4F0093B508 /* PhysicsView.cpp */; }; + AE0270F214C51BA00093B508 /* sndfile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE0270F114C51BA00093B508 /* sndfile.framework */; }; + AE02710C14C51C220093B508 /* DefaultNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE02710A14C51C220093B508 /* DefaultNames.cpp */; }; + AE02711214C51C510093B508 /* ShapeFusionDocManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE02711014C51C510093B508 /* ShapeFusionDocManager.cpp */; }; + AE02712714C5201C0093B508 /* sndfile.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = AE0270F114C51BA00093B508 /* sndfile.framework */; }; + AE33904A1290D7A2000DE273 /* shapefusion.icns in Resources */ = {isa = PBXBuildFile; fileRef = AE3390491290D7A2000DE273 /* shapefusion.icns */; }; + F03A573C0D0381F00057BB53 /* GenericEndianBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F03A573B0D0381F00057BB53 /* GenericEndianBuffer.cpp */; }; + F08B4C5A0AB0B31E00896399 /* ShapeFusionApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F08B4B780AB0AE4B00896399 /* ShapeFusionApp.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildRule section */ + F08B4D9F0AB0CF7500896399 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc; + fileType = sourcecode.cpp; + isEditable = 1; + outputFiles = ( + ); + }; +/* End PBXBuildRule section */ + +/* Begin PBXCopyFilesBuildPhase section */ + AE3390741290D895000DE273 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + AE02712714C5201C0093B508 /* sndfile.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1F3345480BC95CA300A15A32 /* LittleEndianBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LittleEndianBuffer.cpp; sourceTree = ""; }; + 1F3345490BC95CA300A15A32 /* LittleEndianBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LittleEndianBuffer.h; sourceTree = ""; }; + 1F84BCE90B8C760D000B4DC4 /* ShapesDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapesDocument.h; sourceTree = ""; }; + 1F98572F0B8A2CDC00D0395F /* ShapeFusionMain.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapeFusionMain.cpp; sourceTree = ""; }; + 1F9857300B8A2CDC00D0395F /* ShapeFusionMain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapeFusionMain.h; sourceTree = ""; }; + 1F9857310B8A2CDC00D0395F /* ShapeFusionMenus.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapeFusionMenus.cpp; sourceTree = ""; }; + 1F9857320B8A2CDC00D0395F /* ShapeFusionMenus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapeFusionMenus.h; sourceTree = ""; }; + 1F9857E60B8A39BF00D0395F /* ShapesDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapesDocument.cpp; sourceTree = ""; }; + 1F9857E80B8A39BF00D0395F /* ShapesView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapesView.cpp; sourceTree = ""; }; + 1F9857E90B8A39BF00D0395F /* ShapesView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapesView.h; sourceTree = ""; }; + 1F9FB4EF0BF99DF000E8DBBD /* CTView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTView.cpp; sourceTree = ""; }; + 1F9FB4F00BF99DF000E8DBBD /* CTView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTView.h; sourceTree = ""; }; + 1FAD073D0B94409100E04604 /* ShapesElements.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapesElements.cpp; sourceTree = ""; }; + 1FAD073E0B94409100E04604 /* ShapesElements.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapesElements.h; sourceTree = ""; }; + 1FAD85CC0BB1E9410024D113 /* SoundsDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SoundsDocument.cpp; sourceTree = ""; }; + 1FAD85CD0BB1E9410024D113 /* SoundsDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoundsDocument.h; sourceTree = ""; }; + 1FAD85CE0BB1E9410024D113 /* SoundsElements.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SoundsElements.cpp; sourceTree = ""; }; + 1FAD85CF0BB1E9410024D113 /* SoundsElements.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoundsElements.h; sourceTree = ""; }; + 1FAD85D00BB1E9410024D113 /* SoundsView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SoundsView.cpp; sourceTree = ""; }; + 1FAD85D10BB1E9410024D113 /* SoundsView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoundsView.h; sourceTree = ""; }; + 1FD357180BA21F2000360AA5 /* ShapesTreeItemData.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ShapesTreeItemData.cpp; sourceTree = ""; }; + 1FD357190BA21F2000360AA5 /* ShapesTreeItemData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ShapesTreeItemData.h; sourceTree = ""; }; + 1FE8DF870B9C4431003EF856 /* COPYING.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = COPYING.txt; sourceTree = ""; }; + 1FE8DF880B9C4431003EF856 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = ""; }; + 1FEDD4610B9C3F9D00D69B62 /* utilities.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = utilities.cpp; sourceTree = ""; }; + 1FEDD4620B9C3F9D00D69B62 /* utilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = utilities.h; sourceTree = ""; }; + 4DE10B4D0CC39C2E00BAEC76 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = /usr/lib/libiconv.dylib; sourceTree = ""; }; + 4DE10B4F0CC39C4200BAEC76 /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = ""; }; + 4DE10B520CC39C8E00BAEC76 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 4DE10B560CC39CAB00BAEC76 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = ""; }; + AE0270DE14C51B4F0093B508 /* PhysicsDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsDocument.cpp; path = Physics/PhysicsDocument.cpp; sourceTree = ""; }; + AE0270DF14C51B4F0093B508 /* PhysicsEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsEditor.cpp; path = Physics/PhysicsEditor.cpp; sourceTree = ""; }; + AE0270E014C51B4F0093B508 /* PhysicsElements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsElements.cpp; path = Physics/PhysicsElements.cpp; sourceTree = ""; }; + AE0270E114C51B4F0093B508 /* PhysicsTreeItemData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsTreeItemData.cpp; path = Physics/PhysicsTreeItemData.cpp; sourceTree = ""; }; + AE0270E214C51B4F0093B508 /* PhysicsView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsView.cpp; path = Physics/PhysicsView.cpp; sourceTree = ""; }; + AE0270E814C51B680093B508 /* PhysicsDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsDocument.h; path = Physics/PhysicsDocument.h; sourceTree = ""; }; + AE0270E914C51B680093B508 /* PhysicsElements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsElements.h; path = Physics/PhysicsElements.h; sourceTree = ""; }; + AE0270EA14C51B680093B508 /* PhysicsTreeItemData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsTreeItemData.h; path = Physics/PhysicsTreeItemData.h; sourceTree = ""; }; + AE0270EB14C51B680093B508 /* PhysicsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsView.h; path = Physics/PhysicsView.h; sourceTree = ""; }; + AE0270F114C51BA00093B508 /* sndfile.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = sndfile.framework; path = /Library/Frameworks/sndfile.framework; sourceTree = ""; }; + AE02710A14C51C220093B508 /* DefaultNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultNames.cpp; sourceTree = ""; }; + AE02710B14C51C220093B508 /* DefaultNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultNames.h; sourceTree = ""; }; + AE02711014C51C510093B508 /* ShapeFusionDocManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShapeFusionDocManager.cpp; sourceTree = ""; }; + AE02711114C51C510093B508 /* ShapeFusionDocManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShapeFusionDocManager.h; sourceTree = ""; }; + AE3390491290D7A2000DE273 /* shapefusion.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = shapefusion.icns; path = Resources/shapefusion.icns; sourceTree = ""; }; + F03A573B0D0381F00057BB53 /* GenericEndianBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = GenericEndianBuffer.cpp; sourceTree = ""; }; + F03A573D0D0381F80057BB53 /* GenericEndianBuffer.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = GenericEndianBuffer.h; sourceTree = ""; }; + F08B4B780AB0AE4B00896399 /* ShapeFusionApp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShapeFusionApp.cpp; sourceTree = ""; }; + F08B4B7A0AB0AE4B00896399 /* FrameView.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = FrameView.cpp; sourceTree = ""; }; + F08B4B7B0AB0AE4B00896399 /* FrameBrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = FrameBrowser.cpp; sourceTree = ""; }; + F08B4B7C0AB0AE4B00896399 /* CTBrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = CTBrowser.cpp; sourceTree = ""; }; + F08B4B7D0AB0AE4B00896399 /* BitmapView.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapView.cpp; sourceTree = ""; }; + F08B4B7E0AB0AE4B00896399 /* BitmapBrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapBrowser.cpp; sourceTree = ""; }; + F08B4B820AB0AE6C00896399 /* ShapeFusionApp.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 5; path = ShapeFusionApp.h; sourceTree = ""; }; + F08B4B840AB0AE6C00896399 /* FrameView.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = FrameView.h; sourceTree = ""; }; + F08B4B850AB0AE6C00896399 /* FrameBrowser.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = FrameBrowser.h; sourceTree = ""; }; + F08B4B860AB0AE6C00896399 /* CTBrowser.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = CTBrowser.h; sourceTree = ""; }; + F08B4B870AB0AE6C00896399 /* BitmapView.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = BitmapView.h; sourceTree = ""; }; + F08B4B880AB0AE6C00896399 /* BitmapBrowser.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = BitmapBrowser.h; sourceTree = ""; }; + F08B4C360AB0B06D00896399 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + F08B4C370AB0B09A00896399 /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = ""; }; + F08B4C440AB0B10000896399 /* ShapeFusion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShapeFusion.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F08B4C470AB0B10000896399 /* ShapeFusion-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ShapeFusion-Info.plist"; sourceTree = ""; }; + F08B4C760AB0B7E300896399 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + F08B4CB30AB0C0E700896399 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + F0966E020B551E4900820E4F /* SequenceView.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = SequenceView.cpp; sourceTree = ""; }; + F0966E040B551E5100820E4F /* SequenceView.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = SequenceView.h; sourceTree = ""; }; + F096F44E0AD2DD97005A633A /* BigEndianBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.cpp.cpp; path = BigEndianBuffer.cpp; sourceTree = ""; }; + F096F4500AD2DD9F005A633A /* BigEndianBuffer.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = BigEndianBuffer.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F08B4C420AB0B10000896399 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DE10B410CC3992D00BAEC76 /* Carbon.framework in Frameworks */, + 4DE10B4A0CC39BF200BAEC76 /* IOKit.framework in Frameworks */, + 4DE10B4B0CC39BF400BAEC76 /* System.framework in Frameworks */, + 4DE10B500CC39C4200BAEC76 /* QuickTime.framework in Frameworks */, + 4DE10B530CC39C8E00BAEC76 /* Cocoa.framework in Frameworks */, + 4DE10B4E0CC39C2E00BAEC76 /* libiconv.dylib in Frameworks */, + 4DE10B570CC39CAB00BAEC76 /* libz.dylib in Frameworks */, + AE0270F214C51BA00093B508 /* sndfile.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1F84BF630B8C8F5C000B4DC4 /* Shapes */ = { + isa = PBXGroup; + children = ( + 1F9FB4EF0BF99DF000E8DBBD /* CTView.cpp */, + 1F9FB4F00BF99DF000E8DBBD /* CTView.h */, + 1FD357180BA21F2000360AA5 /* ShapesTreeItemData.cpp */, + 1FD357190BA21F2000360AA5 /* ShapesTreeItemData.h */, + 1FAD073D0B94409100E04604 /* ShapesElements.cpp */, + 1FAD073E0B94409100E04604 /* ShapesElements.h */, + 1F9857E60B8A39BF00D0395F /* ShapesDocument.cpp */, + 1F84BCE90B8C760D000B4DC4 /* ShapesDocument.h */, + 1F9857E80B8A39BF00D0395F /* ShapesView.cpp */, + 1F9857E90B8A39BF00D0395F /* ShapesView.h */, + F08B4B7A0AB0AE4B00896399 /* FrameView.cpp */, + F08B4B840AB0AE6C00896399 /* FrameView.h */, + F08B4B7B0AB0AE4B00896399 /* FrameBrowser.cpp */, + F08B4B850AB0AE6C00896399 /* FrameBrowser.h */, + F08B4B7C0AB0AE4B00896399 /* CTBrowser.cpp */, + F08B4B860AB0AE6C00896399 /* CTBrowser.h */, + F08B4B7D0AB0AE4B00896399 /* BitmapView.cpp */, + F08B4B870AB0AE6C00896399 /* BitmapView.h */, + F08B4B7E0AB0AE4B00896399 /* BitmapBrowser.cpp */, + F08B4B880AB0AE6C00896399 /* BitmapBrowser.h */, + F0966E020B551E4900820E4F /* SequenceView.cpp */, + F0966E040B551E5100820E4F /* SequenceView.h */, + 1FEDD4610B9C3F9D00D69B62 /* utilities.cpp */, + 1FEDD4620B9C3F9D00D69B62 /* utilities.h */, + ); + path = Shapes; + sourceTree = ""; + }; + 1FAD85C70BB1E9280024D113 /* Sounds */ = { + isa = PBXGroup; + children = ( + 1FAD85CC0BB1E9410024D113 /* SoundsDocument.cpp */, + 1FAD85CD0BB1E9410024D113 /* SoundsDocument.h */, + 1FAD85CE0BB1E9410024D113 /* SoundsElements.cpp */, + 1FAD85CF0BB1E9410024D113 /* SoundsElements.h */, + 1FAD85D00BB1E9410024D113 /* SoundsView.cpp */, + 1FAD85D10BB1E9410024D113 /* SoundsView.h */, + ); + path = Sounds; + sourceTree = ""; + }; + AE0270DD14C51B3A0093B508 /* Physics */ = { + isa = PBXGroup; + children = ( + AE0270E814C51B680093B508 /* PhysicsDocument.h */, + AE0270E914C51B680093B508 /* PhysicsElements.h */, + AE0270EA14C51B680093B508 /* PhysicsTreeItemData.h */, + AE0270EB14C51B680093B508 /* PhysicsView.h */, + AE0270DE14C51B4F0093B508 /* PhysicsDocument.cpp */, + AE0270DF14C51B4F0093B508 /* PhysicsEditor.cpp */, + AE0270E014C51B4F0093B508 /* PhysicsElements.cpp */, + AE0270E114C51B4F0093B508 /* PhysicsTreeItemData.cpp */, + AE0270E214C51B4F0093B508 /* PhysicsView.cpp */, + ); + name = Physics; + sourceTree = ""; + }; + F08B4B580AB0ADBA00896399 = { + isa = PBXGroup; + children = ( + F08B4B720AB0AE0B00896399 /* Sources */, + F08B4B750AB0AE1200896399 /* Resources */, + F08B4B9E0AB0B02A00896399 /* External things */, + F08B4C450AB0B10000896399 /* Products */, + ); + sourceTree = ""; + }; + F08B4B720AB0AE0B00896399 /* Sources */ = { + isa = PBXGroup; + children = ( + AE0270DD14C51B3A0093B508 /* Physics */, + 1FAD85C70BB1E9280024D113 /* Sounds */, + 1F84BF630B8C8F5C000B4DC4 /* Shapes */, + F08B4B780AB0AE4B00896399 /* ShapeFusionApp.cpp */, + F08B4B820AB0AE6C00896399 /* ShapeFusionApp.h */, + 1F9857310B8A2CDC00D0395F /* ShapeFusionMenus.cpp */, + 1F9857320B8A2CDC00D0395F /* ShapeFusionMenus.h */, + 1F98572F0B8A2CDC00D0395F /* ShapeFusionMain.cpp */, + 1F9857300B8A2CDC00D0395F /* ShapeFusionMain.h */, + F03A573B0D0381F00057BB53 /* GenericEndianBuffer.cpp */, + F03A573D0D0381F80057BB53 /* GenericEndianBuffer.h */, + F096F44E0AD2DD97005A633A /* BigEndianBuffer.cpp */, + F096F4500AD2DD9F005A633A /* BigEndianBuffer.h */, + 1F3345480BC95CA300A15A32 /* LittleEndianBuffer.cpp */, + 1F3345490BC95CA300A15A32 /* LittleEndianBuffer.h */, + AE02711014C51C510093B508 /* ShapeFusionDocManager.cpp */, + AE02711114C51C510093B508 /* ShapeFusionDocManager.h */, + ); + name = Sources; + sourceTree = SOURCE_ROOT; + }; + F08B4B750AB0AE1200896399 /* Resources */ = { + isa = PBXGroup; + children = ( + AE3390491290D7A2000DE273 /* shapefusion.icns */, + 1FE8DF870B9C4431003EF856 /* COPYING.txt */, + 1FE8DF880B9C4431003EF856 /* README.txt */, + F08B4C470AB0B10000896399 /* ShapeFusion-Info.plist */, + AE02710A14C51C220093B508 /* DefaultNames.cpp */, + AE02710B14C51C220093B508 /* DefaultNames.h */, + ); + name = Resources; + sourceTree = ""; + }; + F08B4B9E0AB0B02A00896399 /* External things */ = { + isa = PBXGroup; + children = ( + 4DE10B560CC39CAB00BAEC76 /* libz.dylib */, + 4DE10B520CC39C8E00BAEC76 /* Cocoa.framework */, + 4DE10B4F0CC39C4200BAEC76 /* QuickTime.framework */, + 4DE10B4D0CC39C2E00BAEC76 /* libiconv.dylib */, + F08B4C360AB0B06D00896399 /* Carbon.framework */, + F08B4C370AB0B09A00896399 /* System.framework */, + F08B4C760AB0B7E300896399 /* IOKit.framework */, + F08B4CB30AB0C0E700896399 /* OpenGL.framework */, + AE0270F114C51BA00093B508 /* sndfile.framework */, + ); + name = "External things"; + sourceTree = ""; + }; + F08B4C450AB0B10000896399 /* Products */ = { + isa = PBXGroup; + children = ( + F08B4C440AB0B10000896399 /* ShapeFusion.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F08B4C430AB0B10000896399 /* ShapeFusion */ = { + isa = PBXNativeTarget; + buildConfigurationList = F08B4C480AB0B10000896399 /* Build configuration list for PBXNativeTarget "ShapeFusion" */; + buildPhases = ( + F08B4C400AB0B10000896399 /* Resources */, + F08B4C410AB0B10000896399 /* Sources */, + F08B4C420AB0B10000896399 /* Frameworks */, + AE3390741290D895000DE273 /* CopyFiles */, + ); + buildRules = ( + F08B4D9F0AB0CF7500896399 /* PBXBuildRule */, + ); + dependencies = ( + ); + name = ShapeFusion; + productName = carbon_static; + productReference = F08B4C440AB0B10000896399 /* ShapeFusion.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F08B4B5A0AB0ADBA00896399 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = F08B4B5B0AB0ADBA00896399 /* Build configuration list for PBXProject "ShapeFusion" */; + compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = F08B4B580AB0ADBA00896399; + productRefGroup = F08B4C450AB0B10000896399 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F08B4C430AB0B10000896399 /* ShapeFusion */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F08B4C400AB0B10000896399 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1FE8DF890B9C4431003EF856 /* COPYING.txt in Resources */, + 1FE8DF8A0B9C4431003EF856 /* README.txt in Resources */, + AE33904A1290D7A2000DE273 /* shapefusion.icns in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F08B4C410AB0B10000896399 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F08B4C5A0AB0B31E00896399 /* ShapeFusionApp.cpp in Sources */, + 1F9857330B8A2CDC00D0395F /* ShapeFusionMain.cpp in Sources */, + 1F9857340B8A2CDC00D0395F /* ShapeFusionMenus.cpp in Sources */, + 1F9857EA0B8A39BF00D0395F /* ShapesDocument.cpp in Sources */, + 1F9857EB0B8A39BF00D0395F /* ShapesView.cpp in Sources */, + 1F536BAE0B93426C00F51E49 /* CTBrowser.cpp in Sources */, + 1F9FB4F10BF99DF000E8DBBD /* CTView.cpp in Sources */, + 1F536BAC0B93426B00F51E49 /* BitmapBrowser.cpp in Sources */, + 1F536BAD0B93426C00F51E49 /* BitmapView.cpp in Sources */, + 1F536BAF0B93426D00F51E49 /* FrameBrowser.cpp in Sources */, + 1F536BB00B93426E00F51E49 /* FrameView.cpp in Sources */, + 1F536BB10B93426F00F51E49 /* SequenceView.cpp in Sources */, + 1FAD07400B94409100E04604 /* ShapesElements.cpp in Sources */, + 1FEDD4640B9C3F9D00D69B62 /* utilities.cpp in Sources */, + 1FD3571A0BA21F2000360AA5 /* ShapesTreeItemData.cpp in Sources */, + 1FAD85D20BB1E9410024D113 /* SoundsDocument.cpp in Sources */, + 1FAD85D30BB1E9410024D113 /* SoundsElements.cpp in Sources */, + 1FAD85D40BB1E9410024D113 /* SoundsView.cpp in Sources */, + F03A573C0D0381F00057BB53 /* GenericEndianBuffer.cpp in Sources */, + 1FD941E10B92D5CD00DD1EEC /* BigEndianBuffer.cpp in Sources */, + 1F33454A0BC95CA300A15A32 /* LittleEndianBuffer.cpp in Sources */, + AE0270E314C51B4F0093B508 /* PhysicsDocument.cpp in Sources */, + AE0270E414C51B4F0093B508 /* PhysicsEditor.cpp in Sources */, + AE0270E514C51B4F0093B508 /* PhysicsElements.cpp in Sources */, + AE0270E614C51B4F0093B508 /* PhysicsTreeItemData.cpp in Sources */, + AE0270E714C51B4F0093B508 /* PhysicsView.cpp in Sources */, + AE02710C14C51C220093B508 /* DefaultNames.cpp in Sources */, + AE02711214C51C510093B508 /* ShapeFusionDocManager.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + F08B4B5C0AB0ADBA00896399 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + "$(WX_SRC_ROOT)/include/", + "$(WX_SRC_ROOT)/src/build/include", + ); + LIBRARY_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.4; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + USER_HEADER_SEARCH_PATHS = ""; + WARNING_CFLAGS = "-Wall"; + WX_SRC_ROOT = "/Applications/wxMac-2.8.6"; + }; + name = Debug; + }; + F08B4B5D0AB0ADBA00896399 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 2; + HEADER_SEARCH_PATHS = ( + "$(WX_SRC_ROOT)/include/", + "$(WX_SRC_ROOT)/src/build/include", + ); + LIBRARY_SEARCH_PATHS = ""; + MACOSX_DEPLOYMENT_TARGET = 10.4; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + USER_HEADER_SEARCH_PATHS = ""; + WX_SRC_ROOT = "/Applications/wxMac-2.8.6"; + }; + name = Release; + }; + F08B4C490AB0B10000896399 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "_FILE_OFFSET_BITS=64", + _LARGE_FILES, + __WXMAC__, + ); + GCC_VERSION = 4.0; + HEADER_SEARCH_PATHS = ( + "/usr/local/lib/wx/include/mac-unicode-release-static-2.8", + "/usr/local/include/wx-2.8", + /Library/Frameworks/sndfile.framework/Headers, + ); + INFOPLIST_FILE = "ShapeFusion-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(WX_LIB_ROOT)", + ); + OTHER_LDFLAGS = ( + "-framework", + IOKit, + "-framework", + Carbon, + "-framework", + Cocoa, + "-framework", + System, + "-framework", + QuickTime, + "-framework", + OpenGL, + "-framework", + AGL, + "/usr/local/lib/libwx_macu_richtext-2.8.a", + "/usr/local/lib/libwx_macu_aui-2.8.a", + "/usr/local/lib/libwx_macu_xrc-2.8.a", + "/usr/local/lib/libwx_macu_qa-2.8.a", + "/usr/local/lib/libwx_macu_html-2.8.a", + "/usr/local/lib/libwx_macu_adv-2.8.a", + "/usr/local/lib/libwx_macu_core-2.8.a", + "/usr/local/lib/libwx_base_carbonu_xml-2.8.a", + "/usr/local/lib/libwx_base_carbonu_net-2.8.a", + "/usr/local/lib/libwx_base_carbonu-2.8.a", + "-framework", + WebKit, + "-lwxregexu-2.8", + "-lwxexpat-2.8", + "-lwxtiff-2.8", + "-lwxjpeg-2.8", + "-lwxpng-2.8", + "-lz", + "-lpthread", + "-liconv", + ); + PRODUCT_NAME = ShapeFusion; + WRAPPER_EXTENSION = app; + WX_LIB_ROOT = /usr/local/lib; + WX_SRC_ROOT = /usr/local/lib/wx; + _FILE_OFFSET_BITS = "64 _LARGE_FILES __WXMAC__"; + }; + name = Debug; + }; + F08B4C4A0AB0B10000896399 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEAD_CODE_STRIPPING = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "_FILE_OFFSET_BITS=64", + _LARGE_FILES, + __WXMAC__, + ); + GCC_VERSION = 4.0; + HEADER_SEARCH_PATHS = ( + "/usr/local/lib/wx/include/mac-unicode-release-static-2.8", + "/usr/local/include/wx-2.8", + /Library/Frameworks/sndfile.framework/Headers, + ); + INFOPLIST_FILE = "ShapeFusion-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(WX_LIB_ROOT)", + ); + OTHER_LDFLAGS = ( + "-framework", + IOKit, + "-framework", + Carbon, + "-framework", + Cocoa, + "-framework", + System, + "-framework", + QuickTime, + "-framework", + OpenGL, + "-framework", + AGL, + "/usr/local/lib/libwx_macu_richtext-2.8.a", + "/usr/local/lib/libwx_macu_aui-2.8.a", + "/usr/local/lib/libwx_macu_xrc-2.8.a", + "/usr/local/lib/libwx_macu_qa-2.8.a", + "/usr/local/lib/libwx_macu_html-2.8.a", + "/usr/local/lib/libwx_macu_adv-2.8.a", + "/usr/local/lib/libwx_macu_core-2.8.a", + "/usr/local/lib/libwx_base_carbonu_xml-2.8.a", + "/usr/local/lib/libwx_base_carbonu_net-2.8.a", + "/usr/local/lib/libwx_base_carbonu-2.8.a", + "-framework", + WebKit, + "-lwxregexu-2.8", + "-lwxexpat-2.8", + "-lwxtiff-2.8", + "-lwxjpeg-2.8", + "-lwxpng-2.8", + "-lz", + "-lpthread", + "-liconv", + ); + PRODUCT_NAME = ShapeFusion; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + WX_LIB_ROOT = /usr/local/lib; + WX_SRC_ROOT = /usr/local/lib/wx; + _FILE_OFFSET_BITS = "64 _LARGE_FILES __WXMAC__"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F08B4B5B0AB0ADBA00896399 /* Build configuration list for PBXProject "ShapeFusion" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F08B4B5C0AB0ADBA00896399 /* Debug */, + F08B4B5D0AB0ADBA00896399 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F08B4C480AB0B10000896399 /* Build configuration list for PBXNativeTarget "ShapeFusion" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F08B4C490AB0B10000896399 /* Debug */, + F08B4C4A0AB0B10000896399 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F08B4B5A0AB0ADBA00896399 /* Project object */; +} diff --git a/ShapeFusionApp.cpp b/ShapeFusionApp.cpp new file mode 100644 index 0000000..bbc537c --- /dev/null +++ b/ShapeFusionApp.cpp @@ -0,0 +1,133 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ShapeFusionApp.h" +#include "ShapeFusionMenus.h" +#include "ShapesDocument.h" +#include "ShapesView.h" +#include "SoundsDocument.h" +#include "SoundsView.h" +#include "PhysicsDocument.h" +#include "PhysicsView.h" + +ShapeFusionMain *frame = (ShapeFusionMain *)NULL; + +IMPLEMENT_APP(ShapeFusionApp) + +ShapeFusionApp::ShapeFusionApp(void) +{ + m_docManager = (ShapeFusionDocManager *)NULL; +} + +bool ShapeFusionApp::OnInit(void) +{ + if (!wxApp::OnInit()) + return false; + + // so that we can import every sort of bitmap format + wxInitAllImageHandlers(); + + // Create a document manager + m_docManager = new ShapeFusionDocManager; + + // Create a template relating drawing documents to their views + (void) new wxDocTemplate(m_docManager, _T("Shapes"), _T("*"), _T(""), _T(""), _T("Shapes"), _T("Shapes"), + CLASSINFO(ShapesDocument), CLASSINFO(ShapesView)); + (void) new wxDocTemplate(m_docManager, _T("Sounds"), _T("*"), _T(""), _T(""), _T("Sounds"), _T("Sounds"), + CLASSINFO(SoundsDocument), CLASSINFO(SoundsView)); + + (void) new wxDocTemplate(m_docManager, _T("Physics"), _T("*"), _T(""), _T(""), _T("Physics"), _T("Physics"), CLASSINFO(PhysicsDocument), CLASSINFO(PhysicsView)); + +#ifdef __WXMAC__ + //TODO: Put correct file extension values here +// wxFileName::MacRegisterDefaultTypeAndCreator( wxT("*") , 'WXMB' , 'WXMA' ); +// wxFileName::MacRegisterDefaultTypeAndCreator( wxT("*") , 'WXMB' , 'WXMA' ); +#endif + + // Create the main frame window +#ifdef __WXMAC__ + // a hack to make the frame invisible on MacOS, which is more Mac-like + // http://www.wxwidgets.org/wiki/index.php/WxMac_Issues#The_Mac_OS_menu_bar + frame = new ShapeFusionMain(m_docManager, (wxFrame *)NULL, wxID_ANY, _T("ShapeFusion Workspace"), wxPoint(5,5), wxSize(0,0), 0); +#else + frame = new ShapeFusionMain(m_docManager, (wxFrame *)NULL, wxID_ANY, _T("ShapeFusion Workspace"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE); +#endif + + // Give it an icon (this is ignored in MDI mode: uses resources) +#ifdef __WXMSW__ + frame->SetIcon(wxIcon(_T("doc_icn"))); +#endif + + wxMenuBar *menu_bar = new wxMenuBar; + + CreateFileMenu(menu_bar); + CreateEditMenu(menu_bar); + CreateHelpMenu(menu_bar); + + // Associate the menu bar with the frame + frame->SetMenuBar(menu_bar); + + //FIXME: This doesn't work + //wxMenuItem *menuItem = menu_bar->FindItem(FILE_MENU_HISTORY); + //m_docManager->FileHistoryUseMenu(menuItem->GetMenu()); + + frame->Centre(wxBOTH); + frame->Show(true); + + SetTopWindow(frame); + return true; +} + +int ShapeFusionApp::OnExit(void) +{ + delete m_docManager; + return 0; +} + +/* +* Centralised code for creating a document frame. +* Called when a new view is created (after a New/Open event) +*/ +wxFrame *ShapeFusionApp::CreateChildFrame(wxDocument *doc, wxView *view, const wxString title, wxPoint point, wxSize size, long style) +{ + // Make a child frame + wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, GetMainFrame(), wxID_ANY, title, + point, size, style); + + wxMenuBar *menu_bar = new wxMenuBar; + + CreateFileMenu(menu_bar); + CreateEditMenu(menu_bar); + CreateHelpMenu(menu_bar); + + // Associate the menu bar with the frame + subframe->SetMenuBar(menu_bar); + + //FIXME: This doesn't work + //wxMenuItem *menuItem = menu_bar->FindItem(FILE_MENU_HISTORY); + //m_docManager->FileHistoryUseMenu(menuItem->GetMenu()); + + subframe->Centre(wxBOTH); + + return subframe; +} + +ShapeFusionMain *GetMainFrame(void) +{ + return frame; +} diff --git a/ShapeFusionApp.h b/ShapeFusionApp.h new file mode 100644 index 0000000..2a7283a --- /dev/null +++ b/ShapeFusionApp.h @@ -0,0 +1,46 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SHAPEFUSIONAPP_H +#define SHAPEFUSIONAPP_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "wx/docview.h" +#include "ShapeFusionDocManager.h" +#include "ShapeFusionMain.h" + +class ShapeFusionApp: public wxApp { +public: + ShapeFusionApp(void); + bool OnInit(void); + int OnExit(void); + + wxFrame *CreateChildFrame(wxDocument *doc, wxView *view, const wxString title, wxPoint point, wxSize size, long style = wxDEFAULT_FRAME_STYLE); + +protected: + ShapeFusionDocManager* m_docManager; +}; + +DECLARE_APP(ShapeFusionApp); + +ShapeFusionMain *GetMainFrame(void); + +#endif diff --git a/ShapeFusionDocManager.cpp b/ShapeFusionDocManager.cpp new file mode 100644 index 0000000..d98f240 --- /dev/null +++ b/ShapeFusionDocManager.cpp @@ -0,0 +1,169 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ShapeFusionDocManager.h" + +#include "BigEndianBuffer.h" + +#include +#include + +static wxDocTemplate* FindTemplate(wxList& templates, const wxString& description) +{ + for (unsigned int i = 0; i < templates.GetCount(); ++i) { + wxDocTemplate* temp = reinterpret_cast(templates.Item(i)->GetData()); + if (temp->GetDescription() == description) { + return temp; + } + } + + return 0; +} + +wxDocTemplate* ShapeFusionDocManager::FindTemplateForPath(const wxString& path) +{ + // if we recognize the extension, assume it's correct + wxFileName filename(path); + wxString ext = filename.GetExt(); + + if (ext == _("sndA") || ext == _("snd2")) { + return ::FindTemplate(GetTemplates(), _("Sounds")); + } else if (ext == _("shpA") || ext == _("shp2")) { + return ::FindTemplate(GetTemplates(), _("Shapes")); + } + + wxFileInputStream stream(path); + if (!stream.IsOk()) { + return 0; + } + + + // check for sounds file + { + stream.SeekI(0, wxFromStart); + + unsigned char header[8]; + stream.Read(header, 8); + + BigEndianBuffer buffer(header, 4); + + unsigned long version = buffer.ReadULong(); + if ((version == 0 || version == 1) + && strncmp(reinterpret_cast(&header[4]), "snd2", 4) == 0) { + return ::FindTemplate(GetTemplates(), _("Sounds")); + } + } + + stream.SeekI(0, wxFromEnd); + long filesize = stream.TellI(); + stream.SeekI(0, wxFromStart); + + // check for shapes file + { + bool is_shapes = true; + for (int i = 0; i < 32; ++i) { + unsigned char header[32]; + stream.Read(header, 32); + + BigEndianBuffer buffer(header, 20); + unsigned long status_flags = buffer.ReadULong(); + long offset = buffer.ReadLong(); + long length = buffer.ReadLong(); + long offset16 = buffer.ReadLong(); + long length16 = buffer.ReadLong(); + + if (status_flags != 0 + || (offset != -1 && (offset >= filesize || offset + length > filesize)) + || (offset16 != -1 && (offset16 >= filesize || offset16 + length16 > filesize))) { + is_shapes = false; + break; + } + } + + if (is_shapes) { + return ::FindTemplate(GetTemplates(), _("Shapes")); + } + } + + // check for physics + { + stream.SeekI(0, wxFromStart); + unsigned char header[128]; + stream.Read(header, 128); + + BigEndianBuffer header_buffer(header, 128); + int version = header_buffer.ReadShort(); + int data_version = header_buffer.ReadShort(); + if ((version == 0 || version == 1 || version == 2 || version == 4) && (data_version == 0 || data_version == 1 || data_version == 2)) { + header_buffer.Position(72); + long directory_offset = header_buffer.ReadLong(); + if (directory_offset >= filesize) + return 0; + + unsigned char tag[4]; + stream.Read(tag, 4); + if (strncmp(reinterpret_cast(tag), "MNpx", 4) == 0) { + return ::FindTemplate(GetTemplates(), _("Physics")); + } + } + } + + return 0; +} + +wxDocTemplate* ShapeFusionDocManager::SelectDocumentPath(wxDocTemplate** templates, int noTemplates, wxString& path, long, bool) +{ + wxString pathTmp = wxFileSelector(_("Select a file"), + m_lastDirectory); + + wxDocTemplate* theTemplate = 0; + + if (!pathTmp.empty()) { + if (!wxFileExists(pathTmp)) + { + wxString msgTitle; + if (!wxTheApp->GetAppName().empty()) { + msgTitle = wxTheApp->GetAppName(); + } else { + msgTitle = wxString(_("File error")); + } + + (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle, wxOK | wxICON_EXCLAMATION); + + path = wxEmptyString; + return 0; + } + m_lastDirectory = wxPathOnly(pathTmp); + + path = pathTmp; + + theTemplate = FindTemplateForPath(path); + + if (!theTemplate) + { + (void) wxMessageBox(_("Sorry, the format for this file is unknown."), _("Open File"), wxOK | wxICON_EXCLAMATION); + } + + return FindTemplateForPath(path); + } else { + path = wxEmptyString; + } + + return theTemplate; + +} diff --git a/ShapeFusionDocManager.h b/ShapeFusionDocManager.h new file mode 100644 index 0000000..f29578b --- /dev/null +++ b/ShapeFusionDocManager.h @@ -0,0 +1,34 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SHAPEFUSIONDOCMANAGER_H +#define SHAPEFUSIONDOCMANAGER_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif +#include "wx/docview.h" + +class ShapeFusionDocManager : public wxDocManager { +public: + wxDocTemplate* SelectDocumentPath(wxDocTemplate** templates, int noTemplates, wxString& path, long flags, bool save); + wxDocTemplate* FindTemplateForPath(const wxString& path); +}; + +#endif diff --git a/ShapeFusionMain.cpp b/ShapeFusionMain.cpp new file mode 100644 index 0000000..636b3d7 --- /dev/null +++ b/ShapeFusionMain.cpp @@ -0,0 +1,56 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ShapeFusionMain.h" +#include "ShapeFusionMenus.h" + +/* +* This is the top-level window of the application. +*/ + +IMPLEMENT_CLASS(ShapeFusionMain, wxDocParentFrame) +BEGIN_EVENT_TABLE(ShapeFusionMain, wxDocParentFrame) + EVT_MENU(ABOUT_MENU, ShapeFusionMain::OnAbout) + EVT_MENU_RANGE(FILE_HISTORY_FILE1, FILE_HISTORY_FILE9, ShapeFusionMain::OnMenuHistory) +END_EVENT_TABLE() + +ShapeFusionMain::ShapeFusionMain(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, + const wxPoint& pos, const wxSize& size, const long type): +wxDocParentFrame(manager, frame, id, title, pos, size, type) +{ +} + +void ShapeFusionMain::OnAbout(wxCommandEvent& WXUNUSED(event)) +{ + wxMessageDialog *dlg = new wxMessageDialog(this, + wxT("ShapeFusion 0.5\nhttp://shapefusion.sourceforge.net\n\nCopyright 2000-2008, Tito Dal Canton\n\n" + "An editor for Marathon II, Marathon Infinity and AlephOne shapes and sounds files. " + "Released under the terms of the GNU General Public License: for more information " + "see the COPYING file that comes with ShapeFusion."), + wxT("About ShapeFusion"), wxOK | wxICON_INFORMATION); + dlg->ShowModal(); + dlg->Destroy(); +} + +void ShapeFusionMain::OnMenuHistory(wxCommandEvent& event) +{ + wxString f(m_docManager->GetHistoryFile(event.GetId() - FILE_HISTORY_FILE1)); + if (!f.empty()) + (void)m_docManager->CreateDocument(f, wxDOC_SILENT); +} + diff --git a/ShapeFusionMain.h b/ShapeFusionMain.h new file mode 100644 index 0000000..953ad53 --- /dev/null +++ b/ShapeFusionMain.h @@ -0,0 +1,39 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __FUSIONMAIN_H__ +#define __FUSIONMAIN_H__ + +#include "wx/docview.h" + +// Define a new frame +class ShapeFusionMain: public wxDocParentFrame +{ + DECLARE_CLASS(FusionMain) + +public: + ShapeFusionMain(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, + const wxPoint& pos, const wxSize& size, const long type); + void OnAbout(wxCommandEvent& event); + void OnMenuHistory(wxCommandEvent& event); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/ShapeFusionMenus.cpp b/ShapeFusionMenus.cpp new file mode 100644 index 0000000..5358fdc --- /dev/null +++ b/ShapeFusionMenus.cpp @@ -0,0 +1,194 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ShapeFusionMenus.h" + +void CreateFileMenu(wxMenuBar *menu_bar) +{ + wxMenu *file_menu, + *recent_file_menu; +/* *file_new_menu, + *file_open_menu;*/ + + // We create our two submenus +/* file_new_menu = new wxMenu(); + file_new_menu->Append(FILE_MENU_NEW_SHAPES, wxT("Shapes file")); + file_new_menu->Append(FILE_MENU_NEW_PHYSICS, wxT("Physics file")); + file_new_menu->Append(FILE_MENU_NEW_MAP, wxT("Map file")); + file_new_menu->Append(FILE_MENU_NEW_SOUNDS, wxT("Sounds file")); + file_open_menu = new wxMenu(); + file_open_menu->Append(FILE_MENU_OPEN_SHAPES, wxT("Shapes file")); + file_open_menu->Append(FILE_MENU_OPEN_PHYSICS, wxT("Physics file")); + file_open_menu->Append(FILE_MENU_OPEN_MAP, wxT("Map file")); + file_open_menu->Append(FILE_MENU_OPEN_SOUNDS, wxT("Sounds file"));*/ + // We create the recent menu here... + recent_file_menu = new wxMenu(); + + // We create the 'main' File menu + file_menu = new wxMenu(); +// file_menu->Append(FILE_MENU_NEW, wxT("New..."), file_new_menu); +// file_menu->Append(FILE_MENU_OPEN, wxT("Open..."), file_open_menu); +// file_menu->Append(FILE_MENU_NEW, wxT("New...\tCtrl+N")); + file_menu->Append(FILE_MENU_OPEN, wxT("Open...\tCtrl+O")); + file_menu->Append(FILE_MENU_HISTORY, wxT("Open Recent..."), recent_file_menu); + file_menu->Append(FILE_MENU_CLOSE, wxT("&Close\tCtrl+W")); + file_menu->AppendSeparator(); + file_menu->Append(FILE_MENU_SAVE, wxT("&Save\tCtrl+S")); + file_menu->Append(FILE_MENU_SAVEAS, wxT("Save as...\tCtrl+Shift+S")); + file_menu->Append(FILE_MENU_REVERT, wxT("&Revert")); + file_menu->AppendSeparator(); + file_menu->Append(FILE_MENU_PRINT, _T("&Print...")); + file_menu->Append(FILE_MENU_PRINT_SETUP, _T("Print &Setup...")); + file_menu->Append(FILE_MENU_PREVIEW, _T("Print Pre&view")); + file_menu->AppendSeparator(); + file_menu->Append(FILE_MENU_QUIT, wxT("&Quit\tAlt+F4")); + + file_menu->Enable(FILE_MENU_SAVE, false); + file_menu->Enable(FILE_MENU_SAVEAS, false); + file_menu->Enable(FILE_MENU_CLOSE, false); + + // We add the File menu to the passed menubar + menu_bar->Append(file_menu, wxT("&File")); +} + +void CreateEditMenu(wxMenuBar *menu_bar) +{ + wxMenu *edit_menu; + + edit_menu = new wxMenu(); + edit_menu->Append(EDIT_MENU_UNDO, wxT("&Undo\tCtrl+Z")); + edit_menu->Append(EDIT_MENU_REDO, wxT("&Redo\tCtrl+Shift+Z")); + edit_menu->AppendSeparator(); + edit_menu->Append(EDIT_MENU_CUT, wxT("&Cut\tCtrl+X")); + edit_menu->Append(EDIT_MENU_COPY, wxT("&Copy\tCtrl+C")); + edit_menu->Append(EDIT_MENU_PASTE, wxT("&Paste\tCtrl+V")); + edit_menu->AppendSeparator(); + edit_menu->Append(EDIT_MENU_DELETE, wxT("&Delete")); + + edit_menu->Enable(EDIT_MENU_CUT, false); + edit_menu->Enable(EDIT_MENU_COPY, false); + edit_menu->Enable(EDIT_MENU_PASTE, false); + edit_menu->Enable(EDIT_MENU_DELETE, false); + + // We add the Edit menu to the passed menubar + menu_bar->Append(edit_menu, wxT("&Edit")); +} + +void CreateHelpMenu(wxMenuBar *menu_bar) +{ + wxMenu *help_menu; + + help_menu = new wxMenu(); + help_menu->Append(ABOUT_MENU, wxT("About ShapeFusion")); + help_menu->Append(HELP_MENU, wxT("ShapeFusion Help")); + + menu_bar->Append(help_menu, wxT("&Help")); +} + +void CreateViewMenu(wxMenuBar *menu_bar) +{ + // view menu + wxMenu *view_menu, + *view_colortable_submenu, + *view_tnsize_submenu; + + // We create our two submenus + view_colortable_submenu = new wxMenu(); + for (unsigned int i = 0; i < 8; i++) { + view_colortable_submenu->AppendRadioItem(VIEW_MENU_COLORTABLE_0 + i, wxString::Format(wxT("%d"), i)); + view_colortable_submenu->Enable(VIEW_MENU_COLORTABLE_0 + i, false); + } + + view_tnsize_submenu = new wxMenu(); + view_tnsize_submenu->AppendRadioItem(VIEW_MENU_TNSIZE_SMALL, wxT("Small")); + view_tnsize_submenu->AppendRadioItem(VIEW_MENU_TNSIZE_MEDIUM, wxT("Medium")); + view_tnsize_submenu->AppendRadioItem(VIEW_MENU_TNSIZE_LARGE, wxT("Large")); + view_tnsize_submenu->AppendRadioItem(VIEW_MENU_TNSIZE_AUTO, wxT("Best fit")); + for (unsigned int i = VIEW_MENU_TNSIZE_SMALL; i <= VIEW_MENU_TNSIZE_AUTO; i++) + view_tnsize_submenu->Check(i, i == VIEW_MENU_TNSIZE_MEDIUM); + + // Now the main View menu + view_menu = new wxMenu(); + view_menu->Append(VIEW_MENU_COLOR_TABLE, wxT("Use color table"), view_colortable_submenu); + view_menu->Append(VIEW_MENU_THUMBNAIL_SIZE, wxT("Thumbnail size"), view_tnsize_submenu); + view_menu->AppendCheckItem(VIEW_MENU_TRANSPARENCY, wxT("Show transparent pixels")); + view_menu->AppendCheckItem(VIEW_MENU_CENTERORIGIN, wxT("Fix frame origins")); + + // We add that to the passed menubar + menu_bar->Append(view_menu, wxT("&View")); +} + +void CreateShapesMenu(wxMenuBar *menu_bar) +{ + wxMenu *shapes_menu; + + // We create and build the Shapes menu + shapes_menu = new wxMenu(); + shapes_menu->Append(SHAPES_MENU_ADDCOLORTABLE, wxT("New color table...")); + shapes_menu->Append(SHAPES_MENU_SAVECOLORTABLE, wxT("Export color table to GIMP...")); + shapes_menu->Append(SHAPES_MENU_SAVECOLORTABLETOPS, wxT("Export color table to PhotoShop...")); + shapes_menu->AppendSeparator(); + shapes_menu->Append(SHAPES_MENU_ADDBITMAP, wxT("New bitmap...")); + shapes_menu->Append(SHAPES_MENU_EXPORTBITMAP, wxT("Export bitmap...")); + shapes_menu->Append(SHAPES_MENU_EXPORTMASK, wxT("Export bitmap mask...")); + shapes_menu->Append(SHAPES_MENU_EXPORTBITMAPS, wxT("Export all bitmaps...")); + shapes_menu->Append(SHAPES_MENU_EXPORTMASKS, wxT("Export all bitmap masks...")); + shapes_menu->AppendSeparator(); + shapes_menu->Append(SHAPES_MENU_ADDFRAME, wxT("New frame")); + shapes_menu->AppendSeparator(); + shapes_menu->Append(SHAPES_MENU_ADDSEQUENCE, wxT("New sequence")); + shapes_menu->AppendSeparator(); + shapes_menu->Append(SHAPES_MENU_IMPORTPATCH, wxT("Apply Shapes Patch...")); + shapes_menu->Append(SHAPES_MENU_GENERATEPATCH, wxT("Export Shapes Patch...")); + + // Let's disable all these items... + shapes_menu->Enable(SHAPES_MENU_ADDCOLORTABLE, false); + shapes_menu->Enable(SHAPES_MENU_SAVECOLORTABLE, false); + shapes_menu->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false); + shapes_menu->Enable(SHAPES_MENU_ADDBITMAP, false); + shapes_menu->Enable(SHAPES_MENU_EXPORTBITMAP, false); + shapes_menu->Enable(SHAPES_MENU_EXPORTMASK, false); + shapes_menu->Enable(SHAPES_MENU_EXPORTBITMAPS, false); + shapes_menu->Enable(SHAPES_MENU_EXPORTMASKS, false); + shapes_menu->Enable(SHAPES_MENU_ADDFRAME, false); + shapes_menu->Enable(SHAPES_MENU_ADDSEQUENCE, false); + + // .. and add the whole to the menuBar + menu_bar->Append(shapes_menu, wxT("&Shapes")); +} + +void CreateSoundsMenu(wxMenuBar *menu_bar) +{ + wxMenu *sounds_menu; + + // We create and build the Sounds menu + sounds_menu = new wxMenu(); + sounds_menu->Append(SOUNDS_MENU_ADDCLASS, wxT("Add new sound class")); + sounds_menu->AppendSeparator(); + sounds_menu->Append(SOUNDS_MENU_EXPORT, wxT("Export selected sound")); + sounds_menu->Append(SOUNDS_MENU_IMPORT, wxT("Import sound")); + + // Let's disable them ... + sounds_menu->Enable(SOUNDS_MENU_ADDCLASS, false); + sounds_menu->Enable(SOUNDS_MENU_EXPORT, false); + sounds_menu->Enable(SOUNDS_MENU_IMPORT, false); + + // ... and add the whole to the menu_bar + menu_bar->Append(sounds_menu, wxT("S&ounds")); +} + diff --git a/ShapeFusionMenus.h b/ShapeFusionMenus.h new file mode 100644 index 0000000..aac651a --- /dev/null +++ b/ShapeFusionMenus.h @@ -0,0 +1,101 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SHAPEFUSIONMENUS_H +#define SHAPEFUSIONMENUS_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +enum { + // Application Menus (we just use wx Indexes here) + FILE_MENU_NEW = wxID_NEW, + FILE_MENU_OPEN = wxID_OPEN, + FILE_MENU_CLOSE = wxID_CLOSE, + FILE_MENU_QUIT = wxID_EXIT, + FILE_MENU_SAVE = wxID_SAVE, + FILE_MENU_SAVEAS = wxID_SAVEAS, + FILE_MENU_REVERT = wxID_REVERT, + FILE_MENU_PRINT = wxID_PRINT, + FILE_MENU_PRINT_SETUP = wxID_PRINT_SETUP, + FILE_MENU_PREVIEW = wxID_PREVIEW, + ABOUT_MENU = wxID_ABOUT, + HELP_MENU = wxID_HELP, + FILE_HISTORY_FILE1 = wxID_FILE1, + FILE_HISTORY_FILE9 = wxID_FILE9, + // Edit Menu + EDIT_MENU_UNDO = wxID_UNDO, + EDIT_MENU_REDO = wxID_REDO, + EDIT_MENU_CUT = wxID_CUT, + EDIT_MENU_COPY = wxID_COPY, + EDIT_MENU_PASTE = wxID_PASTE, + EDIT_MENU_DELETE = wxID_DELETE, + // We put our menus that don't come from wx here, + // so they'll have menu ID starting from 1 + FILE_MENU_NEW_SHAPES = 1, + FILE_MENU_NEW_PHYSICS, + FILE_MENU_NEW_MAP, + FILE_MENU_NEW_SOUNDS, + FILE_MENU_OPEN_SHAPES, + FILE_MENU_OPEN_PHYSICS, + FILE_MENU_OPEN_MAP, + FILE_MENU_OPEN_SOUNDS, + FILE_MENU_HISTORY, + // Shapes editing menus + // View Menu + VIEW_MENU_TRANSPARENCY, + VIEW_MENU_CENTERORIGIN, + // Thumbnails submenu + VIEW_MENU_THUMBNAIL_SIZE, + VIEW_MENU_TNSIZE_SMALL, + VIEW_MENU_TNSIZE_MEDIUM, + VIEW_MENU_TNSIZE_LARGE, + VIEW_MENU_TNSIZE_AUTO, + // Color Tables submenu + VIEW_MENU_COLOR_TABLE, + VIEW_MENU_COLORTABLE_0, + VIEW_MENU_COLORTABLE_7 = VIEW_MENU_COLORTABLE_0 + 7, + // Shapes menu + SHAPES_MENU_ADDCOLORTABLE, + SHAPES_MENU_SAVECOLORTABLE, + SHAPES_MENU_SAVECOLORTABLETOPS, + SHAPES_MENU_ADDBITMAP, + SHAPES_MENU_EXPORTBITMAP, + SHAPES_MENU_EXPORTMASK, + SHAPES_MENU_EXPORTBITMAPS, + SHAPES_MENU_EXPORTMASKS, + SHAPES_MENU_ADDFRAME, + SHAPES_MENU_ADDSEQUENCE, + SHAPES_MENU_GENERATEPATCH, + SHAPES_MENU_IMPORTPATCH, + // Sounds menu + SOUNDS_MENU_ADDCLASS, + SOUNDS_MENU_EXPORT, + SOUNDS_MENU_IMPORT +}; + +void CreateFileMenu(wxMenuBar *menu_bar); +void CreateEditMenu(wxMenuBar *menu_bar); +void CreateHelpMenu(wxMenuBar *menu_bar); +void CreateViewMenu(wxMenuBar *menu_bar); +void CreateShapesMenu(wxMenuBar *menu_bar); +void CreateSoundsMenu(wxMenuBar *menu_bar); +#endif + diff --git a/Shapes/BitmapBrowser.cpp b/Shapes/BitmapBrowser.cpp new file mode 100644 index 0000000..e3a69c4 --- /dev/null +++ b/Shapes/BitmapBrowser.cpp @@ -0,0 +1,390 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "wx/image.h" +#include "BitmapBrowser.h" +#include "utilities.h" + +DEFINE_EVENT_TYPE(wxEVT_BITMAPBROWSER) +DEFINE_EVENT_TYPE(wxEVT_BITMAPBROWSER_DELETE) + +BEGIN_EVENT_TABLE(BitmapBrowser, wxScrolledWindow) + EVT_PAINT(BitmapBrowser::OnPaint) + EVT_SIZE(BitmapBrowser::OnSize) + EVT_LEFT_DOWN(BitmapBrowser::OnMouseDown) + EVT_RIGHT_DOWN(BitmapBrowser::OnMouseDown) + EVT_KEY_DOWN(BitmapBrowser::OnKeyDown) +END_EVENT_TABLE() + +BitmapBrowser::BitmapBrowser(wxWindow *parent, wxWindowID id): + wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mColorTable(NULL), mSelection(-1), mNumCols(0), mNumRows(0), mFrozenCount(0) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + mThumbnailPen.SetColour(200, 200, 200); + mSelectionPen.SetColour(0, 0, 0); + mSelectionPen.SetWidth(3); + SetScrollRate(0, 2); + mThumbnailSize = 64; + mMargin = 7; + mWhiteTransparency = true; + mAutoSize = false; +} + +void BitmapBrowser::OnPaint(wxPaintEvent& e) +{ + wxPaintDC tempdc(this); + int cw, ch, rx, ry; + + DoPrepareDC(tempdc); + GetClientSize(&cw, &ch); + CalcUnscrolledPosition(0, 0, &rx, &ry); + // draw thumbnails + tempdc.SetPen(mThumbnailPen); + tempdc.SetBrush(*wxTRANSPARENT_BRUSH); + for (int i = 0; i < (int)mBitmaps.size(); i++) { + int x = mThumbnailPositions[i].x, + y = mThumbnailPositions[i].y; + + if (y + mThumbnailSize < ry) + continue; + if (y > ry + ch) + break; + + int bw = mThumbnails[i].GetWidth(), + bh = mThumbnails[i].GetHeight(); + + if (i == mSelection) { + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + tempdc.SetPen(mSelectionPen); + tempdc.DrawRectangle(x-2, y-2, mThumbnailSize+4, mThumbnailSize+4); + tempdc.SetPen(mThumbnailPen); + } else { + tempdc.DrawRectangle(x-1, y-1, mThumbnailSize+2, mThumbnailSize+2); + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + } + } +} + +// widget resized, recalculate virtual size to correctly wrap thumbnails +void BitmapBrowser::OnSize(wxSizeEvent& e) +{ + UpdateVirtualSize(); +} + +// handle clicks received by the widget +void BitmapBrowser::OnMouseDown(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + // handle bitmap selection + { + int new_selection = -1; + + for (unsigned int i = 0; i < mThumbnailPositions.size(); i++) { + wxRect test(mThumbnailPositions[i].x, mThumbnailPositions[i].y, mThumbnailSize, mThumbnailSize); + + if (test.Contains(mouse)) { + new_selection = i; + break; + } + } + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + + // send selection event + wxCommandEvent event(wxEVT_BITMAPBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + case wxMOUSE_BTN_RIGHT: + break; + } + e.Skip(); +} + +// handle keydown events +void BitmapBrowser::OnKeyDown(wxKeyEvent &e) +{ + switch (e.GetKeyCode()) { + case WXK_LEFT: + case WXK_RIGHT: + case WXK_UP: + case WXK_DOWN: + { + int new_selection = mSelection; + + if (mSelection >= 0 && mSelection < (int)mBitmaps.size()) { + switch (e.GetKeyCode()) { + case WXK_LEFT: + if (mSelection % mNumCols > 0) + new_selection--; + break; + case WXK_RIGHT: + if (mSelection % mNumCols < (mNumCols-1)) + new_selection++; + break; + case WXK_UP: + if (mSelection / mNumCols > 0) + new_selection -= mNumCols; + break; + case WXK_DOWN: + if (mSelection / mNumCols < (mNumRows-1)) + new_selection += mNumCols; + break; + } + } else if (mBitmaps.size() > 0) { + new_selection = 0; + } + if (new_selection != mSelection && new_selection >= 0 + && new_selection < (int)mBitmaps.size()) { + // TODO scroll to show the new selection + mSelection = new_selection; + Refresh(); + + // send bitmap selection event + wxCommandEvent event(wxEVT_BITMAPBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + case WXK_DELETE: + // send a bitmap delete event + if (mSelection >= 0 && mSelection < (int)mBitmaps.size()) { + wxCommandEvent event(wxEVT_BITMAPBROWSER_DELETE, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + break; + default: + e.Skip(); + break; + } +} + +// the Freeze()/Thaw() combo is necessary to get a reasonably +// responsive interface. Otherwise we would be doing bursts +// of UpdateVirtualSize() and potentially RebuildThumbnails() +// every time the user changes collection +void BitmapBrowser::Freeze(void) +{ + mFrozenCount++; +} + +void BitmapBrowser::Thaw(void) +{ + if (mFrozenCount > 0) { + mFrozenCount--; + if (mFrozenCount == 0) { + UpdateVirtualSize(); + Refresh(); + } + } +} + +int BitmapBrowser::GetSelection(void) const +{ + return mSelection; +} + +// set the thumbnail size in pixels. Specify -1 to enable best-fit mode. +void BitmapBrowser::SetThumbnailSize(int size) +{ + if (size > 0) { + mThumbnailSize = size; + mAutoSize = false; + } else { + mAutoSize = true; + } + if (mFrozenCount == 0) { + UpdateVirtualSize(); + if (!mAutoSize) + RebuildThumbnails(); + Refresh(); + } +} + +void BitmapBrowser::SetTranspPixelsDisplay(bool show) +{ + mWhiteTransparency = show; + if (mFrozenCount == 0) { + RebuildThumbnails(); + Refresh(); + } +} + +// add a new ShapesBitmap to the thumbnail list +void BitmapBrowser::AddBitmap(ShapesBitmap *bp) +{ + if (bp != NULL) { + if (bp->Pixels() != NULL) { + mBitmaps.push_back(bp); + mThumbnails.push_back(CreateThumbnail(bp)); + if (mFrozenCount == 0) { + UpdateVirtualSize(); + Refresh(); + } + } else { + wxLogError(wxT("[BitmapBrowser] Added a bitmap with NULL pixels")); + } + } +} + +// clear the thumbnail list +void BitmapBrowser::Clear(void) +{ + mThumbnails.clear(); + mBitmaps.clear(); + mThumbnailPositions.clear(); + mSelection = -1; + UpdateVirtualSize(); + if (mFrozenCount == 0) + Refresh(); +} + +// call before adding bitmaps! +void BitmapBrowser::SetColorTable(ShapesColorTable *ct) +{ + mColorTable = ct; + if (mFrozenCount == 0) { + RebuildThumbnails(); + Refresh(); + } +} + +// calculate and set the wxWindow virtual size, based on the +// number of thumbnails, thumbnail dimensions and given visible +// size. Also pre-calculate thumbnail positions +void BitmapBrowser::UpdateVirtualSize(void) +{ + wxClientDC dc(this); + unsigned int numbitmaps = mBitmaps.size(); + int width, height; + + GetClientSize(&width, &height); + if (numbitmaps < 1) { + SetVirtualSize(0, 0); + return; + } + + if (mAutoSize) { + // calculate the best mThumbnailSize + // (maximum value not requiring window scrolling) + int max_bitmap_dimension = 10, + new_tn_size; + + SetScrollRate(0, 0); + // find greatest dimension among all bitmaps + for (unsigned int i = 0; i < numbitmaps; i++) { + if (mBitmaps[i]->Width() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[i]->Width(); + if (mBitmaps[i]->Height() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[i]->Height(); + } + // FIXME a better algorithm, without looping? + for (new_tn_size = mMargin; ; new_tn_size++) { + int numcols = (width - mMargin) / (new_tn_size + mMargin), + numrows = (numcols > 0) ? (numbitmaps / numcols) : numbitmaps; + + if (numrows * numcols < (int)numbitmaps) + numrows++; + int total_height = numrows * (new_tn_size + mMargin) + mMargin; + + if (total_height > height || (new_tn_size + 2 * mMargin) > width) { + new_tn_size--; + break; + } + if (new_tn_size >= max_bitmap_dimension) { + // no point in wasting window space with huge + // thumbnails showing small bitmaps at their center + new_tn_size = max_bitmap_dimension; + break; + } + } + if (new_tn_size != mThumbnailSize) { + mThumbnailSize = new_tn_size; + RebuildThumbnails(); + } + } else { + SetScrollRate(0, 2); + } + + mNumCols = (width - mMargin) / (mThumbnailSize + mMargin); + mNumRows = (mNumCols > 0) ? (numbitmaps / mNumCols) : numbitmaps; + + if (mNumRows * mNumCols < (int)numbitmaps) + mNumRows++; + + SetVirtualSize(width, mNumRows * (mThumbnailSize + mMargin) + mMargin); + + // recalculate thumbnail positions + int x = mMargin, + y = mMargin; + + mThumbnailPositions.clear(); + for (unsigned int i = 0; i < numbitmaps; i++) { + mThumbnailPositions.push_back(wxPoint(x, y)); + + x += mThumbnailSize + mMargin; + if (x + mThumbnailSize + mMargin > width) { + x = mMargin; + y += mThumbnailSize + mMargin; + } + } +} + +// transform a ShapesBitmap to a wxBitmap thumbnail +wxBitmap BitmapBrowser::CreateThumbnail(ShapesBitmap *bp) +{ + wxImage newimg; + + if (mColorTable) + newimg = ShapesBitmapToImage(bp, mColorTable, mWhiteTransparency); + return ImageThumbnail(newimg, mThumbnailSize, true); +} + +void BitmapBrowser::RebuildThumbnail(unsigned int i) +{ + if (i < mBitmaps.size()) + mThumbnails[i] = CreateThumbnail(mBitmaps[i]); +} + +// just re-decode the ShapesBitmaps to their thumbnail previews, +// without touching window sizes or thumbnail positions. +// Useful to update the display at the end of SetColorTable or after +// altering the ShapesBitmaps +void BitmapBrowser::RebuildThumbnails(void) +{ + for (unsigned int i = 0; i < mBitmaps.size(); i++) + mThumbnails[i] = CreateThumbnail(mBitmaps[i]); +} + diff --git a/Shapes/BitmapBrowser.h b/Shapes/BitmapBrowser.h new file mode 100644 index 0000000..8ba3b2e --- /dev/null +++ b/Shapes/BitmapBrowser.h @@ -0,0 +1,83 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// BitmapBrowser +// A widget for displaying a list of ShapesBitmap's as a scrollable list +// of selectable thumbnails, which tries to fill the width of the widget +// and flow accordingly. +// + +#ifndef BITMAPBROWSER_H +#define BITMAPBROWSER_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_BITMAPBROWSER, -1) +DECLARE_EVENT_TYPE(wxEVT_BITMAPBROWSER_DELETE, -1) + +class BitmapBrowser: public wxScrolledWindow { +private: + vector mBitmaps; // pointers to the encoded bitmaps + vector mThumbnails; // scaled/rendered bitmap thumbnails + ShapesColorTable *mColorTable; // which palette to use for display + vector mThumbnailPositions; // thumbnail positions within window + wxCoord mThumbnailSize, + mMargin; // margin between thumbnails and window edges + bool mAutoSize, // auto-calculate best thumbnail size + mWhiteTransparency; // hide transparent pixels + int mSelection, // selected thumbnail + mNumCols, + mNumRows; + wxPen mThumbnailPen, + mSelectionPen; + unsigned int mFrozenCount; + + wxBitmap CreateThumbnail(ShapesBitmap *bp); + void UpdateVirtualSize(void); + +protected: + DECLARE_EVENT_TABLE(); + +public: + BitmapBrowser(wxWindow *parent, wxWindowID id); + // event handlers + void OnPaint(wxPaintEvent& e); + void OnSize(wxSizeEvent& e); + void OnMouseDown(wxMouseEvent& e); + void OnKeyDown(wxKeyEvent& e); + // wx things + void Freeze(void); + void Thaw(void); + // access + int GetSelection(void) const; + void SetThumbnailSize(int size); + void SetTranspPixelsDisplay(bool show); + void AddBitmap(ShapesBitmap *bp); + void SetColorTable(ShapesColorTable *ct); + void Clear(void); + // utilities + void RebuildThumbnail(unsigned int i); + void RebuildThumbnails(void); +}; + +#endif diff --git a/Shapes/BitmapView.cpp b/Shapes/BitmapView.cpp new file mode 100644 index 0000000..c949df6 --- /dev/null +++ b/Shapes/BitmapView.cpp @@ -0,0 +1,140 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "BitmapView.h" +#include "utilities.h" + +BEGIN_EVENT_TABLE(BitmapView, wxScrolledWindow) + EVT_PAINT(BitmapView::OnPaint) + EVT_LEFT_DOWN(BitmapView::OnDrag) + EVT_LEFT_UP(BitmapView::OnDrag) + EVT_MOTION(BitmapView::OnDrag) + EVT_SIZE(BitmapView::OnSize) +END_EVENT_TABLE() + +BitmapView::BitmapView(wxWindow *parent): + wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mEncBmp(NULL), mColorTable(NULL), mDragging(false) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + SetScrollRate(1, 1); + mWhiteTransparency = true; + mInvisiblePen.SetColour(255, 255, 255); +} + +void BitmapView::OnPaint(wxPaintEvent& e) +{ + wxPaintDC tempdc(this); + int vw, vh, cw, ch; + + GetVirtualSize(&vw, &vh); + DoPrepareDC(tempdc); + GetClientSize(&cw, &ch); + tempdc.SetPen(mInvisiblePen); + if (mEncBmp != NULL && mColorTable != NULL) + tempdc.DrawBitmap(mDecBmp, vw/2 - mDecBmp.GetWidth()/2, vh/2 - mDecBmp.GetHeight()/2); +} + +// handle mouse drag (pan view) +void BitmapView::OnDrag(wxMouseEvent &e) +{ + if (e.ButtonDown()) { + // start panning + int scroll_x, scroll_y; + + GetViewStart(&scroll_x, &scroll_y); + mDragging = true; + mDragStartX = e.GetPosition().x + scroll_x; + mDragStartY = e.GetPosition().y + scroll_y; + } else if (e.Dragging() && mDragging) { + // pan + int dx = mDragStartX - e.GetPosition().x, + dy = mDragStartY - e.GetPosition().y; + + Scroll(dx, dy); + } else if (e.ButtonUp()) { + // end panning + mDragging = false; + } +} + +void BitmapView::OnSize(wxSizeEvent &e) +{ + int cw, ch, + vw = (mEncBmp == NULL) ? 0 : mEncBmp->Width(), + vh = (mEncBmp == NULL) ? 0 : mEncBmp->Height(); + + GetClientSize(&cw, &ch); + if (vw < cw) + vw = cw; + if (vh < ch) + vh = ch; + SetVirtualSize(vw, vh); +} + +void BitmapView::SetTranspPixelsDisplay(bool show) +{ + mWhiteTransparency = show; + if (mEncBmp != NULL && mEncBmp->Pixels() != NULL && mColorTable != NULL) + mDecBmp = wxBitmap(ShapesBitmapToImage(mEncBmp, mColorTable, mWhiteTransparency)); + Refresh(); +} + +// add a new ShapesBitmap to the thumbnail list +void BitmapView::SetBitmap(ShapesBitmap *bp) +{ + mEncBmp = bp; + if (mEncBmp != NULL) { + if (mEncBmp->Pixels() != NULL) { + // adjust sizes + int cw, ch, + vw = mEncBmp->Width(), + vh = mEncBmp->Height(); + + GetClientSize(&cw, &ch); + if (vw < cw) + vw = cw; + if (vh < ch) + vh = ch; + SetVirtualSize(vw, vh); + // decode bitmap + if (mColorTable != NULL) + mDecBmp = wxBitmap(ShapesBitmapToImage(mEncBmp, mColorTable, mWhiteTransparency)); + Refresh(); + } else { + wxLogError(wxT("[BitmapView] Addes a bitmap with NULL pixels")); + SetVirtualSize(0, 0); + } + } else { + SetVirtualSize(0, 0); + } +} + +ShapesBitmap *BitmapView::GetBitmap(void) const +{ + return mEncBmp; +} + +// call this before SettingBitmap! +void BitmapView::SetColorTable(ShapesColorTable *ct) +{ + mColorTable = ct; + if (mEncBmp != NULL && mEncBmp->Pixels() != NULL && mColorTable != NULL) + mDecBmp = wxBitmap(ShapesBitmapToImage(mEncBmp, mColorTable, mWhiteTransparency)); + Refresh(); +} + diff --git a/Shapes/BitmapView.h b/Shapes/BitmapView.h new file mode 100644 index 0000000..60bf8c6 --- /dev/null +++ b/Shapes/BitmapView.h @@ -0,0 +1,61 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// BitmapView +// A widget for displaying a single, full size ShapesBitmap +// + +#ifndef BITMAPVIEW_H +#define BITMAPVIEW_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +class BitmapView: public wxScrolledWindow { +private: + ShapesBitmap *mEncBmp; // encoded bitmap + wxBitmap mDecBmp; // ready-to-draw bitmap + ShapesColorTable *mColorTable; // which palette to use for display + bool mWhiteTransparency; // hide transparent pixels + wxPen mInvisiblePen; + + bool mDragging; + int mDragStartX, + mDragStartY; + +protected: + DECLARE_EVENT_TABLE(); + +public: + BitmapView(wxWindow *parent); + // event handlers + void OnPaint(wxPaintEvent &e); + void OnSize(wxSizeEvent &e); + void OnDrag(wxMouseEvent &e); + // access + void SetTranspPixelsDisplay(bool show); + void SetBitmap(ShapesBitmap *bp); + ShapesBitmap *GetBitmap(void) const; + void SetColorTable(ShapesColorTable *ct); +}; + +#endif diff --git a/Shapes/CTBrowser.cpp b/Shapes/CTBrowser.cpp new file mode 100644 index 0000000..ccffd1c --- /dev/null +++ b/Shapes/CTBrowser.cpp @@ -0,0 +1,204 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "CTBrowser.h" + +DEFINE_EVENT_TYPE(wxEVT_CTBROWSER) + +BEGIN_EVENT_TABLE(CTBrowser, wxScrolledWindow) + EVT_PAINT(CTBrowser::OnPaint) + EVT_SIZE(CTBrowser::OnSize) + EVT_LEFT_DOWN(CTBrowser::OnMouseDown) + EVT_KEY_DOWN(CTBrowser::OnKeyDown) +END_EVENT_TABLE() + +CTBrowser::CTBrowser(wxWindow *parent): + wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mSampleW(1), mSampleH(20), mSelection(-1) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + mInvisiblePen.SetColour(0, 0, 0); + mInvisiblePen.SetStyle(wxTRANSPARENT); + mSelectionPen.SetColour(0, 0, 0); + mSelectionPen.SetWidth(3); + SetScrollRate(2, 2); + mMargin = 10; +} + +void CTBrowser::OnPaint(wxPaintEvent& e) +{ + wxPaintDC tempdc(this); + int visible_w, visible_h, + x = mMargin, y = mMargin; + + DoPrepareDC(tempdc); + GetClientSize(&visible_w, &visible_h); + tempdc.SetPen(mInvisiblePen); + // draw color samples + for (unsigned int i = 0; i < mColorTables.size(); i++) { + wxBrush brush(wxColour(0, 0, 0), wxSOLID); + + // mark selected ct + if ((int)i == mSelection) { + tempdc.SetPen(mSelectionPen); + tempdc.SetBrush(*wxWHITE_BRUSH); + tempdc.DrawRectangle(x-3, y-3, mSampleW*mColorsPerTable+6, mSampleH+6); + tempdc.SetPen(mInvisiblePen); + tempdc.SetBrush(*wxTRANSPARENT_BRUSH); + } + // draw a square for each color + for (unsigned int j = 0; j < mColorsPerTable; j++) { + brush.SetColour(mColorTables[i]->GetColor(j)->Red() >> 8, + mColorTables[i]->GetColor(j)->Green() >> 8, + mColorTables[i]->GetColor(j)->Blue() >> 8); + tempdc.SetBrush(brush); + tempdc.DrawRectangle(x, y, mSampleW, mSampleH); + if (mColorTables[i]->GetColor(j)->Luminescent()) { + // display the self-luminescent color flag + tempdc.SetBrush(*wxWHITE_BRUSH); + tempdc.DrawRectangle(x + 2, y + 2, 2, 2); + } + x += mSampleW; + } + x = mMargin; + y += mSampleH + mMargin; + } +} + +// widget resized, recalculate virtual size to correctly wrap thumbnails +void CTBrowser::OnSize(wxSizeEvent& e) +{ + UpdateVirtualSize(); +} + +void CTBrowser::OnMouseDown(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: // ct selection + { + int new_selection = -1; + + for (unsigned int i = 0; i < mColorTables.size(); i++) { + wxRect test(mMargin, mMargin + i * (mSampleH + mMargin), mSampleW*mColorsPerTable, mSampleH); + + if (test.Contains(mouse)) { + new_selection = i; + break; + } + } + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + // send selection event + wxCommandEvent event(wxEVT_CTBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + } + e.Skip(); +} + +void CTBrowser::OnKeyDown(wxKeyEvent &e) +{ + int new_selection = mSelection; + + if (mSelection >= 0 && mSelection < (int)mColorTables.size()) { + // arrow keys move the selection + switch (e.GetKeyCode()) { + case WXK_UP: + if (mSelection > 0) + new_selection--; + break; + case WXK_DOWN: + if (mSelection < ((int)mColorTables.size()-1)) + new_selection++; + break; + default: + e.Skip(); + } + } else if (mColorTables.size() > 0 && (e.GetKeyCode() == WXK_UP || e.GetKeyCode() == WXK_DOWN)) { + new_selection = 0; + } + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + // send selection event + wxCommandEvent event(wxEVT_CTBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } +} + +// add a new ShapesColorTable to the list +void CTBrowser::AddColorTable(ShapesColorTable *ctp) +{ + if (ctp == NULL) + return; + mColorsPerTable = ctp->ColorCount(); + mColorTables.push_back(ctp); + UpdateVirtualSize(); + Refresh(); +} + +// clear the color table list +void CTBrowser::Clear(void) +{ + mColorTables.clear(); + mSelection = -1; + mColorsPerTable = 0; + UpdateVirtualSize(); +// Refresh(); // not needed since the ShapesEditor only clears before refilling +} + +int CTBrowser::GetSelection(void) const +{ + return mSelection; +} + +// calculate and set the wxWindow virtual size, +// based on the number of color tables, colors per table, +// color sample dimensions and given visible size +void CTBrowser::UpdateVirtualSize(void) +{ + wxClientDC dc(this); + int numcts = mColorTables.size(), + width, height; + + GetClientSize(&width, &height); + // calculate best sample_w + for (int w = 1; w < mSampleH; w++) { + if (2*mMargin + w*(int)mColorsPerTable > width) { + mSampleW = w - 1; + break; + } + } + if (mSampleW < 1) + mSampleW = 1; + SetVirtualSize(2*mMargin + mSampleW*mColorsPerTable, mMargin + numcts * (mSampleH + mMargin)); +} + diff --git a/Shapes/CTBrowser.h b/Shapes/CTBrowser.h new file mode 100644 index 0000000..6c05b50 --- /dev/null +++ b/Shapes/CTBrowser.h @@ -0,0 +1,66 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// CTBrowser +// Widget for displaying a list of ShapesColorTable's. Each color table +// is show as a matrix of color samples. The width of each sample will +// adjust to fit inside the available widget width, while the sample +// height is fixed. +// + +#ifndef CTBROWSER_H +#define CTBROWSER_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_CTBROWSER, -1) + +class CTBrowser: public wxScrolledWindow { +private: + vector mColorTables; // array of pointers to color tables + unsigned int mColorsPerTable; + wxCoord mSampleW, mSampleH, // size of color samples + mMargin; + wxPen mInvisiblePen, + mSelectionPen; + int mSelection; + + void UpdateVirtualSize(void); + +protected: + DECLARE_EVENT_TABLE(); + +public: + CTBrowser(wxWindow *parent); + void OnPaint(wxPaintEvent& e); + void OnSize(wxSizeEvent& e); + void OnMouseDown(wxMouseEvent& e); + void OnKeyDown(wxKeyEvent &e); + + void AddColorTable(ShapesColorTable *ctp); + void Clear(void); + + int GetSelection(void) const; +}; + +#endif diff --git a/Shapes/CTView.cpp b/Shapes/CTView.cpp new file mode 100644 index 0000000..19bf18d --- /dev/null +++ b/Shapes/CTView.cpp @@ -0,0 +1,242 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "CTView.h" +#include + +DEFINE_EVENT_TYPE(wxEVT_CTVIEW_SELECTION) +DEFINE_EVENT_TYPE(wxEVT_CTVIEW_COLOR) + +BEGIN_EVENT_TABLE(CTView, wxPanel) + EVT_PAINT(CTView::OnPaint) + EVT_SIZE(CTView::OnSize) + EVT_LEFT_DOWN(CTView::OnMouseDown) + EVT_LEFT_DCLICK(CTView::OnMouseDoubleClick) +END_EVENT_TABLE() + +// icon for the self-luminescent flag +static char *self_luminescent_icon_xpm[] = { +"8 8 2 1", +" c None", +". c #000000", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ..... ", +" ...... ", +" "}; + +CTView::CTView(wxWindow *parent): + wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mColorTable(NULL), mSwatchSize(0), mMargin(7), mLightBulbIcon(self_luminescent_icon_xpm) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + mInvisiblePen.SetColour(0, 0, 0); + mInvisiblePen.SetStyle(wxTRANSPARENT); + mSelectionPen.SetColour(0, 0, 0); + mSelectionPen.SetWidth(3); +} + +void CTView::OnPaint(wxPaintEvent& e) +{ + if (mColorTable == NULL) + return; + + wxPaintDC tempdc(this); + wxBrush brush(wxColour(0, 0, 0), wxSOLID); + unsigned int x = mMargin, y = mMargin; + int width, height; + + tempdc.GetSize(&width, &height); + tempdc.SetPen(mInvisiblePen); + for (unsigned int j = 0; j < mColorTable->ColorCount(); j++) { + // draw selection marker + if (mSelectionMask[j]) { + tempdc.SetPen(mSelectionPen); + tempdc.SetBrush(*wxWHITE_BRUSH); + tempdc.DrawRectangle(x-3, y-3, mSwatchSize+6, mSwatchSize+6); + tempdc.SetPen(mInvisiblePen); + } + // draw color swatch + brush.SetColour(mColorTable->GetColor(j)->Red() >> 8, + mColorTable->GetColor(j)->Green() >> 8, + mColorTable->GetColor(j)->Blue() >> 8); + tempdc.SetBrush(brush); + tempdc.DrawRectangle(x, y, mSwatchSize, mSwatchSize); + if (mColorTable->GetColor(j)->Luminescent()) { + // display self-luminescent color flag + tempdc.SetBrush(*wxWHITE_BRUSH); + tempdc.DrawBitmap(mLightBulbIcon, x, y + mSwatchSize - mLightBulbIcon.GetHeight(), true); + } + x += mSwatchSize + mMargin; + if ((int)(x + mSwatchSize + mMargin) >= width) { + x = mMargin; + y += mSwatchSize + mMargin; + } + } +} + +void CTView::OnSize(wxSizeEvent &e) +{ + CalculateSwatchSize(); +} + +void CTView::OnMouseDown(wxMouseEvent& e) +{ + wxPoint mouse = e.GetPosition(); + unsigned int x = mMargin, y = mMargin; + int width, height; + bool found = false; + + GetClientSize(&width, &height); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + // first deselect all, if we're not doing multiple selection + if (!wxGetMouseState().ShiftDown()) { + for (unsigned int j = 0; j < mColorTable->ColorCount(); j++) + mSelectionMask[j] = false; + } + // check for clicks inside a color swatch + for (unsigned int j = 0; j < mColorTable->ColorCount(); j++) { + wxRect test(x, y, mSwatchSize, mSwatchSize); + + if (test.Contains(mouse)) { + mSelectionMask[j] = true; + found = true; + break; + } + x += mSwatchSize + mMargin; + if ((int)(x + mSwatchSize + mMargin) >= width) { + x = mMargin; + y += mSwatchSize + mMargin; + } + } + Refresh(); + // send selection event (telling just how many items are selected) + { + wxCommandEvent event(wxEVT_CTVIEW_SELECTION, GetId()); + int selectedCount = 0; + + for (unsigned int j = 0; j < mColorTable->ColorCount(); j++) + selectedCount += mSelectionMask[j] ? 1 : 0; + event.SetEventObject(this); + event.SetInt(selectedCount); + GetEventHandler()->ProcessEvent(event); + } + break; + } + e.Skip(); +} + +// handle double-clicks on swatches, showing the +// color chooser to alter the swatch color +void CTView::OnMouseDoubleClick(wxMouseEvent& e) +{ + wxPoint mouse = e.GetPosition(); + unsigned int x = mMargin, y = mMargin; + int width, height; + + GetClientSize(&width, &height); + for (unsigned int j = 0; j < mColorTable->ColorCount(); j++) { + wxRect test(x, y, mSwatchSize, mSwatchSize); + + if (test.Contains(mouse)) { + // FIXME is it ok to set the CTView as the parent? + wxColour newColor = ::wxGetColourFromUser(this, + wxColour(mColorTable->GetColor(j)->Red() >> 8, + mColorTable->GetColor(j)->Green() >> 8, + mColorTable->GetColor(j)->Blue() >> 8)); + + if (newColor.Ok()) { + mColorTable->GetColor(j)->SetRed(newColor.Red() << 8); + mColorTable->GetColor(j)->SetGreen(newColor.Green() << 8); + mColorTable->GetColor(j)->SetBlue(newColor.Blue() << 8); + } + Refresh(); + // send an event to let the world know + wxCommandEvent event(wxEVT_CTVIEW_COLOR, GetId()); + + event.SetEventObject(this); + event.SetInt(j); + GetEventHandler()->ProcessEvent(event); + break; + } + x += mSwatchSize + mMargin; + if ((int)(x + mSwatchSize + mMargin) >= width) { + x = mMargin; + y += mSwatchSize + mMargin; + } + } + e.Skip(); +} + +void CTView::SetColorTable(ShapesColorTable *ct) +{ + bool need_recalc = (ct != NULL) && (mColorTable != NULL) + && (ct->ColorCount() != mColorTable->ColorCount()); + + mColorTable = ct; + // update selection mask + mSelectionMask.clear(); + if (mColorTable != NULL) { + for (unsigned int i = 0; i < mColorTable->ColorCount(); i++) + mSelectionMask.push_back(false); + } + // visual updates + if (need_recalc) + CalculateSwatchSize(); + Refresh(); +} + +vector CTView::GetSelection(void) const +{ + return mSelectionMask; +} + +// calculate best swatch size fitting into the widget area +void CTView::CalculateSwatchSize(void) +{ + if (mColorTable != NULL) { + int width, height; + unsigned int new_swatch_size = 2; + + GetVirtualSize(&width, &height); + mSwatchSize = 0; + while (mSwatchSize == 0) { + // FIXME faster & more elegant math please + unsigned int x = mMargin, y = mMargin; + + for (unsigned int i = 0; i < mColorTable->ColorCount(); i++) { + x += new_swatch_size + mMargin; + if ((int)(x + new_swatch_size + mMargin) >= width) { + x = mMargin; + y += new_swatch_size + mMargin; + if ((int)(y + new_swatch_size + mMargin) >= height) { + mSwatchSize = new_swatch_size - 1; + break; + } + } + } + new_swatch_size++; + } + } else { + mSwatchSize = 0; + } +} + diff --git a/Shapes/CTView.h b/Shapes/CTView.h new file mode 100644 index 0000000..3f6886d --- /dev/null +++ b/Shapes/CTView.h @@ -0,0 +1,64 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// CTView +// A widget for displaying a ShapesColorTable. We don't derive +// wxScrolledWindow because IMO the purpose of the widget doesn't +// require scrolling. +// + +#ifndef CTVIEW_H +#define CTVIEW_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_CTVIEW_SELECTION, -1) +DECLARE_EVENT_TYPE(wxEVT_CTVIEW_COLOR, -1) + +class CTView: public wxPanel { +private: + ShapesColorTable *mColorTable; // link to the color table + wxPen mInvisiblePen, + mSelectionPen; + unsigned int mSwatchSize, + mMargin; + wxBitmap mLightBulbIcon; + vector mSelectionMask; + +protected: + DECLARE_EVENT_TABLE(); + void CalculateSwatchSize(void); + +public: + CTView(wxWindow *parent); + // event handlers + void OnPaint(wxPaintEvent &e); + void OnSize(wxSizeEvent &e); + void OnMouseDown(wxMouseEvent& e); + void OnMouseDoubleClick(wxMouseEvent& e); + // access + void SetColorTable(ShapesColorTable *ct); + vector GetSelection(void) const; +}; + +#endif diff --git a/Shapes/FrameBrowser.cpp b/Shapes/FrameBrowser.cpp new file mode 100644 index 0000000..025df93 --- /dev/null +++ b/Shapes/FrameBrowser.cpp @@ -0,0 +1,428 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +// +// FrameBrowser +// A widget for displaying a list of ShapesFrame's +// as a scrollable list of selectable thumbnails. Each thumbnail +// displays the frame's associated bitmap, altered with +// the specified mirror transformations. +// +#include "wx/image.h" +#include "FrameBrowser.h" +#include "utilities.h" + +DEFINE_EVENT_TYPE(wxEVT_FRAMEBROWSER) +DEFINE_EVENT_TYPE(wxEVT_FRAMEBROWSER_DELETE) + +BEGIN_EVENT_TABLE(FrameBrowser, wxScrolledWindow) + EVT_PAINT(FrameBrowser::OnPaint) + EVT_SIZE(FrameBrowser::OnSize) + EVT_LEFT_DOWN(FrameBrowser::OnMouseDown) + EVT_RIGHT_DOWN(FrameBrowser::OnMouseDown) + EVT_KEY_DOWN(FrameBrowser::OnKeyDown) +END_EVENT_TABLE() + +FrameBrowser::FrameBrowser(wxWindow *parent, wxWindowID id): + wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mColorTable(NULL), mNumCols(0), mNumRows(0), mFrozenCount(0) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + mThumbnailPen.SetColour(200, 200, 200); + mSelectionPen.SetColour(0, 0, 0); + mSelectionPen.SetWidth(3); + SetScrollRate(0, 2); + mThumbnailSize = 64; + mAutoSize = false; + mMargin = 7; + mWhiteTransparency = true; + mSelection = -1; +} + +void FrameBrowser::OnPaint(wxPaintEvent& e) +{ + wxPaintDC tempdc(this); + int cw, ch, rx, ry; + + DoPrepareDC(tempdc); + GetClientSize(&cw, &ch); + CalcUnscrolledPosition(0, 0, &rx, &ry); + // draw thumbnails + tempdc.SetPen(mThumbnailPen); + tempdc.SetBrush(*wxTRANSPARENT_BRUSH); + for (unsigned int i = 0; i < mThumbnails.size(); i++) { + int x = mThumbnailPositions[i].x, + y = mThumbnailPositions[i].y; + + if (y + mThumbnailSize < ry) + continue; + if (y > ry + ch) + break; + + int bw = mThumbnails[i].GetWidth(), + bh = mThumbnails[i].GetHeight(); + + if ((int)i == mSelection) { + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + tempdc.SetPen(mSelectionPen); + tempdc.DrawRectangle(x-2, y-2, mThumbnailSize+4, mThumbnailSize+4); + tempdc.SetPen(mThumbnailPen); + } else { + tempdc.DrawRectangle(x-1, y-1, mThumbnailSize+2, mThumbnailSize+2); + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + } + } +} + +// widget resized, recalculate virtual size to correctly wrap thumbnails +void FrameBrowser::OnSize(wxSizeEvent& e) +{ + UpdateVirtualSize(); +} + +void FrameBrowser::OnMouseDown(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + // handle frame selection + { + int new_selection = -1; + + for (unsigned int i = 0; i < mThumbnailPositions.size(); i++) { + wxRect test(mThumbnailPositions[i].x, mThumbnailPositions[i].y, + mThumbnailSize, mThumbnailSize); + + if (test.Contains(mouse)) { + new_selection = i; + break; + } + } + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + + // send selection event + wxCommandEvent event(wxEVT_FRAMEBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + case wxMOUSE_BTN_RIGHT: + break; + } + e.Skip(); +} + +void FrameBrowser::OnKeyDown(wxKeyEvent &e) +{ + switch (e.GetKeyCode()) { + case WXK_LEFT: + case WXK_RIGHT: + case WXK_UP: + case WXK_DOWN: + { + int new_selection = mSelection; + + if (mSelection >= 0 && mSelection < (int)mFrames.size()) { + switch (e.GetKeyCode()) { + case WXK_LEFT: + if (mSelection % mNumCols > 0) + new_selection--; + break; + case WXK_RIGHT: + if (mSelection % mNumCols < (mNumCols-1)) + new_selection++; + break; + case WXK_UP: + if (mSelection / mNumCols > 0) + new_selection -= mNumCols; + break; + case WXK_DOWN: + if (mSelection / mNumCols < (mNumRows-1)) + new_selection += mNumCols; + break; + } + } else if (mFrames.size() > 0) { + new_selection = 0; + } + if (new_selection != mSelection && new_selection >= 0 + && new_selection < (int)mFrames.size()) { + // TODO scroll to show the new selection + mSelection = new_selection; + Refresh(); + + // send frame selection event + wxCommandEvent event(wxEVT_FRAMEBROWSER, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + case WXK_DELETE: + // send a frame delete event + if (mSelection >= 0 && mSelection < (int)mFrames.size()) { + wxCommandEvent event(wxEVT_FRAMEBROWSER_DELETE, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + break; + default: + e.Skip(); + break; + } +} + +// the Freeze()/Thaw() combo is necessary to get a reasonably +// responsive interface. Otherwise we would be doing bursts +// of UpdateVirtualSize() and potentially RebuildThumbnails() +// every time the user changes collection +void FrameBrowser::Freeze(void) +{ + mFrozenCount++; +} + +void FrameBrowser::Thaw(void) +{ + if (mFrozenCount > 0) { + mFrozenCount--; + if (mFrozenCount == 0) { + UpdateVirtualSize(); + Refresh(); + } + } +} + +int FrameBrowser::GetSelection(void) const +{ + return mSelection; +} + +void FrameBrowser::SetThumbnailSize(int size) +{ + if (size > 0) { + mThumbnailSize = size; + mAutoSize = false; + } else { + mAutoSize = true; + } + if (mFrozenCount == 0) { + UpdateVirtualSize(); + if (!mAutoSize) + RebuildThumbnails(); + Refresh(); + } +} + +void FrameBrowser::SetTranspPixelsDisplay(bool show) +{ + mWhiteTransparency = show; + if (mFrozenCount == 0) { + RebuildThumbnails(); + Refresh(); + } +} + +// add a new ShapesFrame to the thumbnail list +void FrameBrowser::AddFrame(ShapesFrame *fp) +{ + if (fp != NULL) { + mFrames.push_back(fp); + mThumbnails.push_back(CreateThumbnail(fp)); + if (mFrozenCount == 0) { + UpdateVirtualSize(); + Refresh(); + } + } +} + +// add a ShapesBitmap to the bitmap pointer list. +// Call before adding frames! +void FrameBrowser::AddBitmap(ShapesBitmap *bp) +{ + if (bp != NULL) { + if (bp->Pixels() != NULL) + mBitmaps.push_back(bp); + else + wxLogError(wxT("FrameBrowser: someone tried to add a bitmap with NULL pixels")); + } +} + +// clear the thumbnail list +void FrameBrowser::Clear(void) +{ + mThumbnails.clear(); + mFrames.clear(); + mBitmaps.clear(); + mThumbnailPositions.clear(); + mSelection = -1; + if (mFrozenCount == 0) { + UpdateVirtualSize(); + Refresh(); + } +} + +// clear just the bitmap pointer list +void FrameBrowser::ClearBitmaps(void) +{ + mBitmaps.clear(); +} + +// call before adding frames! +void FrameBrowser::SetColorTable(ShapesColorTable *ct) +{ + mColorTable = ct; + if (mFrozenCount == 0) { + RebuildThumbnails(); + Refresh(); + } +} + +// calculate and set the wxWindow virtual size, based on the +// number of thumbnails, thumbnail dimensions and given visible +// size. Also pre-calculate thumbnail positions +void FrameBrowser::UpdateVirtualSize(void) +{ + wxClientDC dc(this); + int numframes = mThumbnails.size(), + width, height; + + GetClientSize(&width, &height); + if (numframes < 1) { + SetVirtualSize(0, 0); + return; + } + + if (mAutoSize && numframes > 0) { + // calculate the best tn_size + // (its maximum value not requiring window scrolling) + int max_bitmap_dimension = 10, + new_tn_size; + + SetScrollRate(0, 0); + // find greatest dimension among all referenced bitmaps + for (unsigned int i = 0; i < mFrames.size(); i++) { + int bitmapindex = mFrames[i]->BitmapIndex(); + + if (bitmapindex < 0 || bitmapindex >= (int)mBitmaps.size()) + continue; + if (mBitmaps[bitmapindex]->Width() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[bitmapindex]->Width(); + if (mBitmaps[bitmapindex]->Height() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[bitmapindex]->Height(); + } + // start with a small size (margin) and increase it until overflow + for (new_tn_size = mMargin; ; new_tn_size++) { + int numcols = (width - mMargin) / (new_tn_size + mMargin), + numrows = (numcols > 0) ? (numframes / numcols) : numframes; + + if (numrows * numcols < numframes) + numrows++; + int total_height = numrows * (new_tn_size + mMargin) + mMargin; + + if (total_height > height || (new_tn_size + 2 * mMargin) > width) { + // here we are + new_tn_size--; + break; + } + if (new_tn_size >= max_bitmap_dimension) { + // no point in wasting window space with huge + // thumbnails showing small bitmaps at their center + new_tn_size = max_bitmap_dimension; + break; + } + } + if (new_tn_size != mThumbnailSize) { + mThumbnailSize = new_tn_size; + RebuildThumbnails(); + } + } else { + SetScrollRate(0, 2); + } + + mNumCols = (width - mMargin) / (mThumbnailSize + mMargin); + mNumRows = (mNumCols > 0) ? (numframes / mNumCols) : numframes; + + if (mNumRows * mNumCols < numframes) + mNumRows++; + + SetVirtualSize(width, mNumRows * (mThumbnailSize + mMargin) + mMargin); + + // recalculate thumbnail positions + int x = mMargin, y = mMargin; + + mThumbnailPositions.clear(); + for (int i = 0; i < numframes; i++) { + mThumbnailPositions.push_back(wxPoint(x, y)); + + x += mThumbnailSize + mMargin; + if (x + mThumbnailSize + mMargin > width) { + x = mMargin; + y += mThumbnailSize + mMargin; + } + } +} + +// transform an ShapesFrame to a wxBitmap thumbnail +wxBitmap FrameBrowser::CreateThumbnail(ShapesFrame *fp) +{ + if (fp->BitmapIndex() < 0 || fp->BitmapIndex() >= (int)mBitmaps.size()) { + // invalid or unset bitmap + return BadThumbnail(mThumbnailSize); + } else { + // valid bitmap + ShapesBitmap *bp = mBitmaps[fp->BitmapIndex()]; + wxImage newimg(bp->Width(), bp->Height()); + + // decode the bitmap to a wxImage + if (mColorTable) + newimg = ShapesBitmapToImage(bp, mColorTable, mWhiteTransparency); + + // apply frame transformations + if (fp->IsXmirrored()) + newimg = newimg.Mirror(true); + if (fp->IsYmirrored()) + newimg = newimg.Mirror(false); + + return ImageThumbnail(newimg, mThumbnailSize, true); + } +} + +void FrameBrowser::RebuildThumbnail(unsigned int i) +{ + if (i < mThumbnails.size() && i < mFrames.size()) + mThumbnails[i] = CreateThumbnail(mFrames[i]); +} + +// redecode frames to bitmaps (after color table change, frame parameter variations etc) +void FrameBrowser::RebuildThumbnails(void) +{ + for (unsigned int i = 0; i < mFrames.size(); i++) + mThumbnails[i] = CreateThumbnail(mFrames[i]); +} + diff --git a/Shapes/FrameBrowser.h b/Shapes/FrameBrowser.h new file mode 100644 index 0000000..a728869 --- /dev/null +++ b/Shapes/FrameBrowser.h @@ -0,0 +1,86 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// FrameBrowser +// A widget for displaying a list of ShapesFrame's as a scrollable list +// of selectable thumbnails. Each thumbnail displays the frame's +// associated bitmap, altered with the specified mirror transformations. +// + +#ifndef FRAMEBROWSER_H +#define FRAMEBROWSER_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_FRAMEBROWSER, -1) +DECLARE_EVENT_TYPE(wxEVT_FRAMEBROWSER_DELETE, -1) + +class FrameBrowser: public wxScrolledWindow { +private: + vector mFrames; // pointers to frames + vector mBitmaps; // pointers to bitmaps + vector mThumbnails; // scaled/rendered frame thumbnails + ShapesColorTable *mColorTable; // which palette to use for display + vector mThumbnailPositions; // thumbnail positions within window + wxCoord mThumbnailSize, + mMargin; // margin between thumbnails and window edges + bool mAutoSize, + mWhiteTransparency; + int mSelection, + mNumCols, + mNumRows; + wxPen mThumbnailPen, + mSelectionPen; + unsigned int mFrozenCount; + + wxBitmap CreateThumbnail(ShapesFrame *fp); + void UpdateVirtualSize(void); + +protected: + DECLARE_EVENT_TABLE(); + +public: + FrameBrowser(wxWindow *parent, wxWindowID id); + // event handlers + void OnPaint(wxPaintEvent& e); + void OnSize(wxSizeEvent& e); + void OnMouseDown(wxMouseEvent& e); + void OnKeyDown(wxKeyEvent& e); + // wx things + void Freeze(void); + void Thaw(void); + // access methods + int GetSelection(void) const; + void SetThumbnailSize(int size); + void SetTranspPixelsDisplay(bool show); + void AddFrame(ShapesFrame *fp); + void AddBitmap(ShapesBitmap *bp); + void SetColorTable(ShapesColorTable *ct); + void Clear(void); + void ClearBitmaps(void); + // utilities + void RebuildThumbnail(unsigned int i); + void RebuildThumbnails(void); +}; + +#endif diff --git a/Shapes/FrameView.cpp b/Shapes/FrameView.cpp new file mode 100644 index 0000000..abad672 --- /dev/null +++ b/Shapes/FrameView.cpp @@ -0,0 +1,315 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "wx/image.h" +#include "FrameView.h" +#include "utilities.h" + +DEFINE_EVENT_TYPE(wxEVT_FRAMEVIEW_DRAG) + +BEGIN_EVENT_TABLE(FrameView, wxScrolledWindow) + EVT_PAINT(FrameView::OnPaint) + EVT_LEFT_DOWN(FrameView::OnDrag) + EVT_LEFT_UP(FrameView::OnDrag) + EVT_MOTION(FrameView::OnDrag) + EVT_SIZE(FrameView::OnSize) +END_EVENT_TABLE() + +FrameView::FrameView(wxWindow *parent, wxWindowID id): + wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mFrame(NULL), mEncBmp(NULL), mColorTable(NULL), mPanning(false), mDraggingOrigin(false), mDraggingKey(false), mNearOrigin(false), mNearKey(false) +{ + SetBackgroundColour(wxColour(255, 255, 255)); + SetScrollRate(1, 1); + EnableScrolling(false, false); + // origin cursor pen + mOriginPen.SetColour(0, 128, 128); + // key cursor pen + mKeypointPen.SetColour(128, 0, 128); + // mouse cursors + mPanCursor = wxCursor(wxCURSOR_ARROW); + mPointCursor = wxCursor(wxCURSOR_CROSS); + mWhiteTransparency = true; + mCenterOrigin = false; +} + +void FrameView::OnPaint(wxPaintEvent& e) +{ + wxPaintDC tempdc(this); + int vw, vh, cw, ch; + + GetVirtualSize(&vw, &vh); + DoPrepareDC(tempdc); + GetClientSize(&cw, &ch); + if (mFrame != NULL && mColorTable != NULL) { + if (mEncBmp != NULL) { + int origin_x, origin_y; + + if (mCenterOrigin) { + origin_x = vw/2 - mFrame->OriginX(); + origin_y = vh/2 - mFrame->OriginY(); + } else { + origin_x = vw/2 - mDecBmp.GetWidth()/2; + origin_y = vh/2 - mDecBmp.GetHeight()/2; + } + // draw bitmap + tempdc.DrawBitmap(mDecBmp, origin_x, origin_y); + // mark bitmap origin + tempdc.SetPen(mOriginPen); + tempdc.CrossHair(mFrame->OriginX() + origin_x, mFrame->OriginY() + origin_y); + tempdc.DrawCircle(mFrame->OriginX() + origin_x, mFrame->OriginY() + origin_y, 2); + // mark bitmap keypoint + tempdc.SetPen(mKeypointPen); + tempdc.CrossHair(mFrame->KeyX() + origin_x, mFrame->KeyY() + origin_y); + tempdc.DrawCircle(mFrame->KeyX() + origin_x, mFrame->KeyY() + origin_y, 2); + // origin & key labels + wxString origin_label = wxT("Origin"), + key_label = wxT("Keypoint"); + int text1w, text1h, text2w, text2h; + + tempdc.SetFont(*wxSMALL_FONT); + tempdc.GetTextExtent(origin_label, &text1w, &text1h); + tempdc.GetTextExtent(key_label, &text2w, &text2h); + tempdc.SetTextForeground(wxColour(0, 128, 128)); + if (mFrame->OriginY() + origin_y >= text1h + 2) + tempdc.DrawText(origin_label, vw - text1w - 2, mFrame->OriginY() + origin_y - text1h - 2); + else + tempdc.DrawText(origin_label, vw - text1w - 2, mFrame->OriginY() + origin_y + 2); + tempdc.SetTextForeground(wxColour(128, 0, 128)); + if (mFrame->KeyY() + origin_y >= text2h + 2) + tempdc.DrawText(key_label, vw - text2w - 2, mFrame->KeyY() + origin_y - text2h - 2); + else + tempdc.DrawText(key_label, vw - text2w - 2, mFrame->KeyY() + origin_y + 2); + } else { + wxString no_bmp_label = wxT("No associated bitmap"); + int text_w, text_h, + origin_x = vw/2, origin_y = vh/2; + + tempdc.GetTextExtent(no_bmp_label, &text_w, &text_h); + origin_x -= text_w / 2; + origin_y -= text_h / 2; + tempdc.SetTextForeground(wxColour(255, 0, 0)); + tempdc.DrawText(no_bmp_label, origin_x, origin_y); + } + } +} + +// handle mouse drag (pan view, edit origin/keypoint) +void FrameView::OnDrag(wxMouseEvent &e) +{ + if (mFrame == NULL || mEncBmp == NULL || mCenterOrigin) + return; + + if (e.ButtonDown()) { + int scroll_x, scroll_y; + + GetViewStart(&scroll_x, &scroll_y); + if (mNearOrigin) { + // start dragging origin + mDraggingOrigin = true; + } else if (mNearKey) { + // start dragging keypoint + mDraggingKey = true; + } else { + // start panning + mPanning = true; + mDragStartX = e.GetPosition().x + scroll_x; + mDragStartY = e.GetPosition().y + scroll_y; + } + } else if (e.Dragging()) { + if (mPanning) { + // pan + int dx = mDragStartX - e.GetPosition().x, + dy = mDragStartY - e.GetPosition().y; + + Scroll(dx, dy); + } else if (mDraggingOrigin) { + // set origin + int vw, vh, scroll_x, scroll_y, origin_x, origin_y; + + GetVirtualSize(&vw, &vh); + GetViewStart(&scroll_x, &scroll_y); + origin_x = vw/2 - mDecBmp.GetWidth()/2; + origin_y = vh/2 - mDecBmp.GetHeight()/2; + mFrame->SetOriginX(e.GetPosition().x + scroll_x - origin_x); + mFrame->SetOriginY(e.GetPosition().y + scroll_y - origin_y); + // send an event so that other gui elements can update + wxCommandEvent event(wxEVT_FRAMEVIEW_DRAG, GetId()); + + event.SetEventObject(this); + //event.SetInt(j); + GetEventHandler()->ProcessEvent(event); + Refresh(); + } else if (mDraggingKey) { + // set keypoint + int vw, vh, scroll_x, scroll_y, origin_x, origin_y; + + GetVirtualSize(&vw, &vh); + GetViewStart(&scroll_x, &scroll_y); + origin_x = vw/2 - mDecBmp.GetWidth()/2; + origin_y = vh/2 - mDecBmp.GetHeight()/2; + mFrame->SetKeyX(e.GetPosition().x + scroll_x - origin_x); + mFrame->SetKeyY(e.GetPosition().y + scroll_y - origin_y); + // send an event so that other gui elements can update + wxCommandEvent event(wxEVT_FRAMEVIEW_DRAG, GetId()); + + event.SetEventObject(this); + //event.SetInt(j); + GetEventHandler()->ProcessEvent(event); + Refresh(); + } + } else if (e.ButtonUp()) { + mPanning = mDraggingOrigin = mDraggingKey = false; + } else if (e.Moving()) { + // mouse moved without buttons + int vw, vh, scroll_x, scroll_y; + + GetVirtualSize(&vw, &vh); + GetViewStart(&scroll_x, &scroll_y); + + int origin_x = vw/2 - mDecBmp.GetWidth()/2, + origin_y = vh/2 - mDecBmp.GetHeight()/2, + x = e.GetPosition().x + scroll_x, + y = e.GetPosition().y + scroll_y, + delta_x, + delta_y, + dist_origin, + dist_keypoint; + + delta_x = x - (mFrame->OriginX() + origin_x); + delta_y = y - (mFrame->OriginY() + origin_y); + dist_origin = delta_x*delta_x + delta_y*delta_y; + delta_x = x - (mFrame->KeyX() + origin_x); + delta_y = y - (mFrame->KeyY() + origin_y); + dist_keypoint = delta_x*delta_x + delta_y*delta_y; + // are we near origin or keypoint? + if (dist_origin < 25) { + SetCursor(mPointCursor); + mNearOrigin = true; + mNearKey = false; + } else if (dist_keypoint < 25) { + SetCursor(mPointCursor); + mNearOrigin = false; + mNearKey = true; + } else { + SetCursor(mPanCursor); + mNearOrigin = mNearKey = false; + } + } +} + +void FrameView::OnSize(wxSizeEvent &e) +{ + int cw, ch, + vw = (mFrame == NULL || mEncBmp == NULL || mCenterOrigin) ? 0 : mEncBmp->Width(), + vh = (mFrame == NULL || mEncBmp == NULL || mCenterOrigin) ? 0 : mEncBmp->Height(); + + GetClientSize(&cw, &ch); + if (mEncBmp != NULL && mEncBmp->Pixels() != NULL) { + if (vw < cw) + vw = cw; + if (vh < ch) + vh = ch; + } else { + vw = cw; + vh = ch; + } + SetVirtualSize(vw, vh); +} + +void FrameView::SetTranspPixelsDisplay(bool show) +{ + mWhiteTransparency = show; + SetBitmap(mEncBmp); + Refresh(); +} + +void FrameView::SetCenterOrigin(bool center) +{ + mCenterOrigin = center; + SetBitmap(mEncBmp); + Refresh(); +} + +// associate a frame +void FrameView::SetFrame(ShapesFrame *fp) +{ + mFrame = fp; + SetBitmap(mEncBmp); + Refresh(); +} + +ShapesFrame *FrameView::GetFrame(void) const +{ + return mFrame; +} + +// associate a bitmap to display (we could do this in SetFrame +// but we would need a pointer to the original Shapes object) +void FrameView::SetBitmap(ShapesBitmap *bp) +{ + int cw, ch; + + GetClientSize(&cw, &ch); + mEncBmp = bp; + if (bp != NULL) { + if (bp->Pixels() != NULL) { + if (mCenterOrigin) { + // no scrolling + SetVirtualSize(cw, ch); + } else { + // adjust sizes to make scrolling work + int vw = mEncBmp->Width(), + vh = mEncBmp->Height(); + + if (vw < cw) + vw = cw; + if (vh < ch) + vh = ch; + SetVirtualSize(vw, vh); + } + // decode bitmap + if (mColorTable != NULL) { + wxImage img = ShapesBitmapToImage(bp, mColorTable, mWhiteTransparency); + + // apply transformations + if (mFrame) { + if (mFrame->IsXmirrored()) + img = img.Mirror(true); + if (mFrame->IsYmirrored()) + img = img.Mirror(false); + } + mDecBmp = wxBitmap(img); + } + Refresh(); + } else { + wxLogError(wxT("[FrameView] Added a bitmap with NULL pixels")); + SetVirtualSize(cw, ch); + } + } else { + SetVirtualSize(cw, ch); + } +} + +// call this before Set'tingBitmap! +void FrameView::SetColorTable(ShapesColorTable *ct) +{ + mColorTable = ct; + SetBitmap(mEncBmp); + Refresh(); +} + diff --git a/Shapes/FrameView.h b/Shapes/FrameView.h new file mode 100644 index 0000000..fa670eb --- /dev/null +++ b/Shapes/FrameView.h @@ -0,0 +1,74 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// FrameView +// A widget for displaying a single, full size frame +// + +#ifndef FRAMEVIEW_H +#define FRAMEVIEW_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_FRAMEVIEW_DRAG, -1) + +class FrameView: public wxScrolledWindow { +private: + ShapesFrame *mFrame; // frame data + ShapesBitmap *mEncBmp; // encoded bitmap + wxBitmap mDecBmp; // ready-to-draw associated frame bitmap + ShapesColorTable *mColorTable; // which palette to use for display + bool mWhiteTransparency; // hide transparent pixels + wxPen mOriginPen, + mKeypointPen; + wxCursor mPanCursor, + mPointCursor; + + bool mPanning, + mDraggingOrigin, + mDraggingKey, + mNearOrigin, + mNearKey, + mCenterOrigin; // center frame origin rather than frame bitmap + int mDragStartX, + mDragStartY; + +protected: + DECLARE_EVENT_TABLE(); + +public: + FrameView(wxWindow *parent, wxWindowID id); + // event handlers + void OnPaint(wxPaintEvent &e); + void OnSize(wxSizeEvent &e); + void OnDrag(wxMouseEvent &e); + // access + void SetTranspPixelsDisplay(bool show); + void SetCenterOrigin(bool center); + void SetFrame(ShapesFrame *fp); + ShapesFrame *GetFrame(void) const; + void SetBitmap(ShapesBitmap *bp); + void SetColorTable(ShapesColorTable *ct); +}; + +#endif diff --git a/Shapes/Makefile.am b/Shapes/Makefile.am new file mode 100644 index 0000000..03c4a88 --- /dev/null +++ b/Shapes/Makefile.am @@ -0,0 +1,11 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libshapes.a + +libshapes_a_SOURCES = BitmapBrowser.h BitmapView.h CTBrowser.h \ + CTView.h FrameBrowser.h FrameView.h SequenceView.h \ + ShapesDocument.h ShapesElements.h ShapesTreeItemData.h \ + ShapesView.h utilities.h BitmapBrowser.cpp BitmapView.cpp \ + CTBrowser.cpp CTView.cpp FrameBrowser.cpp FrameView.cpp \ + SequenceView.cpp ShapesDocument.cpp ShapesElements.cpp \ + ShapesView.cpp ShapesTreeItemData.cpp utilities.cpp diff --git a/Shapes/Makefile.in b/Shapes/Makefile.in new file mode 100644 index 0000000..bb26db4 --- /dev/null +++ b/Shapes/Makefile.in @@ -0,0 +1,484 @@ +# Makefile.in generated by automake 1.11.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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 = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = Shapes +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libshapes_a_AR = $(AR) $(ARFLAGS) +libshapes_a_LIBADD = +am_libshapes_a_OBJECTS = BitmapBrowser.$(OBJEXT) BitmapView.$(OBJEXT) \ + CTBrowser.$(OBJEXT) CTView.$(OBJEXT) FrameBrowser.$(OBJEXT) \ + FrameView.$(OBJEXT) SequenceView.$(OBJEXT) \ + ShapesDocument.$(OBJEXT) ShapesElements.$(OBJEXT) \ + ShapesView.$(OBJEXT) ShapesTreeItemData.$(OBJEXT) \ + utilities.$(OBJEXT) +libshapes_a_OBJECTS = $(am_libshapes_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libshapes_a_SOURCES) +DIST_SOURCES = $(libshapes_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libshapes.a +libshapes_a_SOURCES = BitmapBrowser.h BitmapView.h CTBrowser.h \ + CTView.h FrameBrowser.h FrameView.h SequenceView.h \ + ShapesDocument.h ShapesElements.h ShapesTreeItemData.h \ + ShapesView.h utilities.h BitmapBrowser.cpp BitmapView.cpp \ + CTBrowser.cpp CTView.cpp FrameBrowser.cpp FrameView.cpp \ + SequenceView.cpp ShapesDocument.cpp ShapesElements.cpp \ + ShapesView.cpp ShapesTreeItemData.cpp utilities.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Shapes/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Shapes/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libshapes.a: $(libshapes_a_OBJECTS) $(libshapes_a_DEPENDENCIES) + -rm -f libshapes.a + $(libshapes_a_AR) libshapes.a $(libshapes_a_OBJECTS) $(libshapes_a_LIBADD) + $(RANLIB) libshapes.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitmapBrowser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitmapView.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CTBrowser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CTView.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrameBrowser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FrameView.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SequenceView.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapesDocument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapesElements.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapesTreeItemData.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShapesView.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilities.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-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/Shapes/SequenceView.cpp b/Shapes/SequenceView.cpp new file mode 100644 index 0000000..3d02513 --- /dev/null +++ b/Shapes/SequenceView.cpp @@ -0,0 +1,613 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "wx/image.h" +#include "wx/dcbuffer.h" +#include "SequenceView.h" +#include "ShapesDocument.h" +#include "utilities.h" + +DEFINE_EVENT_TYPE(wxEVT_SEQUENCEVIEW) + +BEGIN_EVENT_TABLE(SequenceView, wxScrolledWindow) + EVT_PAINT(SequenceView::OnPaint) + EVT_SIZE(SequenceView::OnSize) + EVT_LEFT_DOWN(SequenceView::OnMouseDown) + EVT_LEFT_DCLICK(SequenceView::OnMouseDoubleClick) + EVT_RIGHT_DOWN(SequenceView::OnMouseDown) + EVT_LEFT_UP(SequenceView::OnMouseUp) + EVT_KEY_DOWN(SequenceView::OnKeyDown) + EVT_MOTION(SequenceView::OnMouseMove) +END_EVENT_TABLE() + +const char arrow_left_bits[] = { 0x08, 0x0c, 0x0e, 0x0f, 0x0e, 0x0c, 0x08 }, + arrow_right_bits[] = { 0x01, 0x03, 0x07, 0x0f, 0x07, 0x03, 0x01 }; + +const int THUMB_ARROW_MARGIN = 2; +const int THUMB_ARROW_BUTTON_MARGIN = 2; + +SequenceView::SequenceView(wxWindow *parent, wxWindowID id): + wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE), + mColorTable(NULL), mThumbnailSize(64), mMargin(7), mPrevBtnIcon(arrow_left_bits, 4, 7), + mNextBtnIcon(arrow_right_bits, 4, 7), mAutoSize(false), mSelection(-1), mFrameIndexes(NULL), mView(0) +{ + SetBackgroundStyle(wxBG_STYLE_CUSTOM); + SetBackgroundColour(wxColour(255, 255, 255)); + mThumbnailPen.SetColour(200, 200, 200); + mSelectionPen.SetColour(0, 0, 0); + mSelectionPen.SetWidth(3); + mAngleBrush.SetColour(200, 200, 200); + SetScrollRate(2, 2); + mAngleLabelSpace = 30; // TODO get this from real font extent + mWhiteTransparency = true; + mNumberOfViews = 0; + mFramesPerView = 0; + mAnimationType = UNANIMATED; +} + +void SequenceView::OnPaint(wxPaintEvent& e) +{ + wxAutoBufferedPaintDC tempdc(this); + wxPoint mouse; + int cw, ch, rx, ry; + + if (mFrameIndexes == NULL) + return; + + DoPrepareDC(tempdc); + tempdc.Clear(); + GetClientSize(&cw, &ch); + CalcUnscrolledPosition(0, 0, &rx, &ry); + // get mouse position in scrolled coords + mouse = ScreenToClient(wxGetMousePosition()); + mouse.x += rx; + mouse.y += ry; + // draw thumbnails + tempdc.SetPen(mThumbnailPen); + tempdc.SetBrush(*wxTRANSPARENT_BRUSH); + tempdc.SetTextForeground(wxColour(0, 0, 0)); + tempdc.SetBackgroundMode(wxTRANSPARENT); + for (unsigned int i = 0; i < mThumbnails.size(); i++) { + int x = mThumbnailPositions[i].x, + y = mThumbnailPositions[i].y, + bw = mThumbnails[i].GetWidth(), + bh = mThumbnails[i].GetHeight(); + + if ((int)i == mSelection) { + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + tempdc.SetPen(mSelectionPen); + tempdc.DrawRectangle(x-2, y-2, mThumbnailSize+4, mThumbnailSize+4); + tempdc.SetPen(mThumbnailPen); + } else { + tempdc.DrawRectangle(x-1, y-1, mThumbnailSize+2, mThumbnailSize+2); + tempdc.DrawBitmap(mThumbnails[i], x + mThumbnailSize/2 - bw/2, y + mThumbnailSize/2 - bh/2); + } + // draw arrow buttons if mouse is over this thumbnail + wxRect tnrect(x, y, mThumbnailSize, mThumbnailSize); + + if (tnrect.Contains(mouse)) { + wxString label = wxString::Format(wxT("%d"), (*mFrameIndexes)[i]); + int labelw, labelh; + + tempdc.SetFont(*wxSMALL_FONT); + tempdc.DrawBitmap(mPrevBtnIcon, x + 2, y + mThumbnailSize - mPrevBtnIcon.GetHeight() - 2); + tempdc.DrawBitmap(mNextBtnIcon, x + mThumbnailSize - mNextBtnIcon.GetWidth() - 2, y + mThumbnailSize - mNextBtnIcon.GetHeight() - 2); + tempdc.GetTextExtent(label, &labelw, &labelh); + tempdc.SetTextForeground(wxColour(255, 255, 255)); + tempdc.DrawText(label, x + (mThumbnailSize-labelw) / 2 - 1, y + mThumbnailSize - labelh - 2); + tempdc.DrawText(label, x + (mThumbnailSize-labelw) / 2 + 1, y + mThumbnailSize - labelh - 2); + tempdc.DrawText(label, x + (mThumbnailSize-labelw) / 2, y + mThumbnailSize - labelh - 2 - 1); + tempdc.DrawText(label, x + (mThumbnailSize-labelw) / 2, y + mThumbnailSize - labelh - 2 + 1); + tempdc.SetTextForeground(wxColour(0, 0, 0)); + tempdc.DrawText(label, x + (mThumbnailSize-labelw) / 2, y + mThumbnailSize - labelh - 2); + } + } + if (mThumbnails.size() > 0 && mAnimationType != UNANIMATED && mAnimationType != ANIMATED_1) { + // draw angle labels + char *deg = "°"; + wxString deg2(deg, wxConvISO8859_1); // FIXME does not work on OS X (draws infinity char) + + tempdc.SetFont(*wxSMALL_FONT); + tempdc.SetBrush(mAngleBrush); + for (int i = 0; i < mNumberOfViews; i++) { + wxString label = wxString::Format(wxT("%d"), i * 360 / mNumberOfViews) + deg2; + int tw, th; + + tempdc.GetTextExtent(label, &tw, &th); + tempdc.DrawRectangle(mMargin-1, mMargin + i * (mThumbnailSize + mMargin) - 1, mAngleLabelSpace+2, mThumbnailSize+2); + tempdc.DrawText(label, mMargin + mAngleLabelSpace - tw, mMargin + i * (mThumbnailSize + mMargin) + mThumbnailSize/2 - th/2); + } + } +} + +// widget resized, recalculate virtual size to correctly wrap thumbnails +void SequenceView::OnSize(wxSizeEvent& e) +{ + UpdateVirtualSize(); +} + +void SequenceView::OnMouseDown(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + // handle frame selection + { + int new_selection = -1; + + for (unsigned int i = 0; i < mThumbnailPositions.size(); i++) { + wxRect test(mThumbnailPositions[i].x, mThumbnailPositions[i].y, + mThumbnailSize, mThumbnailSize); + + if (test.Contains(mouse)) { + new_selection = i; + break; + } + } + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + + // send selection event + wxCommandEvent event(wxEVT_SEQUENCEVIEW, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } + break; + case wxMOUSE_BTN_RIGHT: + break; + } + e.Skip(); +} + +void SequenceView::OnMouseUp(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + // clicks on the little arrows change the associated frame index + // FIXME mouse tracking like real buttons (starting with a mouse down) + { + // find wether the mouse was released over a thumbnail + int touched_thumbnail = -1; + + for (unsigned int i = 0; i < mThumbnailPositions.size(); i++) { + wxRect test(mThumbnailPositions[i].x, mThumbnailPositions[i].y, + mThumbnailSize, mThumbnailSize); + + if (test.Contains(mouse)) { + touched_thumbnail = i; + break; + } + } + if (touched_thumbnail > -1) { + // find wether an arrow was touched + if (GetPrevArrowButtonRect(touched_thumbnail).Contains(mouse)) { + if ((*mFrameIndexes)[touched_thumbnail] > -1) { + (*mFrameIndexes)[touched_thumbnail]--; + RebuildThumbnail(touched_thumbnail); + Refresh(); + if (mView) { + static_cast(mView->GetDocument())->Modify(true); + } + } + } else if (GetNextArrowButtonRect(touched_thumbnail).Contains(mouse)) { + if ((*mFrameIndexes)[touched_thumbnail] < ((int)mFrames.size()-1)) { + (*mFrameIndexes)[touched_thumbnail]++; + RebuildThumbnail(touched_thumbnail); + Refresh(); + if (mView) { + static_cast(mView->GetDocument())->Modify(true); + } + } + } + } + } + break; + } + e.Skip(); +} + +void SequenceView::OnMouseMove(wxMouseEvent &e) +{ + Refresh(); +} + +void SequenceView::OnKeyDown(wxKeyEvent &e) +{ + if (e.ShiftDown()) { + // edit frame index of selection + switch (e.GetKeyCode()) { + case WXK_LEFT: + if (mSelection >= 0) { + if ((*mFrameIndexes)[mSelection] > -1) { + (*mFrameIndexes)[mSelection]--; + RebuildThumbnail(mSelection); + Refresh(); + if (mView) { + static_cast(mView->GetDocument())->Modify(true); + } + } + } + break; + case WXK_RIGHT: + if (mSelection >= 0) { + if ((*mFrameIndexes)[mSelection] < ((int)mFrames.size()-1)) { + (*mFrameIndexes)[mSelection]++; + RebuildThumbnail(mSelection); + Refresh(); + if (mView) { + static_cast(mView->GetDocument())->Modify(true); + } + } + } + break; + default: + e.Skip(); + break; + } + } else { + // edit selection with arrow keys + int new_selection = mSelection; + + if (mSelection >= 0 && mSelection < (mNumberOfViews * mFramesPerView)) { + switch (e.GetKeyCode()) { + case WXK_LEFT: + if (mSelection % mFramesPerView > 0) + new_selection--; + break; + case WXK_RIGHT: + if (mSelection % mFramesPerView < (mFramesPerView-1)) + new_selection++; + break; + case WXK_UP: + if (mSelection / mFramesPerView > 0) + new_selection -= mFramesPerView; + break; + case WXK_DOWN: + if (mSelection / mFramesPerView < (mNumberOfViews-1)) + new_selection += mFramesPerView; + break; + case WXK_RETURN: + case WXK_NUMPAD_ENTER: + PopupFrameIndexDialog(mSelection); + break; + default: + e.Skip(); + } + } else if (mNumberOfViews * mFramesPerView > 0) { + new_selection = 0; + } + // TODO scroll to show the new position + if (new_selection != mSelection) { + mSelection = new_selection; + Refresh(); + + // send selection event + wxCommandEvent event(wxEVT_SEQUENCEVIEW, GetId()); + + event.SetEventObject(this); + event.SetInt(mSelection); + GetEventHandler()->ProcessEvent(event); + } + } +} + +void SequenceView::OnMouseDoubleClick(wxMouseEvent& e) +{ + wxClientDC dc(this); + wxPoint mouse; + + DoPrepareDC(dc); + mouse = e.GetLogicalPosition(dc); + switch (e.GetButton()) { + case wxMOUSE_BTN_LEFT: + { + int selection = -1; + for (unsigned int i = 0; i < mThumbnailPositions.size(); ++i) { + wxRect test(mThumbnailPositions[i].x, mThumbnailPositions[i].y, mThumbnailSize, mThumbnailSize); + if (test.Contains(mouse)) { + selection = i; + break; + } + } + + if (selection != -1) { + if (!GetPrevArrowButtonRect(selection).Contains(mouse) && + !GetNextArrowButtonRect(selection).Contains(mouse)) { + PopupFrameIndexDialog(selection); + } + } + } + break; + } +} + +int SequenceView::GetSelection(void) const +{ + return mSelection; +} + +void SequenceView::SetThumbnailSize(int size) +{ + if (size > 0) { + mThumbnailSize = size; + mAutoSize = false; + } else { + mAutoSize = true; + } + UpdateVirtualSize(); + if (!mAutoSize) + RebuildThumbnails(); + Refresh(); +} + +void SequenceView::SetTranspPixelsDisplay(bool show) +{ + mWhiteTransparency = show; + RebuildThumbnails(); + Refresh(); +} + +// add a new ShapesFrame to the thumbnail list +void SequenceView::AddFrame(ShapesFrame *fp) +{ + if (fp != NULL) + mFrames.push_back(fp); +} + +// add a ShapesBitmap to the bitmap pointer list. Call before adding frames! +void SequenceView::AddBitmap(ShapesBitmap *bp) +{ + if (bp != NULL) { + if (bp->Pixels() != NULL) + mBitmaps.push_back(bp); + else + wxLogError(wxT("SequenceView: someone tried to add a bitmap with NULL pixels")); + } +} + +// set sequence parameters: frames per view, animation type and frame index array. +// Guess number of views from animation type. Also create thumbnails (add frames, +// bitmaps and set color table before!) +void SequenceView::SetSeqParameters(int animtype, int fpv, vector *indexes, wxView* view) +{ + mAnimationType = animtype; + mNumberOfViews = ActualNumberOfViews(animtype); + mFramesPerView = fpv; + mFrameIndexes = indexes; + mView = view; + RebuildThumbnails(); + UpdateVirtualSize(); + Refresh(); +} + +// clear the thumbnail list +void SequenceView::Clear(void) +{ + mThumbnails.clear(); + mFrames.clear(); + mBitmaps.clear(); + mThumbnailPositions.clear(); + mSelection = -1; + UpdateVirtualSize(); + Refresh(); +} + +// call before adding frames! +void SequenceView::SetColorTable(ShapesColorTable *ct) +{ + mColorTable = ct; + RebuildThumbnails(); + Refresh(); +} + +// calculate and set the wxWindow virtual size, based on the +// number of thumbnails, thumbnail dimensions and given visible +// size. Also pre-calculate thumbnail positions +// FIXME behave like a FrameBrowser if mAnimationType == UNANIMATED, +// because frames are just to be chosen randomly and not really +// an animation. +void SequenceView::UpdateVirtualSize(void) +{ + wxClientDC dc(this); + int numframes = mThumbnails.size(), + width, height, + additional_pad = (mAnimationType == UNANIMATED || mAnimationType == ANIMATED_1) + ? 0 : (mAngleLabelSpace + mMargin); + + if (numframes < 1 || mFrameIndexes == NULL) { + SetVirtualSize(0, 0); + return; + } + GetClientSize(&width, &height); + if (mAutoSize && numframes > 0) { + // calculate the best tn_size + // (its maximum value not requiring window scrolling) + int max_bitmap_dimension = 0, + new_tn_size; + + SetScrollRate(0, 0); + // find greatest dimension among all referenced bitmaps + for (unsigned int i = 0; i < mFrameIndexes->size(); i++) { + int frame_index = (*mFrameIndexes)[i]; + + if (frame_index < 0 || frame_index >= (int)mFrames.size()) + continue; + + int bitmap_index = mFrames[frame_index]->BitmapIndex(); + + if (bitmap_index < 0 || bitmap_index >= (int)mBitmaps.size()) + continue; + if (mBitmaps[bitmap_index]->Width() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[bitmap_index]->Width(); + if (mBitmaps[bitmap_index]->Height() > max_bitmap_dimension) + max_bitmap_dimension = mBitmaps[bitmap_index]->Height(); + } + // start with a minimum size and increase it until overflow + for (new_tn_size = 2*mMargin; ; new_tn_size++) { + int numcols = mFramesPerView, + numrows = mNumberOfViews, + total_width = numcols * (new_tn_size + mMargin) + mMargin + additional_pad, + total_height = numrows * (new_tn_size + mMargin) + mMargin; + + if (total_width > width || total_height > height) { + // here we are + new_tn_size--; + break; + } + if (max_bitmap_dimension > 0 && new_tn_size >= max_bitmap_dimension) { + // no point in wasting window space with huge + // thumbnails showing small bitmaps at their center + break; + } + } + if (new_tn_size != mThumbnailSize) { + mThumbnailSize = new_tn_size; + RebuildThumbnails(); + } + } else { + SetScrollRate(2, 2); + } + + // now row & column count is simply mNumberOfViews and mFramesPerView, + // not the mess needed in the FrameBrowser + int numcols = mFramesPerView, + numrows = mNumberOfViews; + + SetVirtualSize(numcols * (mThumbnailSize + mMargin) + mMargin + additional_pad, + numrows * (mThumbnailSize + mMargin) + mMargin); + + // recalculate thumbnail positions + mThumbnailPositions.clear(); + for (int r = 0; r < numrows; r++) { + for (int c = 0; c < numcols; c++) + mThumbnailPositions.push_back(wxPoint(mMargin + (mThumbnailSize + mMargin) * c + additional_pad, + mMargin + (mThumbnailSize + mMargin) * r)); + } +} + +// transform an ShapesFrame to a wxBitmap thumbnail +wxBitmap SequenceView::CreateThumbnail(ShapesFrame *fp) +{ + if (fp->BitmapIndex() < 0 || fp->BitmapIndex() >= (int)mBitmaps.size()) { + // invalid or unset bitmap + // FIXME we are rebuilding this wxBitmap each time! Build it once + // and store it somewhere (rebuild upon tn_size change) + return BadThumbnail(mThumbnailSize); + } else { + // valid bitmap + ShapesBitmap *bp = mBitmaps[fp->BitmapIndex()]; + wxImage newimg(bp->Width(), bp->Height()); + + // decode the bitmap to a wxImage + if (mColorTable) + newimg = ShapesBitmapToImage(bp, mColorTable, mWhiteTransparency); + + // apply frame transformations + if (fp->IsXmirrored()) + newimg = newimg.Mirror(true); + if (fp->IsYmirrored()) + newimg = newimg.Mirror(false); + + // TODO apply transfer mode + + return ImageThumbnail(newimg, mThumbnailSize, true); + } +} + +void SequenceView::RebuildThumbnail(unsigned int i) +{ + if (i < mThumbnails.size() && i < mFrameIndexes->size()) { + if ((*mFrameIndexes)[i] >= 0 && (*mFrameIndexes)[i] < (int)mFrames.size()) + mThumbnails[i] = CreateThumbnail(mFrames[(*mFrameIndexes)[i]]); + else + mThumbnails[i] = BadThumbnail(mThumbnailSize); + } +} + +// redecode frames to bitmaps (after color table change, frame parameter variations etc) +void SequenceView::RebuildThumbnails(void) +{ + mThumbnails.clear(); + if (mFrameIndexes != NULL) { + for (unsigned int i = 0; i < mFrameIndexes->size(); i++) { + if ((*mFrameIndexes)[i] >= 0 && (*mFrameIndexes)[i] < (int)mFrames.size()) + mThumbnails.push_back(CreateThumbnail(mFrames[(*mFrameIndexes)[i]])); + else + mThumbnails.push_back(BadThumbnail(mThumbnailSize)); + } + } +} + +void SequenceView::PopupFrameIndexDialog(int selection) +{ + long v = 0; + if (wxGetTextFromUser(_("Change frame:"), _("Chage frame"), wxString::Format(wxT("%i"), (*mFrameIndexes)[selection]), GetParent()).ToLong(&v)) { + if (v >= -1 && v <= static_cast(mFrames.size()) - 1) { + (*mFrameIndexes)[selection] = v; + RebuildThumbnail(selection); + Refresh(); + if (mView) { + static_cast(mView->GetDocument())->Modify(true); + } + } + } +} + +wxRect SequenceView::GetNextArrowButtonRect(int thumbnail_index) const +{ + int thumb_x = mThumbnailPositions[thumbnail_index].x; + int thumb_y = mThumbnailPositions[thumbnail_index].y; + + int x = thumb_x + mThumbnailSize - mNextBtnIcon.GetWidth() - THUMB_ARROW_MARGIN; + int y = thumb_y + mThumbnailSize - mNextBtnIcon.GetHeight() - THUMB_ARROW_MARGIN; + int w = mPrevBtnIcon.GetWidth(); + int h = mPrevBtnIcon.GetHeight(); + + return wxRect(x - THUMB_ARROW_BUTTON_MARGIN, + y - THUMB_ARROW_BUTTON_MARGIN, + w + 2 * THUMB_ARROW_BUTTON_MARGIN, + h + 2 * THUMB_ARROW_BUTTON_MARGIN); +} + +wxRect SequenceView::GetPrevArrowButtonRect(int thumbnail_index) const +{ + int thumb_x = mThumbnailPositions[thumbnail_index].x; + int thumb_y = mThumbnailPositions[thumbnail_index].y; + + int x = thumb_x + THUMB_ARROW_MARGIN; + int y = thumb_y + mThumbnailSize - mNextBtnIcon.GetHeight() - THUMB_ARROW_MARGIN; + int w = mPrevBtnIcon.GetWidth(); + int h = mPrevBtnIcon.GetHeight(); + + return wxRect(x - THUMB_ARROW_BUTTON_MARGIN, + y - THUMB_ARROW_BUTTON_MARGIN, + w + 2 * THUMB_ARROW_BUTTON_MARGIN, + h + 2 * THUMB_ARROW_BUTTON_MARGIN); +} diff --git a/Shapes/SequenceView.h b/Shapes/SequenceView.h new file mode 100644 index 0000000..5e291e0 --- /dev/null +++ b/Shapes/SequenceView.h @@ -0,0 +1,97 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// SequenceView +// An editor widget for sequence frames. It displays the frames of a +// sequence keeping them organized in views. +// + +#ifndef SEQUENCEVIEW_H +#define SEQUENCEVIEW_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "wx/docview.h" +#include "ShapesElements.h" + +DECLARE_EVENT_TYPE(wxEVT_SEQUENCEVIEW, -1) + +class SequenceView: public wxScrolledWindow { +private: + vector mFrames; // pointers to frames + vector mBitmaps; // pointers to bitmaps + vector mThumbnails; // scaled/rendered frame thumbnails + ShapesColorTable *mColorTable; // which palette to use for display + vector mThumbnailPositions; // thumbnail positions within window + wxCoord mThumbnailSize, + mMargin, // margin between thumbnails and window edges + mAngleLabelSpace; + wxBitmap mPrevBtnIcon, + mNextBtnIcon; + bool mAutoSize, + mWhiteTransparency; + int mSelection; // selected thumbnail + wxPen mThumbnailPen, + mSelectionPen; + wxBrush mAngleBrush; + + int mNumberOfViews, + mFramesPerView, + mAnimationType; + vector *mFrameIndexes; + + wxBitmap CreateThumbnail(ShapesFrame *fp); + void UpdateVirtualSize(void); + + void PopupFrameIndexDialog(int index); + wxView* mView; + + wxRect GetNextArrowButtonRect(int thumbnail_index) const; + wxRect GetPrevArrowButtonRect(int thumbnail_index) const; + +protected: + DECLARE_EVENT_TABLE(); + +public: + SequenceView(wxWindow *parent, wxWindowID id); + // event handlers + void OnPaint(wxPaintEvent& e); + void OnSize(wxSizeEvent& e); + void OnMouseDown(wxMouseEvent& e); + void OnMouseMove(wxMouseEvent &e); + void OnMouseUp(wxMouseEvent& e); + void OnKeyDown(wxKeyEvent& e); + void OnMouseDoubleClick(wxMouseEvent& e); + // access methods + int GetSelection(void) const; + void SetThumbnailSize(int size); + void SetTranspPixelsDisplay(bool show); + void AddFrame(ShapesFrame *fp); + void AddBitmap(ShapesBitmap *bp); + void SetColorTable(ShapesColorTable *ct); + void SetSeqParameters(int animtype, int fpv, vector *indexes, wxView* view); + void Clear(void); + // utilities + void RebuildThumbnail(unsigned int i); + void RebuildThumbnails(void); +}; + +#endif diff --git a/Shapes/ShapesDocument.cpp b/Shapes/ShapesDocument.cpp new file mode 100644 index 0000000..ea279ce --- /dev/null +++ b/Shapes/ShapesDocument.cpp @@ -0,0 +1,344 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif +#include "wx/datstrm.h" +#include "ShapesDocument.h" + +IMPLEMENT_DYNAMIC_CLASS(ShapesDocument, wxDocument) + +ShapesDocument::ShapesDocument(): + wxDocument(), ShapesElement(false) +{ + +} + +ShapesDocument::~ShapesDocument() +{ + +} + +unsigned int ShapesDocument::CollectionCount(void) const +{ + return mCollections.size(); +} + +// collection data access +int ShapesDocument::CollectionStatus(unsigned int id) +{ + return mCollections[id]->Status(); +} + +unsigned int ShapesDocument::CollectionFlags(unsigned int id) const +{ + return mCollections[id]->Flags(); +} + +bool ShapesDocument::CollectionDefined(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->Defined(chunk); +} + +int ShapesDocument::CollectionVersion(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->Version(chunk); +} + +int ShapesDocument::CollectionType(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->Type(chunk); +} + +unsigned int ShapesDocument::CollectionFlags(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->Flags(chunk); +} + +int ShapesDocument::CollectionScaleFactor(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->ScaleFactor(chunk); +} + +unsigned int ShapesDocument::CollectionBitmapCount(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->BitmapCount(chunk); +} + +unsigned int ShapesDocument::CollectionColorTableCount(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->ColorTableCount(chunk); +} + +unsigned int ShapesDocument::CollectionFrameCount(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->FrameCount(chunk); +} + +unsigned int ShapesDocument::CollectionSequenceCount(unsigned int id, unsigned int chunk) const +{ + return mCollections[id]->SequenceCount(chunk); +} + +ShapesColorTable *ShapesDocument::GetColorTable(unsigned int coll, unsigned int chunk, unsigned int ct) const +{ + return mCollections[coll]->GetColorTable(chunk, ct); +} + +ShapesBitmap *ShapesDocument::GetBitmap(unsigned int coll, unsigned int chunk, unsigned int bitmap) const +{ + return mCollections[coll]->GetBitmap(chunk, bitmap); +} + +ShapesFrame *ShapesDocument::GetFrame(unsigned int coll, unsigned int chunk, unsigned int frame) const +{ + return mCollections[coll]->GetFrame(chunk, frame); +} + +ShapesSequence *ShapesDocument::GetSequence(unsigned int coll, unsigned int chunk, unsigned int seq) const +{ + return mCollections[coll]->GetSequence(chunk, seq); +} + +ShapesChunk* ShapesDocument::GetChunk(unsigned int coll, unsigned int chunk) const +{ + return mCollections[coll]->GetChunk(chunk); +} + +// collection alteration +void ShapesDocument::InsertColorTable(ShapesColorTable *ct, unsigned int coll, unsigned int chunk) +{ + mCollections[coll]->InsertColorTable(ct, chunk); +} + +void ShapesDocument::DeleteColorTable(unsigned int coll, unsigned int chunk, unsigned int ct) +{ + mCollections[coll]->DeleteColorTable(chunk, ct); +} + +void ShapesDocument::InsertBitmap(ShapesBitmap *b, unsigned int coll, unsigned int chunk) +{ + mCollections[coll]->InsertBitmap(b, chunk); +} + +void ShapesDocument::DeleteBitmap(unsigned int coll, unsigned int chunk, unsigned int b) +{ + mCollections[coll]->DeleteBitmap(chunk, b); +} + +void ShapesDocument::InsertFrame(ShapesFrame *f, unsigned int coll, unsigned int chunk) +{ + mCollections[coll]->InsertFrame(f, chunk); +} + +void ShapesDocument::DeleteFrame(unsigned int coll, unsigned int chunk, unsigned int f) +{ + mCollections[coll]->DeleteFrame(chunk, f); +} + +void ShapesDocument::InsertSequence(ShapesSequence *s, unsigned int coll, unsigned int chunk) +{ + mCollections[coll]->InsertSequence(s, chunk); +} + +void ShapesDocument::DeleteSequence(unsigned int coll, unsigned int chunk, unsigned int s) +{ + mCollections[coll]->DeleteSequence(chunk, s); +} + +bool ShapesDocument::DoOpenDocument(const wxString& file) +{ + bool wxOpen = wxDocument::DoOpenDocument(file); + + if (!(wxOpen && mGoodData)) { + wxLogError(wxT("[ShapesDocument] There was an error while loading, see log")); + return false; + } + return true; +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& ShapesDocument::SaveObject(wxSTD ostream& stream) +#else +wxOutputStream& ShapesDocument::SaveObject(wxOutputStream& stream) +#endif +{ + unsigned int collectionCount = CollectionCount(); + + // compose and write the collection header block + BigEndianBuffer raw_headers(SIZEOF_collection_header * collectionCount); + long running_offset = SIZEOF_collection_header * collectionCount; + + for (unsigned int i = 0; i < collectionCount; i++) { + ShapesCollection *coll = mCollections[i]; + + raw_headers.WriteShort(coll->Status()); + raw_headers.WriteUShort(coll->Flags()); + // 8-bit version + if (coll->Defined(COLL_VERSION_8BIT)) { + unsigned int collSize = coll->SizeInFile(COLL_VERSION_8BIT); + + raw_headers.WriteLong(running_offset); + raw_headers.WriteLong(collSize); + running_offset += collSize; + } else { + raw_headers.WriteLong(-1); + raw_headers.WriteLong(0); + } + // truecolor version + if (coll->Defined(COLL_VERSION_TRUECOLOR)) { + unsigned int collSize = coll->SizeInFile(COLL_VERSION_TRUECOLOR); + + raw_headers.WriteLong(running_offset); + raw_headers.WriteLong(collSize); + running_offset += collSize; + } else { + raw_headers.WriteLong(-1); + raw_headers.WriteLong(0); + } + raw_headers.WriteZeroes(12); + } +#if wxUSE_STD_IOSTREAM + stream.write((char *)raw_headers.Data(), raw_headers.Size()); +#else + stream.Write((char *)raw_headers.Data(), raw_headers.Size()); +#endif + + // write collections + for (unsigned int i = 0; i < collectionCount; i++) + mCollections[i]->SaveObject(stream); + + return stream; +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& ShapesDocument::SavePatch(wxSTD ostream& stream, const ShapesDocument& other) +#else +wxOutputStream& ShapesDocument::SavePatch(wxOutputStream& stream, const ShapesDocument& other) +#endif +{ + if (mCollections.size() != other.mCollections.size()) { + wxLogError(wxT("[ShapesDocument] Shapes files must contain the same number of collections to generate a patch")); + return stream; + } + + // 8-bit versions + for (unsigned int i = 0; i < mCollections.size(); ++i) { + mCollections[i]->SavePatch(stream, *other.mCollections[i], i, 0); + } + + for (unsigned int i = 0; i < mCollections.size(); ++i) { + mCollections[i]->SavePatch(stream, *other.mCollections[i], i, 1); + } + + return stream; +} + +#if wxUSE_STD_IOSTREAM +wxSTD istream& ShapesDocument::LoadObject(wxSTD istream& stream) +#else +wxInputStream& ShapesDocument::LoadObject(wxInputStream& stream) +#endif +{ + mGoodData = false; + + // first check file size to immediately rule out invalid stuff +#if wxUSE_STD_IOSTREAM + stream.seekg(0, std::ios::end); + wxInt32 filesize = stream.tellg(); + stream.seekg(0, std::ios::beg); +#else + wxInt32 filesize = stream.GetSize(); +#endif + if (filesize < COLLECTIONS_PER_FILE * SIZEOF_collection_header) { + wxLogError(wxT("[ShapesDocument] File too small to be a Marathon shapes file")); + return stream; + } + + // find how many collections are stored and load them + unsigned int i = 0; + + while (true) { + ShapesCollection *c = new ShapesCollection(IsVerbose()); + + if (IsVerbose()) + wxLogDebug(wxT("[ShapesDocument] Trying to load collection %d"), i); + +#if wxUSE_STD_IOSTREAM + stream.seekg(i * SIZEOF_collection_header, std::ios::beg); +#else + stream.SeekI(i * SIZEOF_collection_header); +#endif + c->LoadObject(stream); + + if (c->IsGood()) { + mCollections.push_back(c); + i++; + } else { + break; + } + } + if (i >= COLLECTIONS_PER_FILE) + mGoodData = true; + else + wxLogError(wxT("[ShapesDocument] Could not find enough collections. This may not be a Marathon Shapes file.")); + + return stream; +} + +#if wxUSE_STD_IOSTREAM +bool ShapesDocument::LoadPatch(wxSTD istream& stream) +#else +bool ShapesDocument::LoadPatch(wxInputStream& stream) +#endif +{ +#if wxUSE_STD_IOSTREAM + stream.seekg(0, std::ios::end); + wxInt32 filesize = stream.tellg(); + stream.seekg(0, std::ios::beg); +#else + wxInt32 filesize = stream.GetSize(); +#endif + + // memory is cheap, read the whole thing in + BigEndianBuffer buffer(filesize); + +#if wxUSE_STD_IOSTREAM + stream.read((char *) buffer.Data(), buffer.Size()); +#else + stream.Read((char *) buffer.Data(), buffer.Size()); +#endif + + while (buffer.Position() < buffer.Size()) { + long collection = buffer.ReadLong(); + if (collection < mCollections.size()) { + mCollections[collection]->LoadPatch(buffer); + if (!mCollections[collection]->IsGood()) { + return false; + } + } else { + wxLogError(wxT("Shapes patches cannot add entire collections")); + return false; + } + } + + return true; +} diff --git a/Shapes/ShapesDocument.h b/Shapes/ShapesDocument.h new file mode 100644 index 0000000..d859643 --- /dev/null +++ b/Shapes/ShapesDocument.h @@ -0,0 +1,91 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// +// Shapes +// Shapes class representing what's inside a Marathon shapes file. +// Note that, for keeping things simple and providing compatibility, +// the class doesn't store everything using the original on-disk format. +// For example, flags are expanded to bool fields and fixed point values +// are converted to doubles. Every bitmap is converted to a simple block +// of width*height pixels, regardless of its compression and pixel order. +// Conversions take place only when actually loading and writing files. +// + +#ifndef SHAPESDOCUMENT_H +#define SHAPESDOCUMENT_H + +#include "wx/docview.h" +#include "ShapesElements.h" + +// class representing the contents of a Marathon shapes file +class ShapesDocument: public wxDocument, public ShapesElement +{ + DECLARE_DYNAMIC_CLASS(ShapesDocument) + +private: + vector mCollections; + +public: + unsigned int CollectionCount(void) const; + // collection data access + int CollectionStatus(unsigned int id); + unsigned int CollectionFlags(unsigned int id) const; + bool CollectionDefined(unsigned int id, unsigned int chunk) const; + int CollectionVersion(unsigned int id, unsigned int chunk) const; + int CollectionType(unsigned int id, unsigned int chunk) const; + unsigned int CollectionFlags(unsigned int id, unsigned int chunk) const; + int CollectionScaleFactor(unsigned int id, unsigned int chunk) const; + unsigned int CollectionBitmapCount(unsigned int id, unsigned int chunk) const; + unsigned int CollectionColorTableCount(unsigned int id, unsigned int chunk) const; + unsigned int CollectionFrameCount(unsigned int id, unsigned int chunk) const; + unsigned int CollectionSequenceCount(unsigned int id, unsigned int chunk) const; + ShapesColorTable *GetColorTable(unsigned int coll, unsigned int chunk, unsigned int ct) const; + ShapesBitmap *GetBitmap(unsigned int coll, unsigned int chunk, unsigned int bitmap) const; + ShapesFrame *GetFrame(unsigned int coll, unsigned int chunk, unsigned int frame) const; + ShapesSequence *GetSequence(unsigned int coll, unsigned int chunk, unsigned int seq) const; + ShapesChunk* GetChunk(unsigned int coll, unsigned int chunk) const; + // collection alteration + void InsertColorTable(ShapesColorTable *ct, unsigned int coll, unsigned int chunk); + void DeleteColorTable(unsigned int coll, unsigned int chunk, unsigned int ct); + void InsertBitmap(ShapesBitmap *b, unsigned int coll, unsigned int chunk); + void DeleteBitmap(unsigned int coll, unsigned int chunk, unsigned int b); + void InsertFrame(ShapesFrame *f, unsigned int coll, unsigned int chunk); + void DeleteFrame(unsigned int coll, unsigned int chunk, unsigned int f); + void InsertSequence(ShapesSequence *s, unsigned int coll, unsigned int chunk); + void DeleteSequence(unsigned int coll, unsigned int chunk, unsigned int s); + + bool DoOpenDocument(const wxString& file); + +#if wxUSE_STD_IOSTREAM + wxSTD ostream& SaveObject(wxSTD ostream& stream); + wxSTD istream& LoadObject(wxSTD istream& stream); + wxSTD ostream& SavePatch(wxSTD ostream& stream, const ShapesDocument& other); + bool LoadPatch(wxSTD istream& stream); +#else + wxOutputStream& SaveObject(wxOutputStream& stream); + wxInputStream& LoadObject(wxInputStream& stream); + wxOutputStream& SavePatch(wxOutputStream& stream, const ShapesDocument& other); + bool LoadPatch(wxInputStream& stream); +#endif + + ShapesDocument(void); + ~ShapesDocument(void); +}; + +#endif diff --git a/Shapes/ShapesElements.cpp b/Shapes/ShapesElements.cpp new file mode 100644 index 0000000..90182c6 --- /dev/null +++ b/Shapes/ShapesElements.cpp @@ -0,0 +1,2093 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include "ShapesElements.h" +#include "utilities.h" +#include "../LittleEndianBuffer.h" +#include +#include + +// on-file struct sizes +#define SIZEOF_collection_definition 544 +#define SIZEOF_rgb_color_value 8 +#define SIZEOF_bitmap_definition 30 +#define SIZEOF_low_level_shape_definition 36 +#define SIZEOF_high_level_shape_definition 88 +// NOTE about SIZEOF_high_level_shape_definition. The original engine +// sets SIZEOF_high_level_shape_definition=90 because the first frame +// index is included in the high_level_shape_definition. I don't like +// this, so I do my way (but be careful!) +#define COLLECTION_VERSION 3 + +// color flags +enum { + SELF_LUMINESCENT_COLOR = 1 << 7 +}; +// bitmap flags +enum { + COLUMN_ORDER = 1 << 15, + TRANSPARENCY_ENABLED = 1 << 14 +}; +// frame flags +enum { + X_MIRROR = 1 << 15, // mirror along vertical axis + Y_MIRROR = 1 << 14, // mirror along horizontal axis + KEYPOINT_OBSCURED = 1 << 13 // "host obscures parasite" (RenderPlaceObjs.cpp) +}; + +#define FOUR_CHARS_TO_INT(a,b,c,d) (((unsigned int)(a) << 24) | ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d)) + +ShapesColor::ShapesColor(bool verbose): ShapesElement(verbose) +{ + +} + +ShapesColor::ShapesColor(unsigned int r, unsigned int g, unsigned int b, unsigned int value, bool luminescent, bool verbose): + ShapesElement(verbose), mLuminescent(luminescent), mValue(value), mRed(r), mGreen(g), mBlue(b) +{ + +} + +ShapesColor::~ShapesColor(void) +{ + +} + +bool ShapesColor::operator==(const ShapesColor& other) const +{ + return mLuminescent == other.mLuminescent + && mValue == other.mValue + && mRed == other.mRed + && mGreen == other.mGreen + && mBlue == other.mBlue; +} + +BigEndianBuffer& ShapesColor::SaveObject(BigEndianBuffer& buffer) +{ + unsigned char flags = mLuminescent ? SELF_LUMINESCENT_COLOR : 0; + + buffer.WriteUChar(flags); + buffer.WriteUChar(mValue); + buffer.WriteUShort(mRed); + buffer.WriteUShort(mGreen); + buffer.WriteUShort(mBlue); + + return buffer; +} + +BigEndianBuffer& ShapesColor::LoadObject(BigEndianBuffer& buffer) +{ + unsigned char flags; + + flags = buffer.ReadUChar(); + mValue = buffer.ReadUChar(); + mRed = buffer.ReadUShort(); + mGreen = buffer.ReadUShort(); + mBlue = buffer.ReadUShort(); + + mLuminescent = flags & SELF_LUMINESCENT_COLOR; + + mGoodData = true; + return buffer; +} + +ShapesColorTable::ShapesColorTable(bool verbose): ShapesElement(verbose) +{ + +} + +ShapesColorTable::ShapesColorTable(std::ifstream& ifs, wxString file_ext): ShapesElement(false) +{ + // FIXME better error checking and reporting + if (file_ext == wxString(wxT("act"))) { + // Photoshop binary color table file (Adobe Color Table, .act) + ifs.seekg(0, std::ios::end); + unsigned int fileSize = ifs.tellg(), + colorCount = 0; + ifs.seekg(0, std::ios::beg); + + if (fileSize >= 3*256+4) { + // extra info found - get the color count from that + BigEndianBuffer extraInfo(4); + + ifs.seekg(3 * 256); + ifs.read((char *)extraInfo.Data(), 4); + colorCount = (unsigned int)extraInfo.ReadShort(); + if (colorCount > 256) + colorCount = 256; + } else if (fileSize == 3*256) { + // no extra info - exactly 256 colors and no transparent color + colorCount = 256; + } else { + // we need at least 3*256 bytes + wxLogError(wxT("This Adobe Color Table file has an invalid size: will not try to load it.")); + return; + } + ifs.seekg(0, std::ios::beg); + for (unsigned int value = 0; value < colorCount; value++) { + unsigned char rgb[3]; + ifs.read((char *)rgb, 3); + ShapesColor *newColor = new ShapesColor(rgb[0]<<8, rgb[1]<<8, rgb[2]<<8, value); + mColors.push_back(newColor); + } + } else if (file_ext == wxString(wxT("gpl"))) { + // Gimp ASCII palette file + unsigned int value = 0; + + while (ifs.good() && value < 256) { + char buffer[256] = ""; + unsigned int red, green, blue; + + ifs.getline(buffer, 255); + if (sscanf(buffer, "%u %u %u", &red, &green, &blue) == 3) { + ShapesColor *newColor = new ShapesColor(red<<8, green<<8, blue<<8, value); + + mColors.push_back(newColor); + value++; + } + } + } +} + +ShapesColorTable::~ShapesColorTable(void) +{ + for (unsigned int i = 0; i < mColors.size(); i++) + delete mColors[i]; +} + +static bool compareShapesColorPtrs(ShapesColor* rhs, ShapesColor* lhs) +{ + return (*rhs == *lhs); +} + +bool ShapesColorTable::operator==(const ShapesColorTable& other) const +{ + if (mColors.size() == other.mColors.size()) { + return std::equal(mColors.begin(), mColors.end(), other.mColors.begin(), compareShapesColorPtrs); + } else { + return false; + } +} + +BigEndianBuffer& ShapesColorTable::SaveObject(BigEndianBuffer& stream) +{ + for (unsigned int i = 0; i < mColors.size(); i++) { + ShapesColor *color = mColors[i]; + + color->SaveObject(stream); + } + return stream; +} + +BigEndianBuffer& ShapesColorTable::SavePatch(BigEndianBuffer& buffer, int index) +{ + buffer.WriteLong(FOUR_CHARS_TO_INT('c','t','a','b')); + buffer.WriteLong(index); + return SaveObject(buffer); +} + +BigEndianBuffer& ShapesColorTable::LoadObject(BigEndianBuffer& buffer, unsigned int offset, unsigned int color_count) +{ + buffer.Position(offset); + + for (unsigned int i = 0; i < color_count; i++) { + ShapesColor *color = new ShapesColor(IsVerbose()); + + color->LoadObject(buffer); + + if (!color->IsGood()) { + wxLogError(wxT("[ShapesColorTable] Error loading color table")); + mGoodData = false; + return buffer; + } + mColors.push_back(color); + } + + mGoodData = true; + return buffer; +} + +// export a color table to Gimp ASCII format +int ShapesColorTable::SaveToGimp(wxString path) const +{ + std::ofstream cts(path.fn_str(), std::ios::binary); + + if (cts.good()) { + cts << "GIMP Palette\n"; + cts << "Name: ShapeFusion exported palette\n"; + cts << "#\n"; + for (unsigned int i = 0; i < ColorCount(); i++) { + ShapesColor *color = GetColor(i); + + cts << (color->Red() >> 8) << ' '; + cts << (color->Green() >> 8) << ' '; + cts << (color->Blue() >> 8) << '\n'; + } + cts.close(); + return 0; + } else { + return -1; + } +} + +// export a color table to Photoshop binary format +// (MacOS file type is '8BCT', extension '.act', Adobe Color Table) +int ShapesColorTable::SaveToPhotoshop(wxString path) const +{ + std::ofstream cts(path.fn_str(), std::ios::binary); + + if (cts.good()) { + BigEndianBuffer actData(3*256+4); + + actData.WriteZeroes(3*256+4); + actData.Position(0); + // write the RGB byte triplets for our colors + for (unsigned int i = 0; i < ColorCount(); i++) { + ShapesColor *color = GetColor(i); + + actData.WriteChar(color->Red() >> 8); + actData.WriteChar(color->Green() >> 8); + actData.WriteChar(color->Blue() >> 8); + } + // write the extra info at the end: + // number of colors and index of the transparent color + actData.Position(3*256); + actData.WriteShort(ColorCount()); + actData.WriteShort(0); + cts.write((char *)actData.Data(), actData.Size()); + cts.close(); + return 0; + } else { + return -1; + } +} + +ShapesBitmap::ShapesBitmap(bool verbose): ShapesElement(verbose), mPixels(NULL) +{ +} + +ShapesBitmap::ShapesBitmap(wxImage image, ShapesColorTable *colortable): + ShapesElement(false), mPixels(NULL) +{ + FromImage(image, colortable); +} + +ShapesBitmap::~ShapesBitmap(void) +{ + if (mPixels) + delete mPixels; + mPixels = NULL; +} + +bool ShapesBitmap::operator==(const ShapesBitmap& other) const +{ + if (mWidth == other.mWidth + && mHeight == other.mHeight + && mBytesPerRow == other.mBytesPerRow + && mBitDepth == other.mBitDepth + && mColumnOrder == other.mColumnOrder + && mTransparent == other.mTransparent) { + return std::equal(mPixels, mPixels + (mWidth * mHeight), other.mPixels); + } else { + return false; + } +} + +unsigned int ShapesBitmap::SizeInFile(void) const +{ + unsigned int size = 0; + + // scanline pointer placeholder + if (mColumnOrder) + size += 4 * mWidth; + else + size += 4 * mHeight; + if (mBytesPerRow == -1) { + // compressed + size += mWidth * 4; + for (int x = 0; x < mWidth; x++) { + unsigned char *pp = mPixels + x; + int p0 = -1, + p1; + + for (int y = 0; y < mHeight; y++) { + if (*pp != 0) { + p0 = y; + break; + } + pp += mWidth; + } + if (p0 == -1) + continue; // no opaque mPixels in this column + p1 = p0; + pp = mPixels + x + mWidth * (mHeight - 1); + for (int y = mHeight - 1; y >= 0; y--) { + if (*pp != 0) { + p1 = y; + break; + } + pp -= mWidth; + } + size += p1 - p0 + 1; + } + } else { + // plain + size += mWidth * mHeight; + } + + return size; +} + +BigEndianBuffer& ShapesBitmap::SaveObject(BigEndianBuffer& buffer) +{ + short flags = 0; + + if (mColumnOrder) + flags |= COLUMN_ORDER; + if (mTransparent) + flags |= TRANSPARENCY_ENABLED; + buffer.WriteShort(mWidth); + buffer.WriteShort(mHeight); + buffer.WriteShort(mBytesPerRow); + buffer.WriteShort(flags); + buffer.WriteShort(mBitDepth); + buffer.WriteZeroes(20 + 4 * (mColumnOrder ? mWidth : mHeight)); + if (mBytesPerRow == -1) { + // compress + for (int x = 0; x < mWidth; x++) { + unsigned char *pp = mPixels + x; + int p0 = -1, p1; + + for (int y = 0; y < mHeight; y++) { + if (*pp != 0) { + p0 = y; + break; + } + pp += mWidth; + } + if (p0 == -1) { + // no opaque pixels in this column + buffer.WriteShort(0); + buffer.WriteShort(0); + } else { + // found opaque pixels, go on + p1 = p0; + pp = mPixels + x + mWidth * (mHeight - 1); + for (int y = mHeight - 1; y >= 0; y--) { + if (*pp != 0) { + p1 = y; + break; + } + pp -= mWidth; + } + buffer.WriteShort(p0); + buffer.WriteShort(p1 + 1); + pp = mPixels + x + p0 * mWidth; + for (int y = p0; y <= p1; y++) { + buffer.WriteChar(*pp); + pp += mWidth; + } + } + } + } else { + if (mColumnOrder) { + for (int x = 0; x < mWidth; x++) { + for (int y = 0; y < mHeight; y++) + buffer.WriteChar(*(mPixels + x + y * mWidth)); + } + } else { + buffer.WriteBlock(mWidth * mHeight, mPixels); + } + } + return buffer; +} + +BigEndianBuffer& ShapesBitmap::SavePatch(BigEndianBuffer& buffer, int index) +{ + buffer.WriteLong(FOUR_CHARS_TO_INT('b', 'm', 'a', 'p')); + buffer.WriteLong(index); + buffer.WriteLong(SizeInFile() + SIZEOF_bitmap_definition); + return SaveObject(buffer); +} + +BigEndianBuffer& ShapesBitmap::LoadObject(BigEndianBuffer& buffer, unsigned int offset) +{ + buffer.Position(offset); + + mWidth = buffer.ReadShort(); + mHeight = buffer.ReadShort(); + mBytesPerRow = buffer.ReadShort(); + + if (mWidth < 0) { + wxLogError(wxT("[ShapesBitmap] Invalid bitmap width %d"), mWidth); + return buffer; + } + if (mHeight < 0) { + wxLogError(wxT("[ShapesBitmap] Invalid bitmap height %d"), mHeight); + return buffer; + } + if (mBytesPerRow < -1) { + wxLogError(wxT("[ShapesBitmap] Invalid bitmap bytes-per-row %d"), mBytesPerRow); + return buffer; + } + + short flags = buffer.ReadShort(); + + mColumnOrder = flags & COLUMN_ORDER; + mTransparent = flags & TRANSPARENCY_ENABLED; + + mBitDepth = buffer.ReadShort(); + if (mBitDepth != 8) { + wxLogError(wxT("[ShapesBitmap] Invalid bitmap depth %d"), mBitDepth); + return buffer; + } + + if (IsVerbose()) { + wxLogDebug(wxT("[ShapesBitmap] Width: %d"), mWidth); + wxLogDebug(wxT("[ShapesBitmap] Height: %d"), mHeight); + wxLogDebug(wxT("[ShapesBitmap] Bytes/Row: %d"), mBytesPerRow); + wxLogDebug(wxT("[ShapesBitmap] Flags: %d"), flags); + wxLogDebug(wxT("[ShapesBitmap] Bit Depth: %d"), mBitDepth); + } + + // skip unused fields and placeholders + unsigned int numscanlines = (mColumnOrder ? mWidth : mHeight); + + buffer.Position(buffer.Position() + 20 + numscanlines * 4); + + // load pixel data + mPixels = new unsigned char[mWidth * mHeight]; + if (mPixels == NULL) { + wxLogError(wxT("[ShapesBitmap] Could not allocate pixel buffer")); + return buffer; + } + if (mBytesPerRow > -1) { + // uncompressed bitmap + if (mColumnOrder) { + // column order + unsigned char *dstp; + + for (int x = 0; x < mWidth; x++) { + dstp = mPixels + x; + for (int y = 0; y < mHeight; y++) { + *dstp = buffer.ReadUChar(); + dstp += mWidth; + } + } + } else { + // row order + buffer.ReadBlock(mWidth * mHeight, mPixels); + } + } else { + // compressed bitmap (always column order) + memset(mPixels, 0, mWidth * mHeight); + for (int x = 0; x < mWidth; x++) { + short p0, p1; + unsigned char *dstp; + + p0 = buffer.ReadShort(); + p1 = buffer.ReadShort(); + dstp = mPixels + x + p0 * mWidth; + while (p0 != p1) { + *dstp = buffer.ReadUChar(); + dstp += mWidth; + p0++; + } + } + } + + mGoodData = true; + return buffer; +} + +// export the ShapesBitmap to an indexed BMP file specified by path +void ShapesBitmap::SaveToBMP(wxString path, ShapesColorTable *colorTable) const +{ + std::ofstream stream(path.fn_str(), std::ios::binary); + + if (stream.good()) { + unsigned int colorCount = colorTable->ColorCount(); + unsigned long paddedWidth = (mWidth + 3) & 0xfffffffc; + + // header + LittleEndianBuffer headerBlock(54); + + headerBlock.WriteChar('B'); + headerBlock.WriteChar('M'); + headerBlock.WriteULong(54 + 4*colorCount + paddedWidth * mHeight); // file size + headerBlock.WriteULong(0); // reserved + headerBlock.WriteULong(54 + 4*colorCount); // raster data offset + headerBlock.WriteULong(40); // info header size + headerBlock.WriteULong(mWidth); + headerBlock.WriteULong(mHeight); + headerBlock.WriteUShort(1); // plane count + headerBlock.WriteUShort(8); // bits per pixel + headerBlock.WriteULong(0); // no compression + headerBlock.WriteULong(0); // compressed size of image + headerBlock.WriteULong(0); + headerBlock.WriteULong(0); + headerBlock.WriteULong(colorCount); // FIXME + headerBlock.WriteULong(0); // FIXME + stream.write((const char *)headerBlock.Data(), headerBlock.Size()); + + // palette + LittleEndianBuffer paletteBlock(4*colorCount); + + for (unsigned int i = 0; i < colorCount; i++) { + ShapesColor *color = colorTable->GetColor(i); + + paletteBlock.WriteUChar(color->Blue() >> 8); + paletteBlock.WriteUChar(color->Green() >> 8); + paletteBlock.WriteUChar(color->Red() >> 8); + paletteBlock.WriteUChar(0); + } + stream.write((const char *)paletteBlock.Data(), paletteBlock.Size()); + + // 8-bit raster data + LittleEndianBuffer rasterBlock(paddedWidth * mHeight); + + for (int y = 0; y < mHeight; y++) { + rasterBlock.WriteBlock(mWidth, mPixels + (mHeight - y - 1) * mWidth); + rasterBlock.WriteZeroes(paddedWidth - mWidth); + } + stream.write((const char *)rasterBlock.Data(), rasterBlock.Size()); + + stream.close(); + } +} + +// export the ShapesBitmap mask to a 1-bit BMP file specified by path +void ShapesBitmap::SaveMaskToBMP(wxString path) const +{ + std::ofstream stream(path.fn_str(), std::ios::binary); + + if (stream.good()) { + unsigned long rowBytes = ((mWidth + 31) & 0xffffffe0) >> 3; + + // header + LittleEndianBuffer headerBlock(54); + + headerBlock.WriteChar('B'); + headerBlock.WriteChar('M'); + headerBlock.WriteULong(54 + 4*2 + rowBytes * mHeight); // file size + headerBlock.WriteULong(0); // reserved + headerBlock.WriteULong(54 + 4*2); // raster data offset + headerBlock.WriteULong(40); // info header size + headerBlock.WriteULong(mWidth); + headerBlock.WriteULong(mHeight); + headerBlock.WriteUShort(1); // plane count + headerBlock.WriteUShort(1); // bits per pixel + headerBlock.WriteULong(0); // no compression + headerBlock.WriteULong(0); // compressed size of image + headerBlock.WriteULong(0); + headerBlock.WriteULong(0); + headerBlock.WriteULong(2); + headerBlock.WriteULong(0); + stream.write((const char *)headerBlock.Data(), headerBlock.Size()); + + // black & white palette + LittleEndianBuffer paletteBlock(4*2); + + paletteBlock.WriteUChar(0); + paletteBlock.WriteUChar(0); + paletteBlock.WriteUChar(0); + paletteBlock.WriteUChar(0); + paletteBlock.WriteUChar(255); + paletteBlock.WriteUChar(255); + paletteBlock.WriteUChar(255); + paletteBlock.WriteUChar(0); + stream.write((const char *)paletteBlock.Data(), paletteBlock.Size()); + + // 1-bit raster data + LittleEndianBuffer rasterBlock(rowBytes * mHeight); + + rasterBlock.WriteZeroes(rowBytes * mHeight); + for (unsigned int y = 0; (int)y < mHeight; y++) { + unsigned char *p = mPixels + y * mWidth, + bit = 128, + byte = 0; + + rasterBlock.Position((mHeight - y - 1) * rowBytes); + for (unsigned int x = 0; (int)x < mWidth; x++) { + if (*p++ != 0) + byte |= bit; + bit >>= 1; + if (bit == 0) { + bit = 128; + rasterBlock.WriteUChar(byte); + byte = 0; + } + } + if (bit != 128) + rasterBlock.WriteUChar(byte); + } + stream.write((const char *)rasterBlock.Data(), rasterBlock.Size()); + + stream.close(); + } +} + +void ShapesBitmap::ClipboardCopy(ShapesColorTable* colortable) const +{ + if (wxTheClipboard->Open()) { + // create an RGBA wxImage + wxImage image; + image.Create(mWidth, mHeight, false); + + unsigned char* src = mPixels; + unsigned char* dst = image.GetData(); + for (int x = 0; x < mWidth; ++x) { + for (int y = 0; y < mHeight; ++y) { + unsigned char c = *src++; + ShapesColor* color = colortable->GetColor(c); + *dst++ = color->Red(); + *dst++ = color->Green(); + *dst++ = color->Blue(); + } + } + + wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(image))); + wxTheClipboard->Close(); + } +} + +void ShapesBitmap::ClipboardPaste(ShapesColorTable* colortable) +{ + if (wxTheClipboard->Open()) { + wxBitmapDataObject clipboardData; + if (wxTheClipboard->GetData(clipboardData)) { + FromImage(clipboardData.GetBitmap().ConvertToImage(), colortable); + } + wxTheClipboard->Close(); + } +} + +void ShapesBitmap::FromImage(wxImage image, ShapesColorTable* colortable) +{ + mWidth = image.GetWidth(); + mHeight = image.GetHeight(); + mBytesPerRow = image.GetWidth(); + mBitDepth = 8; + mColumnOrder = true; + mTransparent = false; + + if (mPixels) { + delete mPixels; + } + + unsigned char* srcpixels = image.GetData(), *src = srcpixels, *dst; + + mPixels = new unsigned char[mWidth * mHeight]; + if (mPixels == NULL) { + wxLogError(wxT("Could not allocate new %dx%d bitmap\n"), mWidth, mHeight); + return; + } + dst = mPixels; + // quantize from 8-bit RGB pixels to an indexed bitmap + for (int i = 0; i < mWidth * mHeight; i++) { + unsigned char r = *src++, g = *src++, b = *src++, + best_value = 0; + float min_dist = 0; + + for (unsigned int j = 0; j < colortable->ColorCount(); j++) { + unsigned short ct_r = colortable->GetColor(j)->Red(), + ct_g = colortable->GetColor(j)->Green(), + ct_b = colortable->GetColor(j)->Blue(); + float dist = ColourDistance(r/255.0, g/255.0, b/255.0, + ct_r/65535.0, ct_g/65535.0, ct_b/65535.0); + + if (dist < min_dist || j == 0) { + min_dist = dist; + best_value = colortable->GetColor(j)->Value(); + } + } + *dst++ = best_value; + if (best_value == 0) + mTransparent = true; // guess the user will want transparency + } +} + +ShapesFrame::ShapesFrame(bool verbose): ShapesElement(verbose) +{ + // initialize values to something reasonable + mBitmapIndex = -1; + mXmirror = mYmirror = mKeypointObscured = false; + mMinimumLightIntensity = 0; + mOriginX = mOriginY = mKeyX = mKeyY = 0; + mScaleFactor = 0; + mWorldLeft = mWorldRight = mWorldTop = mWorldBottom = 0; + mWorldX0 = mWorldY0 = 0; +} + +ShapesFrame::~ShapesFrame(void) +{ + +} + +bool ShapesFrame::operator==(const ShapesFrame& other) const +{ + return mXmirror == other.mXmirror + && mYmirror == other.mYmirror + && mKeypointObscured == other.mKeypointObscured + && mMinimumLightIntensity == other.mMinimumLightIntensity + && mBitmapIndex == other.mBitmapIndex + && mScaleFactor == other.mScaleFactor + && mOriginX == other.mOriginX + && mOriginY == other.mOriginY + && mKeyX == other.mKeyX + && mKeyY == other.mKeyY; +} + +BigEndianBuffer& ShapesFrame::SaveObject(BigEndianBuffer& buffer) +{ + unsigned short flags = 0; + float mli_integer, mli_fractional; + long min_light_intensity = 0; + + if (mXmirror) + flags |= X_MIRROR; + if (mYmirror) + flags |= Y_MIRROR; + if (mKeypointObscured) + flags |= KEYPOINT_OBSCURED; + + min_light_intensity = static_cast(mMinimumLightIntensity * 65536.0 + 0.5); // convert float to 16.16 fixed + + buffer.WriteUShort(flags); + buffer.WriteLong(min_light_intensity); + buffer.WriteShort(mBitmapIndex); + buffer.WriteShort(mOriginX); + buffer.WriteShort(mOriginY); + buffer.WriteShort(mKeyX); + buffer.WriteShort(mKeyY); + buffer.WriteShort(mWorldLeft); + buffer.WriteShort(mWorldRight); + buffer.WriteShort(mWorldTop); + buffer.WriteShort(mWorldBottom); + buffer.WriteShort(mWorldX0); + buffer.WriteShort(mWorldY0); + buffer.WriteZeroes(8); + + return buffer; +} + +BigEndianBuffer& ShapesFrame::SavePatch(BigEndianBuffer& buffer, int index) +{ + buffer.WriteLong(FOUR_CHARS_TO_INT('l','l','s','h')); + buffer.WriteLong(index); + return SaveObject(buffer); +} + +BigEndianBuffer& ShapesFrame::LoadObject(BigEndianBuffer& buffer, unsigned int offset) +{ + unsigned short flags; + wxInt32 mli_fixed; + + buffer.Position(offset); + + flags = buffer.ReadUShort(); + + mXmirror = flags & X_MIRROR; + mYmirror = flags & Y_MIRROR; + mKeypointObscured = flags & KEYPOINT_OBSCURED; + + mli_fixed = buffer.ReadLong(); + + mMinimumLightIntensity = mli_fixed / 65536.0; // convert 16.16 fixed to float + + mBitmapIndex = buffer.ReadShort(); + mOriginX = buffer.ReadShort(); + mOriginY = buffer.ReadShort(); + mKeyX = buffer.ReadShort(); + mKeyY = buffer.ReadShort(); + mWorldLeft = buffer.ReadShort(); + mWorldRight = buffer.ReadShort(); + mWorldTop = buffer.ReadShort(); + mWorldBottom = buffer.ReadShort(); + mWorldX0 = buffer.ReadShort(); + mWorldY0 = buffer.ReadShort(); + + if (IsVerbose()) { + wxLogDebug(wxT("[ShapesFrame] Flags: %d"), flags); + wxLogDebug(wxT("[ShapesFrame] Min. Light Intensity: %f"), mMinimumLightIntensity); + wxLogDebug(wxT("[ShapesFrame] Bitmap Index: %d"), mBitmapIndex); + wxLogDebug(wxT("[ShapesFrame] Origin (X): %d"), mOriginX); + wxLogDebug(wxT("[ShapesFrame] Origin (Y): %d"), mOriginY); + wxLogDebug(wxT("[ShapesFrame] Key (X): %d"), mKeyX); + wxLogDebug(wxT("[ShapesFrame] Key (Y): %d"), mKeyY); + wxLogDebug(wxT("[ShapesFrame] World (Left): %d"), mWorldLeft); + wxLogDebug(wxT("[ShapesFrame] World (Right): %d"), mWorldRight); + wxLogDebug(wxT("[ShapesFrame] World (Top): %d"), mWorldTop); + wxLogDebug(wxT("[ShapesFrame] World (Bottom): %d"), mWorldBottom); + wxLogDebug(wxT("[ShapesFrame] World (X0): %d"), mWorldX0); + wxLogDebug(wxT("[ShapesFrame] World (Y0): %d"), mWorldY0); + } + + mGoodData = true; + return buffer; +} + +ShapesSequence::ShapesSequence(bool verbose): ShapesElement(verbose) +{ + // initialize values to something reasonable + mType = 0; + mFlags = 0; + mName = _T("new sequence"); + mNumberOfViews = UNANIMATED; + mFramesPerView = 0; + mTicksPerFrame = 1; + mKeyFrame = 0; + mTransferMode = 0; + mTransferModePeriod = 1; + mFirstFrameSound = mKeyFrameSound = mLastFrameSound = -1; + mPixelsToWorld = 0; + mLoopFrame = 0; +} + +ShapesSequence::~ShapesSequence(void) +{ + +} + +bool ShapesSequence::operator==(const ShapesSequence& other) const +{ + if (mType == other.mType + && mFlags == other.mFlags + && mName == other.mName + && mNumberOfViews == other.mNumberOfViews + && mFramesPerView == other.mFramesPerView + && mTicksPerFrame == other.mTicksPerFrame + && mKeyFrame == other.mKeyFrame + && mTransferMode == other.mTransferMode + && mTransferModePeriod == other.mTransferModePeriod + && mFirstFrameSound == other.mFirstFrameSound + && mKeyFrameSound == other.mKeyFrameSound + && mLastFrameSound == other.mLastFrameSound + && mPixelsToWorld == other.mPixelsToWorld + && mLoopFrame == other.mLoopFrame + && mFrameIndexes.size() == other.mFrameIndexes.size()) { + return std::equal(mFrameIndexes.begin(), mFrameIndexes.end(), other.mFrameIndexes.begin()); + } else { + return false; + } +} + +unsigned int ShapesSequence::SizeInFile() const +{ + return 2 * (FrameIndexCount() + 1); +} + +BigEndianBuffer& ShapesSequence::SaveObject(BigEndianBuffer& buffer) +{ + char name[33] = ""; + + // Ugh--wxGTK doesn't recognize wxFONTENCODING_MACROMAN, and + // if you try to create a new wsCSConv with it, successive + // attempts to create wxT("macintosh") fail. Windows, on the + // other hand, doesn't recognize wxT("macintosh"), although if + // you ask it if seqnameconv.IsOk() it returns true and only + // fails when you try to convert something. So, #ifdef to + // success +#ifdef __WIN32__ + wxCSConv seqnameconv(wxFONTENCODING_MACROMAN); +#else + wxCSConv seqnameconv(wxT("macintosh")); +#endif + + buffer.WriteShort(mType); + buffer.WriteUShort(mFlags); + buffer.WriteChar(mName.Length()); + strncpy(name, seqnameconv.cWC2MB(mName.wc_str(*wxConvCurrent)), 33); + buffer.WriteBlock(33, (unsigned char *)name); + buffer.WriteShort(mNumberOfViews); + buffer.WriteShort(mFramesPerView); + buffer.WriteShort(mTicksPerFrame); + buffer.WriteShort(mKeyFrame); + buffer.WriteShort(mTransferMode); + buffer.WriteShort(mTransferModePeriod); + buffer.WriteShort(mFirstFrameSound); + buffer.WriteShort(mKeyFrameSound); + buffer.WriteShort(mLastFrameSound); + buffer.WriteShort(mPixelsToWorld); + buffer.WriteShort(mLoopFrame); + buffer.WriteZeroes(28); + for (unsigned int i = 0; i < mFrameIndexes.size(); i++) + buffer.WriteShort(mFrameIndexes[i]); + buffer.WriteShort(0); + + return buffer; +} + +BigEndianBuffer& ShapesSequence::SavePatch(BigEndianBuffer& buffer, int index) +{ + buffer.WriteLong(FOUR_CHARS_TO_INT('h','l','s','h')); + buffer.WriteLong(index); + buffer.WriteLong(SizeInFile() + SIZEOF_high_level_shape_definition); + return SaveObject(buffer); +} + +BigEndianBuffer& ShapesSequence::LoadObject(BigEndianBuffer& buffer, long offset) +{ + buffer.Position(offset); + mType = buffer.ReadShort(); + mFlags = buffer.ReadUShort(); + + // the mName is a Mac Pascal string, not a C string (length,chars) + unsigned char namelen = buffer.ReadUChar(); + + if (namelen > 32) { + wxLogError(wxT("[ShapesSequence] Sequence name too long (%d/32)"), namelen); + return buffer; + } + + char name[33]; +#ifdef __WIN32__ + wxCSConv seqnameconv(wxFONTENCODING_MACROMAN); +#else + wxCSConv seqnameconv(wxT("macintosh")); +#endif + + buffer.ReadBlock(33, (unsigned char *)name); + name[namelen] = 0; + mName = wxString(seqnameconv.cMB2WC(name), *wxConvCurrent, namelen); + + mNumberOfViews = buffer.ReadShort(); + mFramesPerView = buffer.ReadShort(); + mTicksPerFrame = buffer.ReadShort(); + mKeyFrame = buffer.ReadShort(); + mTransferMode = buffer.ReadShort(); + mTransferModePeriod = buffer.ReadShort(); + mFirstFrameSound = buffer.ReadShort(); + mKeyFrameSound = buffer.ReadShort(); + mLastFrameSound = buffer.ReadShort(); + mPixelsToWorld = buffer.ReadShort(); + mLoopFrame = buffer.ReadShort(); + buffer.Position(buffer.Position() + 28); + + if (IsVerbose()) { + wxLogDebug(wxT("[ShapesSequence] Type: %d"), mType); + wxLogDebug(wxT("[ShapesSequence] Flags: %d"), mFlags); + wxLogDebug(wxT("[ShapesSequence] Name: %s"), mName.c_str()); + wxLogDebug(wxT("[ShapesSequence] Number of Views: %d"), mNumberOfViews); + wxLogDebug(wxT("[ShapesSequence] Frames/Views: %d"), mFramesPerView); + wxLogDebug(wxT("[ShapesSequence] Ticks/Frame: %d"), mTicksPerFrame); + wxLogDebug(wxT("[ShapesSequence] Key Frame: %d"), mKeyFrame); + wxLogDebug(wxT("[ShapesSequence] Transfer Mode: %d"), mTransferMode); + wxLogDebug(wxT("[ShapesSequence] Transfer Mode Period: %d"), mTransferModePeriod); + wxLogDebug(wxT("[ShapesSequence] First Frame Sound: %d"), mFirstFrameSound); + wxLogDebug(wxT("[ShapesSequence] Key Frame Sound: %d"), mKeyFrameSound); + wxLogDebug(wxT("[ShapesSequence] Last Frame Sound: %d"), mLastFrameSound); + wxLogDebug(wxT("[ShapesSequence] Pixels to World: %d"), mPixelsToWorld); + wxLogDebug(wxT("[ShapesSequence] Loop Frame: %d"), mLoopFrame); + } + + if (mNumberOfViews < 0 || mFramesPerView < 0) { + wxLogError(wxT("[ShapesSequence] Invalid sequence type parameters: numberOfViews=%d, framesPerView=%d"), + mNumberOfViews, mFramesPerView); + return buffer; + } + // guess these shouldn't be < 0, but RED Shapes have a case with mKeyFrame=-1 + if (mKeyFrame < -1 || mLoopFrame < -1) { + wxLogError(wxT("[ShapesSequence] Invalid key/loop frame values in sequence data: keyFrame=%d, loopFrame=%d"), + mKeyFrame, mLoopFrame); + return buffer; + } + if (mFirstFrameSound < -1 || mKeyFrameSound < -1 || mLastFrameSound < -1) { + wxLogError(wxT("[ShapesSequence] Invalid sound values in sequence data: firstFrameSound=%d, keyFrameSound=%d, lastFrameSound=%d"), + mFirstFrameSound, mKeyFrameSound, mLastFrameSound); + return buffer; + } + + // load frame indexes + int n = ActualNumberOfViews(mNumberOfViews) * mFramesPerView; + + if (n > 0) { + for (int k = 0; k < n; k++) + mFrameIndexes.push_back(buffer.ReadShort()); + } + + buffer.ReadShort(); // terminating index (usually 0 but can be garbage) + + mGoodData = true; + return buffer; +} + +// given a high_level_shape_definition.mNumberOfViews value, +// return the real number of views +int ActualNumberOfViews(int t) +{ + switch (t) { + case UNANIMATED: + case ANIMATED_1: + return 1; + case ANIMATED_3TO4: + case ANIMATED_4: + return 4; + case ANIMATED_3TO5: + case ANIMATED_5: + return 5; + case ANIMATED_2TO8: + case ANIMATED_5TO8: + case ANIMATED_8: + return 8; + default: + wxLogError(wxT("[ShapesSequence] Unknown sequence type %d, don't know the number of views"), t); + return t; + } + return -1; +} + +ShapesChunk::ShapesChunk(bool verbose): ShapesElement(verbose) +{ + +} + +ShapesChunk::~ShapesChunk(void) +{ + Clear(); +} + +void ShapesChunk::Clear(void) +{ + unsigned int i; + + for (i = 0; i < mColorTables.size(); i++) + delete mColorTables[i]; + for (i = 0; i < mSequences.size(); i++) + delete mSequences[i]; + for (i = 0; i < mFrames.size(); i++) + delete mFrames[i]; + for (i = 0; i < mBitmaps.size(); i++) + delete mBitmaps[i]; + + mColorTables.clear(); + mSequences.clear(); + mFrames.clear(); + mBitmaps.clear(); + + mGoodData = false; +} + +static bool compareColorTablePtrs(ShapesColorTable* lhs, ShapesColorTable* rhs) { + return *lhs == *rhs; +} + +static bool compareSequencePtrs(ShapesSequence* lhs, ShapesSequence* rhs) { + return *lhs == *rhs; +} + +static bool compareFramePtrs(ShapesFrame* lhs, ShapesFrame* rhs) { + return *lhs == *rhs; +} + +static bool compareBitmapPtrs(ShapesBitmap* lhs, ShapesBitmap* rhs) { + return *lhs == *rhs; +} + +bool ShapesChunk::operator==(const ShapesChunk& other) const +{ + if (mVersion == other.mVersion + && mType == other.mType + && mFlags == other.mFlags + && mPixelsToWorld == other.mPixelsToWorld + && mColorTables.size() == other.mColorTables.size() + && mSequences.size() == other.mSequences.size() + && mFrames.size() == other.mFrames.size() + && mBitmaps.size() == other.mBitmaps.size()) { + if (!std::equal(mColorTables.begin(), mColorTables.end(), other.mColorTables.begin(), compareColorTablePtrs)) + return false; + if (!std::equal(mSequences.begin(), mSequences.end(), other.mSequences.begin(), compareSequencePtrs)) + return false; + if (!std::equal(mFrames.begin(), mFrames.end(), other.mFrames.begin(), compareFramePtrs)) + return false; + return (std::equal(mBitmaps.begin(), mBitmaps.end(), other.mBitmaps.begin(), compareBitmapPtrs)); + } else { + return false; + } +} + +ShapesColorTable* ShapesChunk::GetColorTable(unsigned int index) const +{ + if (index < 0 || index > mColorTables.size()) + return NULL; + return mColorTables[index]; +} + +ShapesBitmap* ShapesChunk::GetBitmap(unsigned int index) const +{ + if (index < 0 || index > mBitmaps.size()) + return NULL; + return mBitmaps[index]; +} + +ShapesFrame* ShapesChunk::GetFrame(unsigned int index) const +{ + if (index < 0 || index > mFrames.size()) + return NULL; + return mFrames[index]; +} + +ShapesSequence* ShapesChunk::GetSequence(unsigned int index) const +{ + if (index < 0 || index > mSequences.size()) + return NULL; + return mSequences[index]; +} + +void ShapesChunk::InsertColorTable(ShapesColorTable *ct) +{ + mColorTables.push_back(ct); +} + +void ShapesChunk::DeleteColorTable(unsigned int ct) +{ + mColorTables.erase(mColorTables.begin() + ct); +} + +void ShapesChunk::InsertBitmap(ShapesBitmap *b) +{ + mBitmaps.push_back(b); +} + +void ShapesChunk::DeleteBitmap(unsigned int b) +{ + if (b < mBitmaps.size()) { + // preserve existing frame-bitmap associations and associate + // a null bitmap to frames using the bitmap we're deleting + for (unsigned int i = 0; i < mFrames.size(); i++) { + short bitmap_index = mFrames[i]->BitmapIndex(); + + if (bitmap_index == (int)b) + mFrames[i]->SetBitmapIndex(-1); + else if (bitmap_index > (int)b) + mFrames[i]->SetBitmapIndex(bitmap_index - 1); + } + // now actually delete the bitmap + mBitmaps.erase(mBitmaps.begin() + b); + } +} + +void ShapesChunk::InsertFrame(ShapesFrame *f) +{ + mFrames.push_back(f); +} + +void ShapesChunk::DeleteFrame(unsigned int f) +{ + if (f < mFrames.size()) { + // preserve existing sequence-frame associations and + // unreference this frame index from any sequence using it + for (unsigned int i = 0; i < mSequences.size(); i++) { + for (unsigned int j = 0; j < mSequences[i]->FrameIndexCount(); j++) { + short frame_index = mSequences[i]->GetFrameIndex(j); + + if (frame_index == (int)f) + mSequences[i]->SetFrameIndex(j, -1); + else if (frame_index > (int)f) + mSequences[i]->SetFrameIndex(j, frame_index - 1); + } + } + // now actually delete the frame + mFrames.erase(mFrames.begin() + f); + } +} + +void ShapesChunk::InsertSequence(ShapesSequence *s) +{ + mSequences.push_back(s); +} + +void ShapesChunk::DeleteSequence(unsigned int s) +{ + if (s < mSequences.size()) + mSequences.erase(mSequences.begin() + s); +} + +void ShapesChunk::ClipboardCopy() +{ + if (wxTheClipboard->Open()) { + size_t size = SizeInFile(); + unsigned char* data = new unsigned char[size]; + BigEndianBuffer buffer(data, size); + + SaveObject(buffer); + + wxCustomDataObject* dataObject = new wxCustomDataObject(wxDataFormat(wxT("application/vnd.shapefusion.shapeschunk"))); + dataObject->TakeData(size, data); + + wxTheClipboard->SetData(dataObject); + + wxTheClipboard->Close(); + } +} + +void ShapesChunk::ClipboardPaste() +{ + if (wxTheClipboard->Open()) { + wxCustomDataObject dataObject(wxDataFormat(wxT("application/vnd.shapefusion.shapeschunk"))); + if (wxTheClipboard->GetData(dataObject)) { + BigEndianBuffer buffer(reinterpret_cast(dataObject.GetData()), dataObject.GetSize()); + + Clear(); + + LoadObject(buffer); + } + + wxTheClipboard->Close(); + } +} + +unsigned int ShapesChunk::SizeInFile(void) const +{ + unsigned int bitmap_count = BitmapCount(), + frame_count = FrameCount(), + sequence_count = SequenceCount(), + color_table_count = ColorTableCount(), + size; + + // size of our definition + size = SIZEOF_collection_definition; + // add contribute of sequence offset table + size += 4 * sequence_count; + // add contribute of bitmap offset table + size += 4 * bitmap_count; + // add contribute of frame offset table + size += 4 * frame_count; + // add contribute of color tables + if (color_table_count > 0) + size += SIZEOF_rgb_color_value * color_table_count * GetColorTable(0)->ColorCount(); + // add contribute of bitmaps + size += SIZEOF_bitmap_definition * bitmap_count; + for (unsigned int i = 0; i < bitmap_count; i++) { + ShapesBitmap *bitmap = mBitmaps[i]; + + size += bitmap->SizeInFile(); + } + // add contribute of frame definitions + size += SIZEOF_low_level_shape_definition * frame_count; + // add contribute of sequence definitions (and following frame indexes) + size += SIZEOF_high_level_shape_definition * sequence_count; + for (unsigned int i = 0 ; i < sequence_count ; i++) { + ShapesSequence *seq = mSequences[i]; + + size += seq->SizeInFile(); + } + + return size; +} + +unsigned int ShapesChunk::SizeInPatch(const ShapesChunk* other) const { + unsigned int size = 4; // 'cldf' + + size += SIZEOF_collection_definition; + + for (unsigned int i = 0; i < mColorTables.size(); ++i) { + if (other == NULL || i >= other->mColorTables.size() || *mColorTables[i] != *other->mColorTables[i]) { + size += SIZEOF_rgb_color_value * mColorTables[i]->ColorCount() + 8; + } + } + + for (unsigned int i = 0; i < mSequences.size(); ++i) { + if (other == NULL || i >= other->mSequences.size() || *mSequences[i] != *other->mSequences[i]) { + size += SIZEOF_high_level_shape_definition + mSequences[i]->SizeInPatch(); + } + } + + + for (unsigned int i = 0; i < mFrames.size(); ++i) { + if (other == NULL || i >= other->mFrames.size() || *mFrames[i] != *other->mFrames[i]) { + size += SIZEOF_low_level_shape_definition + 8; + } + } + + for (unsigned int i = 0; i < mBitmaps.size(); ++i) { + if (other == NULL || i >= other->mBitmaps.size() || *mBitmaps[i] != *other->mBitmaps[i]) { + size += SIZEOF_bitmap_definition + mBitmaps[i]->SizeInPatch(); + } + } + + return size; +} + +BigEndianBuffer& ShapesChunk::SaveObject(BigEndianBuffer& buffer) +{ + unsigned int bitmap_count = BitmapCount(), + frame_count = FrameCount(), + sequence_count = SequenceCount(), + i; + long sequence_table_offset, + sequence_offsets[sequence_count], + frame_table_offset, + frame_offsets[frame_count], + bitmap_table_offset, + bitmap_offsets[bitmap_count]; + + // skip the collection definition, we'll fill it at the end + buffer.Position(SIZEOF_collection_definition); + // write color tables + for (i = 0; i < ColorTableCount(); i++) + mColorTables[i]->SaveObject(buffer); + + // write sequences + sequence_table_offset = buffer.Position(); + if (sequence_count > 0) { + buffer.Position(buffer.Position() + sequence_count * 4); + + for (i = 0; i < sequence_count; i++) { + sequence_offsets[i] = buffer.Position(); + + mSequences[i]->SaveObject(buffer); + } + } + // write frames + frame_table_offset = buffer.Position(); + buffer.Position(buffer.Position() + frame_count * 4); + for (i = 0; i < frame_count; i++) { + frame_offsets[i] = buffer.Position(); + + mFrames[i]->SaveObject(buffer); + } + + // write bitmaps + bitmap_table_offset = buffer.Position(); + buffer.Position(buffer.Position() + bitmap_count * 4); + for (i = 0; i < bitmap_count; i++) { + bitmap_offsets[i] = buffer.Position(); + + mBitmaps[i]->SaveObject(buffer); + } + + // go back and write the collection definition (with correct offsets) + buffer.Position(0); + buffer.WriteShort(mVersion); + buffer.WriteShort(mType); + buffer.WriteUShort(mFlags); + buffer.WriteShort(GetColorTable(0)->ColorCount()); + buffer.WriteShort(ColorTableCount()); + buffer.WriteLong(SIZEOF_collection_definition); + buffer.WriteShort(sequence_count); + buffer.WriteLong(sequence_table_offset); + buffer.WriteShort(frame_count); + buffer.WriteLong(frame_table_offset); + buffer.WriteShort(bitmap_count); + buffer.WriteLong(bitmap_table_offset); + buffer.WriteShort(mPixelsToWorld); + buffer.WriteLong(SizeInFile()); + buffer.WriteZeroes(506); + + // fill offset tables + if (bitmap_count > 0) { + buffer.Position(bitmap_table_offset); + for (i = 0; i < bitmap_count; i++) + buffer.WriteLong(bitmap_offsets[i]); + } + if (frame_count > 0) { + buffer.Position(frame_table_offset); + for (i = 0; i < frame_count; i++) + buffer.WriteLong(frame_offsets[i]); + } + if (sequence_count > 0) { + buffer.Position(sequence_table_offset); + for (i = 0; i < sequence_count; i++) + buffer.WriteLong(sequence_offsets[i]); + } + + return buffer; +} + +BigEndianBuffer& ShapesChunk::SavePatch(BigEndianBuffer& buffer, const ShapesChunk* other) +{ + buffer.WriteLong(FOUR_CHARS_TO_INT('c','l','d','f')); + + // collection header + buffer.WriteShort(mVersion); + buffer.WriteShort(mType); + buffer.WriteUShort(mFlags); + buffer.WriteShort(GetColorTable(0)->ColorCount()); + buffer.WriteShort(ColorTableCount()); + buffer.WriteLong(SIZEOF_collection_definition); + buffer.WriteShort(SequenceCount()); + buffer.WriteLong(0); + buffer.WriteShort(FrameCount()); + buffer.WriteLong(0); + buffer.WriteShort(BitmapCount()); + buffer.WriteLong(0); + buffer.WriteShort(mPixelsToWorld); + buffer.WriteLong(0); + buffer.WriteZeroes(506); + + for (unsigned int i = 0; i < mColorTables.size(); ++i) { + if (other == NULL || i >= other->mColorTables.size() || *mColorTables[i] != *other->mColorTables[i]) { + mColorTables[i]->SavePatch(buffer, i); + } + } + + for (unsigned int i = 0; i < mSequences.size(); ++i) { + if (other == NULL || i >= other->mSequences.size() || *mSequences[i] != *other->mSequences[i]) { + mSequences[i]->SavePatch(buffer, i); + } + } + + for (unsigned int i = 0; i < mFrames.size(); ++i) { + if (other == NULL || i >= other->mFrames.size() || *mFrames[i] != *other->mFrames[i]) { + mFrames[i]->SavePatch(buffer, i); + } + } + + for (unsigned int i = 0; i < mBitmaps.size(); ++i) { + if (other == NULL || i >= other->mBitmaps.size() || *mBitmaps[i] != *other->mBitmaps[i]) { + mBitmaps[i]->SavePatch(buffer, i); + } + } + + return buffer; +} + +BigEndianBuffer& ShapesChunk::LoadObject(BigEndianBuffer& buffer) +{ + short color_count, + clut_count, + bitmap_count, + high_level_shape_count, + low_level_shape_count, + i; + long color_table_offset, + high_level_shape_offset_table_offset, + low_level_shape_offset_table_offset, + bitmap_offset_table_offset, + oldpos, + offset, + size; + + mVersion = buffer.ReadShort(); + mType = buffer.ReadShort(); + mFlags = buffer.ReadUShort(); + color_count = buffer.ReadShort(); + clut_count = buffer.ReadShort(); + color_table_offset = buffer.ReadLong(); + high_level_shape_count = buffer.ReadShort(); + high_level_shape_offset_table_offset = buffer.ReadLong(); + low_level_shape_count = buffer.ReadShort(); + low_level_shape_offset_table_offset = buffer.ReadLong(); + bitmap_count = buffer.ReadShort(); + bitmap_offset_table_offset = buffer.ReadLong(); + mPixelsToWorld = buffer.ReadShort(); + size = buffer.ReadLong(); + + // validate values + if (mVersion != COLLECTION_VERSION) { + wxLogError(wxT("[ShapesChunk] Unknown collection version %d"), mVersion); + return buffer; + } + + if ((unsigned long)size != buffer.Size()) { + wxLogError(wxT("[ShapesChunk] Chunk size mismatch (%ld/%d): this may not be a Marathon shapes file"), size, buffer.Size()); + return buffer; + } + if (color_table_offset < SIZEOF_collection_definition + || color_table_offset >= size + || high_level_shape_offset_table_offset < SIZEOF_collection_definition + || high_level_shape_offset_table_offset >= size + || low_level_shape_offset_table_offset < SIZEOF_collection_definition + || low_level_shape_offset_table_offset >= size + || bitmap_offset_table_offset < SIZEOF_collection_definition + || bitmap_offset_table_offset >= size) { + wxLogError(wxT("[ShapesChunk] Invalid offsets in collection definition: this may not be a Marathon shapes file")); + return buffer; + } + if (color_count < 0 || clut_count < 0 || high_level_shape_count < 0 || low_level_shape_count < 0 || bitmap_count < 0) { + wxLogError(wxT("[ShapesChunk] Invalid object counts in collection definition: this may not be a Marathon shapes file")); + return buffer; + } + + if (IsVerbose()) { + wxLogDebug(wxT("[ShapesChunk] Version: %d"), mVersion); + wxLogDebug(wxT("[ShapesChunk] Type: %d"), mType); + wxLogDebug(wxT("[ShapesChunk] Flags: %d"), mFlags); + wxLogDebug(wxT("[ShapesChunk] %d color tables, %d colors per table"), clut_count, color_count); + wxLogDebug(wxT("[ShapesChunk] %d sequences"), high_level_shape_count); + wxLogDebug(wxT("[ShapesChunk] %d frames"), low_level_shape_count); + wxLogDebug(wxT("[ShapesChunk] %d bitmaps"), bitmap_count); + } + + // load color tables + for (i = 0; i < clut_count; i++) { + ShapesColorTable *color_table = new ShapesColorTable(IsVerbose()); + + if (IsVerbose()) + wxLogDebug(wxT("[ShapesChunk] Loading colortable %d/%d"), i+1, clut_count); + + oldpos = buffer.Position(); + + color_table->LoadObject(buffer, color_table_offset + i * color_count * SIZEOF_rgb_color_value, color_count); + + buffer.Position(oldpos); + + // we stop if an error occured + if (!color_table->IsGood()) { + wxLogError(wxT("[ShapesChunk] Error loading color table %d... Dropped"), i); + return buffer; + } + + mColorTables.push_back(color_table); + } + + // load bitmaps, decoding compressed ones + buffer.Position(bitmap_offset_table_offset); + for (i = 0; i < bitmap_count; i++) { + offset = buffer.ReadLong(); + if (offset < SIZEOF_collection_definition || offset >= size) { + wxLogError(wxT("[ShapesChunk] Invalid bitmap offset: this may not be a Marathon shapes file")); + return buffer; + } + + ShapesBitmap *bitmap = new ShapesBitmap(IsVerbose()); + if (IsVerbose()) + wxLogDebug(wxT("[ShapesChunk] Loading bitmap %d/%d"), i+1, bitmap_count); + + oldpos = buffer.Position(); + + bitmap->LoadObject(buffer, offset); + + buffer.Position(oldpos); + + // we stop if an error occured + if (!bitmap->IsGood()) { + wxLogError(wxT("[ShapesDocument] Error loading bitmap %d... Dropped"), i); + return buffer; + } + + mBitmaps.push_back(bitmap); + } + + // load sequences + buffer.Position(high_level_shape_offset_table_offset); + for (i = 0; i < high_level_shape_count; i++) { + offset = buffer.ReadLong(); + if (offset < SIZEOF_collection_definition || offset >= size) { + wxLogError(wxT("[ShapesChunk] Invalid sequence offset: this may not be a Marathon shapes file")); + return buffer; + } + + ShapesSequence *sequence = new ShapesSequence(IsVerbose()); + if (IsVerbose()) + wxLogDebug(wxT("[ShapesChunk] Loading sequence %d/%d"), i+1, high_level_shape_count); + + oldpos = buffer.Position(); + + sequence->LoadObject(buffer, offset); + + buffer.Position(oldpos); + + // we stop if an error occured + if (!sequence->IsGood()) { + wxLogError(wxT("[ShapesDocument] Error loading sequence... Dropped")); + return buffer; + } + + mSequences.push_back(sequence); + } + + // load frames + buffer.Position(low_level_shape_offset_table_offset); + for (i = 0; i < low_level_shape_count; i++) { + offset = buffer.ReadLong(); + if (offset < SIZEOF_collection_definition || offset >= size) { + wxLogError(wxT("[ShapesChunk] Invalid frame offset: this may not be a Marathon shapes file")); + return buffer; + } + + ShapesFrame *frame = new ShapesFrame(IsVerbose()); + if (IsVerbose()) + wxLogDebug(wxT("[ShapesChunk] Loading frame %d/%d"), i+1, low_level_shape_count); + + oldpos = buffer.Position(); + + frame->LoadObject(buffer, offset); + + buffer.Position(oldpos); + // calculate scale factor from world_* fields and associated bitmap dimensions. + // If this fails, default to collection global scale factor + if (frame->BitmapIndex() >= 0 && frame->BitmapIndex() < (int)mBitmaps.size()) { + int bitmapWidth = mBitmaps[frame->BitmapIndex()]->Width(); + + if (bitmapWidth > 0) + frame->SetScaleFactor((frame->WorldRight() - frame->WorldLeft()) / bitmapWidth); + else + frame->SetScaleFactor(mPixelsToWorld); + } else { + frame->SetScaleFactor(mPixelsToWorld); + } + + // store if correct + if (!frame->IsGood()) { + wxLogError(wxT("[ShapesDocument] Error loading frame %d... Dropped"), i); + return buffer; + } + + mFrames.push_back(frame); + } + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& ShapesChunk::LoadPatch(BigEndianBuffer& buffer) +{ + mGoodData = true; + + long tag = buffer.ReadLong(); + short color_count = 0; + + while (tag != FOUR_CHARS_TO_INT('e','n','d','c')) { + switch (tag) { + case FOUR_CHARS_TO_INT('c','l','d','f'): { + mVersion = buffer.ReadShort(); + if (mVersion != COLLECTION_VERSION) { + wxLogError(wxT("[ShapesChunk] Unknown 'cldf' version %d in patch"), mVersion); + mGoodData = false; + return buffer; + } + + mType = buffer.ReadShort(); + mFlags = buffer.ReadUShort(); + color_count = buffer.ReadShort(); + mColorTables.resize(buffer.ReadShort()); + buffer.ReadLong(); // color table offset + mSequences.resize(buffer.ReadShort()); + buffer.ReadLong(); // high level shape offset + mFrames.resize(buffer.ReadShort()); + buffer.ReadLong(); // low level shape offset + mBitmaps.resize(buffer.ReadShort()); + buffer.ReadLong(); // bitmap offsets + mPixelsToWorld = buffer.ReadShort(); + buffer.ReadLong(); // size + buffer.Position(buffer.Position() + 506); + break; + } + case FOUR_CHARS_TO_INT('c','t','a','b'): { + long index = buffer.ReadLong(); + if (index < mColorTables.size()) { + ShapesColorTable* c = new ShapesColorTable(IsVerbose()); + c->LoadObject(buffer, buffer.Position(), color_count); + if (c->IsGood()) { + delete mColorTables[index]; + mColorTables[index] = c; + } else { + mGoodData = false; + return buffer; + } + } else { + wxLogError(wxT("[ShapesChunk] Invliad 'ctab' index")); + mGoodData = false; + return buffer; + } + break; + } + case FOUR_CHARS_TO_INT('h','l','s','h'): { + long index = buffer.ReadLong(); + long chunk_size = buffer.ReadLong(); + long position = buffer.Position(); + if (index < mSequences.size()) { + ShapesSequence* ss = new ShapesSequence(IsVerbose()); + ss->LoadObject(buffer, position); + buffer.Position(position + chunk_size); + if (ss->IsGood()) { + delete mSequences[index]; + mSequences[index] = ss; + } else { + mGoodData = false; + return buffer; + } + } else { + wxLogError(wxT("[ShapesChunk] Invalid 'hlsh' index")); + mGoodData = false; + return buffer; + } + break; + } + case FOUR_CHARS_TO_INT('l','l','s','h'): { + long index = buffer.ReadLong(); + if (index < mFrames.size()) { + ShapesFrame* sf = new ShapesFrame(IsVerbose()); + sf->LoadObject(buffer, buffer.Position()); + if (sf->IsGood()) { + delete mFrames[index]; + mFrames[index] = sf; + } else { + mGoodData = false; + return buffer; + } + } else { + wxLogError(wxT("[ShapesChunk] Invalid 'llsh' index")); + mGoodData = false; + return buffer; + } + break; + } + case FOUR_CHARS_TO_INT('b','m','a','p'): { + long index = buffer.ReadLong(); + long size = buffer.ReadLong(); + long position = buffer.Position(); + + if (index < mBitmaps.size()) { + ShapesBitmap* b = new ShapesBitmap(IsVerbose()); + b->LoadObject(buffer, position); + buffer.Position(position + size); + if (b->IsGood()) { + delete mBitmaps[index]; + mBitmaps[index] = b; + } else { + mGoodData = false; + return buffer; + } + } else { + wxLogError(wxT("[ShapesChunk] Invalid 'bmap' index")); + mGoodData = false; + return buffer; + } + break; + } + } + + tag = buffer.ReadLong(); + } + + return buffer; +} + +ShapesCollection::ShapesCollection(bool verbose): ShapesElement(verbose) +{ + mChunks[0] = NULL; + mChunks[1] = NULL; +} + +ShapesCollection::~ShapesCollection(void) +{ + if (mChunks[0]) + delete mChunks[0]; + if (mChunks[1]) + delete mChunks[1]; +} + +bool ShapesCollection::Defined(unsigned int chunk) const +{ + if (chunk > COLL_VERSION_TRUECOLOR) + return false; + return mChunks[chunk] != NULL; +} + +int ShapesCollection::Version(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->Version() : 0); +} + +int ShapesCollection::Type(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->Type() : 0); +} + +int ShapesCollection::Flags(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->Flags() : 0); +} + +int ShapesCollection::ScaleFactor(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->ScaleFactor() : 0); +} + +int ShapesCollection::ColorTableCount(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->ColorTableCount() : 0); +} + +int ShapesCollection::BitmapCount(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->BitmapCount() : 0); +} + +int ShapesCollection::FrameCount(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->FrameCount() : 0); +} + +int ShapesCollection::SequenceCount(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk]->SequenceCount() : 0); +} + +ShapesColorTable* ShapesCollection::GetColorTable(unsigned int chunk, unsigned int index) const +{ + return (Defined(chunk) ? mChunks[chunk]->GetColorTable(index) : NULL); +} + +ShapesBitmap* ShapesCollection::GetBitmap(unsigned int chunk, unsigned int index) const +{ + return (Defined(chunk) ? mChunks[chunk]->GetBitmap(index) : NULL); +} + +ShapesFrame* ShapesCollection::GetFrame(unsigned int chunk, unsigned int index) const +{ + return (Defined(chunk) ? mChunks[chunk]->GetFrame(index) : NULL); +} + +ShapesSequence* ShapesCollection::GetSequence(unsigned int chunk, unsigned int index) const +{ + return (Defined(chunk) ? mChunks[chunk]->GetSequence(index) : NULL); +} + +ShapesChunk* ShapesCollection::GetChunk(unsigned int chunk) const +{ + return (Defined(chunk) ? mChunks[chunk] : NULL); +} + +void ShapesCollection::InsertColorTable(ShapesColorTable *ct, unsigned int chunk) +{ + if (Defined(chunk)) + mChunks[chunk]->InsertColorTable(ct); +} + +void ShapesCollection::DeleteColorTable(unsigned int chunk, unsigned int ct) +{ + if (Defined(chunk)) + mChunks[chunk]->DeleteColorTable(ct); +} + +void ShapesCollection::InsertBitmap(ShapesBitmap *b, unsigned int chunk) +{ + if (Defined(chunk)) + mChunks[chunk]->InsertBitmap(b); +} + +void ShapesCollection::DeleteBitmap(unsigned int chunk, unsigned int b) +{ + if (Defined(chunk)) + mChunks[chunk]->DeleteBitmap(b); +} + +void ShapesCollection::InsertFrame(ShapesFrame *f, unsigned int chunk) +{ + if (Defined(chunk)) + mChunks[chunk]->InsertFrame(f); +} + +void ShapesCollection::DeleteFrame(unsigned int chunk, unsigned int f) +{ + if (Defined(chunk)) + mChunks[chunk]->DeleteFrame(f); +} + +void ShapesCollection::InsertSequence(ShapesSequence *s, unsigned int chunk) +{ + if (Defined(chunk)) + mChunks[chunk]->InsertSequence(s); +} + +void ShapesCollection::DeleteSequence(unsigned int chunk, unsigned int s) +{ + if (Defined(chunk)) + mChunks[chunk]->DeleteSequence(s); +} + +// calculate how much space a collection is going +// to take when encoded to its on-file format. +unsigned int ShapesCollection::SizeInFile(unsigned int chunk) const +{ + if (!Defined(chunk)) + return 0; + + unsigned int size = 0; + + size += mChunks[chunk]->SizeInFile(); + return size; +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& ShapesCollection::SaveObject(wxSTD ostream& stream) +#else +wxOutputStream& ShapesCollection::SaveObject(wxOutputStream& stream) +#endif +{ + for (unsigned int i = 0; i < 2 ; i++) { + if (Defined(i)) { + BigEndianBuffer chunkbuffer(mChunks[i]->SizeInFile()); + + mChunks[i]->SaveObject(chunkbuffer); +#if wxUSE_STD_IOSTREAM + stream.write((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#else + stream.Write((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#endif + } + } + return stream; +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& ShapesCollection::SavePatch(wxSTD ostream& stream, const ShapesCollection& other, int index, int depth) +#else +wxOutputStream& ShapesCollection::SavePatch(wxOutputStream& stream, const ShapesCollection& other, int index, int depth) +#endif +{ + bool diff = Defined(depth) && (other.mChunks[depth] == NULL || *mChunks[depth] != *other.mChunks[depth]); + unsigned int size = 12; + if (diff) { + size += mChunks[depth]->SizeInPatch(other.mChunks[depth]); + } + + BigEndianBuffer chunkbuffer(size); + chunkbuffer.WriteLong(index); + chunkbuffer.WriteLong(depth ? 16 : 8); + if (diff) { + mChunks[depth]->SavePatch(chunkbuffer, other.mChunks[depth]); + } + chunkbuffer.WriteLong(FOUR_CHARS_TO_INT('e','n','d','c')); +#if wxUSE_STD_IOSTREAM + stream.write((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#else + stream.Write((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#endif + + return stream; +} + +#if wxUSE_STD_IOSTREAM +wxSTD istream& ShapesCollection::LoadObject(wxSTD istream& stream) +#else +wxInputStream& ShapesCollection::LoadObject(wxInputStream& stream) +#endif +{ + BigEndianBuffer coll_header(SIZEOF_collection_header); + +#if wxUSE_STD_IOSTREAM + stream.read((char *)coll_header.Data(), coll_header.Size()); +#else + stream.Read((char *)coll_header.Data(), coll_header.Size()); +#endif + +#if wxUSE_STD_IOSTREAM + stream.seekg(0, std::ios::end); + wxInt32 filesize = stream.tellg(); + stream.seekg(0, std::ios::beg); +#else + wxInt32 filesize = stream.GetSize(); +#endif + + long offset8, length8, + offset16, length16; + + mStatus = coll_header.ReadShort(); + mFlags = coll_header.ReadUShort(); + offset8 = coll_header.ReadLong(); + length8 = coll_header.ReadLong(); + offset16 = coll_header.ReadLong(); + length16 = coll_header.ReadLong(); + + if (offset8 < -1 || length8 < 0 || offset16 < -1 || length16 < 0) + return stream; + if ((offset8 + length8) > filesize) + return stream; + if ((offset16 + length16) > filesize) + return stream; + + if (IsVerbose()) { + wxLogDebug(wxT("[ShapesCollection] Status: %d"), mStatus); + wxLogDebug(wxT("[ShapesCollection] Flags: %d"), mFlags); + } + + // is there the 8-bit version? + if (offset8 != -1) { + if (IsVerbose()) + wxLogDebug(wxT("[ShapesCollection] 8-bit chunk present")); + + BigEndianBuffer chunkbuffer(length8); + +#if wxUSE_STD_IOSTREAM + stream.seekg(offset8, std::ios::beg); + stream.read((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#else + stream.SeekI(offset8, wxFromStart); + stream.Read((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#endif + + ShapesChunk *pc = new ShapesChunk(IsVerbose()); + pc->LoadObject(chunkbuffer); + + if (!pc->IsGood()) { + wxLogError(wxT("[ShapesCollection] Error loading 8-bit chunk... Dropped")); + return stream; + } + mChunks[0] = pc; + } + + // is there the 16-bit version? + if (offset16 != -1) { + if (IsVerbose()) + wxLogDebug(wxT("[ShapesCollection] 16/32-bit chunk present")); + + BigEndianBuffer chunkbuffer(length16); + +#if wxUSE_STD_IOSTREAM + stream.seekg(offset16, std::ios::beg); + stream.read((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#else + stream.SeekI(offset16, wxFromStart); + stream.Read((char *)chunkbuffer.Data(), chunkbuffer.Size()); +#endif + + ShapesChunk *pc = new ShapesChunk(IsVerbose()); + pc->LoadObject(chunkbuffer); + + if (!pc->IsGood()) { + wxLogError(wxT("[ShapesCollection] Error loading 16/32-bit chunk... Dropped")); + return stream; + } + mChunks[1] = pc; + } + + mGoodData = true; + return stream; +} + +BigEndianBuffer& ShapesCollection::LoadPatch(BigEndianBuffer& buffer) +{ + int depth = buffer.ReadLong(); + ShapesChunk* chunk = 0; + if (depth == 8) { + if (!mChunks[0]) { + mChunks[0] = new ShapesChunk(IsVerbose()); + } + chunk = mChunks[0]; + } else if (depth == 16) { + if (!mChunks[1]) { + mChunks[1] = new ShapesChunk(IsVerbose()); + } + chunk = mChunks[1]; + } else { + wxLogError(wxT("[ShapesCollection] Error loading patch chunk; invalid depth")); + mGoodData = false; + return buffer; + } + + chunk->LoadPatch(buffer); + if (!chunk->IsGood()) { + mGoodData = false; + } + return buffer; +} diff --git a/Shapes/ShapesElements.h b/Shapes/ShapesElements.h new file mode 100644 index 0000000..34b16eb --- /dev/null +++ b/Shapes/ShapesElements.h @@ -0,0 +1,454 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SHAPESLOADERS_H +#define SHAPESLOADERS_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#include "wx/clipbrd.h" +#endif +#include +using std::vector; +#include "../BigEndianBuffer.h" + +#define COLLECTIONS_PER_FILE 32 + +#define SIZEOF_collection_header 32 + +class ShapesElement +{ +private: + bool mVerboseLoading; + +protected: + // So that subclasses can change their status + bool mGoodData; + +public: + ShapesElement(bool verbose): mVerboseLoading(verbose), mGoodData(false) {} + ~ShapesElement(void) {} + + bool IsGood() const { return mGoodData; } + bool IsVerbose() const { return mVerboseLoading; } +}; + +// internal-use utility constants +enum { + COLL_VERSION_8BIT = 0, + COLL_VERSION_TRUECOLOR +}; + +// a color +class ShapesColor: public ShapesElement +{ +private: + bool mLuminescent; + unsigned char mValue; + unsigned short mRed, mGreen, mBlue; + +public: + // constructor/destructor + ShapesColor(bool verbose = false); + ShapesColor(unsigned int r, unsigned int g, unsigned int b, unsigned int value, bool luminescent = false, bool verbose = false); + ~ShapesColor(void); + + // operators + bool operator==(const ShapesColor& other) const; + bool operator!=(const ShapesColor& other) const { return !(*this == other); } + // accessors + bool Luminescent(void) const { return mLuminescent; } + unsigned char Value(void) const { return mValue; } + unsigned short Red(void) const { return mRed; } + unsigned short Green(void) const { return mGreen; } + unsigned short Blue(void) const { return mBlue; } + void SetLuminescent(bool l) { mLuminescent = l; } + void SetRed(unsigned short c) { mRed = c; } + void SetGreen(unsigned short c) { mGreen = c; } + void SetBlue(unsigned short c) { mBlue = c; } + // utilities + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +// a color table +class ShapesColorTable: public ShapesElement +{ +private: + vector mColors; + +public: + ShapesColorTable(bool verbose = false); + ShapesColorTable(std::ifstream& ifs, wxString file_ext); + ~ShapesColorTable(void); + + // operators + bool operator==(const ShapesColorTable& other) const; + bool operator!=(const ShapesColorTable& other) const { return !(*this == other); } + + unsigned int ColorCount(void) const { return mColors.size(); } + ShapesColor *GetColor(unsigned int index) const { return mColors[index]; } + void InsertColor(ShapesColor *color) { mColors.push_back(color); } + + unsigned int SizeInFile() const; + + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset, unsigned int color_count); + BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index); + int SaveToGimp(wxString path) const; + int SaveToPhotoshop(wxString path) const; +}; + +// a bitmap +class ShapesBitmap: public ShapesElement +{ +private: + short mWidth, mHeight, + mBytesPerRow, // width for uncompressed bitmaps, -1 for compressed ones + mBitDepth; // 8 + bool mColumnOrder, // store in column-order format + mTransparent; + unsigned char *mPixels; + // list of frames referencing this bitmap + vector mUsers; + +public: + // constructor/destructor + ShapesBitmap(bool verbose = false); + ShapesBitmap(wxImage image, ShapesColorTable *colortable); + ~ShapesBitmap(void); + + // operators + bool operator==(const ShapesBitmap& other) const; + bool operator!=(const ShapesBitmap& other) const { return !(*this == other); } + + // accessors + short Width(void) const { return mWidth; } + short Height(void) const { return mHeight; } + short BytesPerRow(void) const { return mBytesPerRow; } + short BitDepth(void) const { return mBitDepth; } + bool IsColumnOrdered(void) const { return mColumnOrder; } + bool IsTransparent(void) const { return mTransparent; } + unsigned char* Pixels(void) const { return mPixels; } + // mutators + void SetWidth(short w) { mWidth = w; } + void SetHeight(short h) { mHeight = h; } + void SetBytesPerRow(short b) { mBytesPerRow = b; } + void SetBitDepth(short b) { mBitDepth = b; } + void SetColumnOrdered(bool b) { mColumnOrder = b; } + void SetTransparent(bool n) { mTransparent = n; } + // utilities + void ClipboardCopy(ShapesColorTable* colorTable) const; + void ClipboardPaste(ShapesColorTable* colorTable); + void FromImage(wxImage image, ShapesColorTable* colorTable); + unsigned int SizeInFile() const; + unsigned int SizeInPatch() const { return SizeInFile() + 12; } + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset); + BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index); + void SaveToBMP(wxString path, ShapesColorTable *colorTable) const; + void SaveMaskToBMP(wxString path) const; +}; + +// a frame, aka "low level shape definition" +class ShapesFrame : public ShapesElement +{ +private: + bool mXmirror, + mYmirror, + mKeypointObscured; + float mMinimumLightIntensity; + short mBitmapIndex; + // bitmap scale factor. Computed when loading Shapes + // using world_* fields and associated bitmap dimensions + int mScaleFactor; + // logical origin + short mOriginX, mOriginY; + // keypoint. Used in player legs shapes to specify where to attach torso shapes + short mKeyX, mKeyY; + // FIXME do we really need to store these fields here? + // scaled bitmap rectangle in world coordinates. The physical bitmap rectangle + // is scaled around the frame origin position, which gets translated to (0,0). + // Computed as: + // world_left = -scale_factor * origin_x + // world_top = scale_factor * origin_y + // world_right = scale_factor * (width - origin_x) + // world_bottom = -scale_factor * (height - origin_y) + short mWorldLeft, mWorldRight, mWorldTop, mWorldBottom; + // scaled keypoint position in world coordinates. Computed as: + // world_x0 = scale_factor * (key_x - origin_x) + // world_y0 = -scale_factor * (key_y - origin_y) + short mWorldX0, mWorldY0; + // list of sequences referencing this frame + vector mUsers; + +public: + // constructor/destructor + ShapesFrame(bool verbose = false); + ~ShapesFrame(void); + // operators + bool operator==(const ShapesFrame& other) const; + bool operator!=(const ShapesFrame& other) const { return !(*this == other); } + // accessors + bool IsXmirrored(void) const {return mXmirror;} + bool IsYmirrored(void) const {return mYmirror;} + bool IsKeypointObscured(void) const {return mKeypointObscured;} + float MinimumLightIntensity(void) const {return mMinimumLightIntensity;} + int ScaleFactor(void) const {return mScaleFactor;} + short BitmapIndex(void) const {return mBitmapIndex;} + short OriginX(void) const {return mOriginX;} + short OriginY(void) const {return mOriginY;} + short KeyX(void) const {return mKeyX;} + short KeyY(void) const {return mKeyY;} + short WorldLeft(void) const {return mWorldLeft;} + short WorldRight(void) const {return mWorldRight;} + short WorldTop(void) const {return mWorldTop;} + short WorldBottom(void) const {return mWorldBottom;} + short WorldX0(void) const {return mWorldX0;} + short WorldY0(void) const {return mWorldY0;} + // mutators + void SetXmirrored(bool b) {mXmirror = b;} + void SetYmirrored(bool b) {mYmirror = b;} + void SetKeypointObscured(bool b) {mKeypointObscured = b;} + void SetMinimumLightIntensity(float v) {mMinimumLightIntensity = v;} + void SetBitmapIndex(short i) {mBitmapIndex = i;} + void SetScaleFactor(int s) {mScaleFactor = s;} + void SetOriginX(short x) {mOriginX = x;} + void SetOriginY(short y) {mOriginY = y;} + void SetKeyX(short x) {mKeyX = x;} + void SetKeyY(short y) {mKeyY = y;} + void SetWorldLeft(short s) {mWorldLeft = s;} + void SetWorldRight(short s) {mWorldRight = s;} + void SetWorldTop(short s) {mWorldTop = s;} + void SetWorldBottom(short s) {mWorldBottom = s;} + void SetWorldX0(short s) {mWorldX0 = s;} + void SetWorldY0(short s) {mWorldY0 = s;} + // utilities + unsigned int SizeInFile() const; + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset); +}; + +// sequence types (ShapesSequence.number_of_views). Nobody +// seems to know what these values really mean, they just +// tell the actual number of views in a redundant way +enum { + ANIMATED_1 = 1, // simple isotropic animation + ANIMATED_2TO8 = 2, // 8 view animation + ANIMATED_3TO4 = 3, // 4 view animation + ANIMATED_4 = 4, // 4 view animation + ANIMATED_5TO8 = 5, // 8 view animation + ANIMATED_8 = 8, // 8 view animation + ANIMATED_3TO5 = 9, // 5 view animation + UNANIMATED = 10, // no animation, choose a random frame + ANIMATED_5 = 11 // 5 view animation +}; + +// a sequence, aka "high level shape definition" +class ShapesSequence: public ShapesElement +{ +private: + short mType; + unsigned short mFlags; + wxString mName; + short mNumberOfViews, + mFramesPerView, + mTicksPerFrame, + mKeyFrame, + mTransferMode, + mTransferModePeriod, + mFirstFrameSound, + mKeyFrameSound, + mLastFrameSound, + mPixelsToWorld, + mLoopFrame; +//FIXME This could be made private +public: + vector mFrameIndexes; + +public: + // constructor/destructor + ShapesSequence(bool verbose = false); + ~ShapesSequence(void); + // operators + bool operator==(const ShapesSequence& other) const; + bool operator!=(const ShapesSequence& other) const { return !(*this == other); } + // accessors + short Type(void) const {return mType;} + unsigned short Flags(void) const {return mFlags;} + wxString Name(void) const {return mName;} + short NumberOfViews(void) const {return mNumberOfViews;} + short FramesPerView(void) const {return mFramesPerView;} + short TicksPerFrame(void) const {return mTicksPerFrame;} + short KeyFrame(void) const {return mKeyFrame;} + short TransferMode(void) const {return mTransferMode;} + short TransferModePeriod(void) const {return mTransferModePeriod;} + short FirstFrameSound(void) const {return mFirstFrameSound;} + short KeyFrameSound(void) const {return mKeyFrameSound;} + short LastFrameSound(void) const {return mLastFrameSound;} + short PixelsToWorld(void) const {return mPixelsToWorld;} + short LoopFrame(void) const {return mLoopFrame;} + unsigned int FrameIndexCount(void) const {return mFrameIndexes.size();} + short GetFrameIndex(unsigned int index) const {return mFrameIndexes[index];} + // mutators + void SetType(short t) {mType = t;} + void SetFlags(unsigned short f) {mFlags = f;} + void SetName(wxString name) {mName = name;} + void SetNumberOfViews(short n) {mNumberOfViews = n;} + void SetFramesPerView(short n) {mFramesPerView = n;} + void SetTicksPerFrame(short n) {mTicksPerFrame = n;} + void SetKeyFrame(short n) {mKeyFrame = n;} + void SetTransferMode(short n) {mTransferMode = n;} + void SetTransferModePeriod(short n) {mTransferModePeriod = n;} + void SetFirstFrameSound(short n) {mFirstFrameSound = n;} + void SetKeyFrameSound(short n) {mKeyFrameSound = n;} + void SetLastFrameSound(short n) {mLastFrameSound = n;} + void SetPixelsToWorld(short n) {mPixelsToWorld = n;} + void SetLoopFrame(short n) {mLoopFrame = n;} + void SetFrameIndex(unsigned int index, short value) {mFrameIndexes[index] = value;} + // utilities + unsigned int SizeInFile() const; + unsigned int SizeInPatch() const { return SizeInFile() + 12; } + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, long offset); + BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index); +}; + +int ActualNumberOfViews(int t); + +// chunk types. Bitmap encoding seems to depend on this setting +enum { + _unused_collection = 0, // plain + _wall_collection, // plain + _object_collection, // RLE + _interface_collection, // plain + _scenery_collection // RLE +}; + +// a Shapes chunk +class ShapesChunk: public ShapesElement +{ +private: + short mVersion; // COLLECTION_VERSION (same for all Marathon games) + short mType; + unsigned short mFlags; // unused; 0 in Durandal/Infinity, 1 in Rubicon and others + short mPixelsToWorld; + + vector mColorTables; + vector mSequences; + vector mFrames; + vector mBitmaps; + +public: + // constructor/destructor + ShapesChunk(bool verbose = false); + ~ShapesChunk(void); + void Clear(void); + bool operator==(const ShapesChunk& other) const; + bool operator!=(const ShapesChunk& other) const { return !(*this == other); } + // chunk data access + int Version() const {return mVersion;} + int Type() const {return mType;} + int Flags() const {return mFlags;} + int ScaleFactor() const {return mPixelsToWorld;} + unsigned int ColorTableCount() const {return mColorTables.size();} + unsigned int BitmapCount() const {return mBitmaps.size();} + unsigned int FrameCount() const {return mFrames.size();} + unsigned int SequenceCount() const {return mSequences.size();} + ShapesColorTable* GetColorTable(unsigned int index) const; + ShapesBitmap* GetBitmap(unsigned int index) const; + ShapesFrame* GetFrame(unsigned int index) const; + ShapesSequence* GetSequence(unsigned int index) const; + // chunk alteration + void InsertColorTable(ShapesColorTable *ct); + void DeleteColorTable(unsigned int ct); + void InsertBitmap(ShapesBitmap *b); + void DeleteBitmap(unsigned int b); + void InsertFrame(ShapesFrame *f); + void DeleteFrame(unsigned int f); + void InsertSequence(ShapesSequence *s); + void DeleteSequence(unsigned int s); + // utilities + + void ClipboardCopy(); + void ClipboardPaste(); + unsigned int SizeInFile() const; + unsigned int SizeInPatch(const ShapesChunk* other) const; + BigEndianBuffer& SaveObject(BigEndianBuffer& stream); + BigEndianBuffer& SavePatch(BigEndianBuffer& stream, const ShapesChunk* other); + BigEndianBuffer& LoadObject(BigEndianBuffer& stream); + BigEndianBuffer& LoadPatch(BigEndianBuffer& buffer); +}; + +// a Shapes collection +class ShapesCollection: public ShapesElement +{ +private: + short mStatus; + unsigned short mFlags; + ShapesChunk *mChunks[2]; // chunks for 8-bit and truecolor game + +public: + ShapesCollection(bool verbose = false); + ~ShapesCollection(void); + // accessors + int Status(void) const {return mStatus;} + int Flags(void) const {return mFlags;} + // collection data access + bool Defined(unsigned int chunk) const; + int Version(unsigned int chunk) const; + int Type(unsigned int chunk) const; + int Flags(unsigned int chunk) const; + int ScaleFactor(unsigned int chunk) const; + int ColorTableCount(unsigned int chunk) const; + int BitmapCount(unsigned int chunk) const; + int FrameCount(unsigned int chunk) const; + int SequenceCount(unsigned int chunk) const; + ShapesColorTable* GetColorTable(unsigned int chunk, unsigned int index) const; + ShapesBitmap* GetBitmap(unsigned int chunk, unsigned int index) const; + ShapesFrame* GetFrame(unsigned int chunk, unsigned int index) const; + ShapesSequence* GetSequence(unsigned int chunk, unsigned int index) const; + ShapesChunk* GetChunk(unsigned int chunk) const; + // collection alteration + void InsertColorTable(ShapesColorTable *ct, unsigned int chunk); + void DeleteColorTable(unsigned int chunk, unsigned int ct); + void InsertBitmap(ShapesBitmap *b, unsigned int chunk); + void DeleteBitmap(unsigned int chunk, unsigned int b); + void InsertFrame(ShapesFrame *f, unsigned int chunk); + void DeleteFrame(unsigned int chunk, unsigned int f); + void InsertSequence(ShapesSequence *s, unsigned int chunk); + void DeleteSequence(unsigned int chunk, unsigned int s); + // utilities + unsigned int SizeInFile(unsigned int chunk) const; + +#if wxUSE_STD_IOSTREAM + wxSTD ostream& SaveObject(wxSTD ostream& stream); + wxSTD ostream& SavePatch(wxSTD ostream& stream, const ShapesCollection& other, int index, int depth); + wxSTD istream& LoadObject(wxSTD istream& stream); +#else + wxOutputStream& SaveObject(wxOutputStream& stream); + wxOutputStream& SavePatch(wxOutputStream& stream, const ShapesCollection& other, int index, int depth); + wxInputStream& LoadObject(wxInputStream& stream); +#endif + BigEndianBuffer& LoadPatch(BigEndianBuffer& buffer); +}; + +#endif + diff --git a/Shapes/ShapesTreeItemData.cpp b/Shapes/ShapesTreeItemData.cpp new file mode 100644 index 0000000..4851177 --- /dev/null +++ b/Shapes/ShapesTreeItemData.cpp @@ -0,0 +1,50 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "ShapesTreeItemData.h" + +ShapesTreeItemData::ShapesTreeItemData(int id, int vers, int sect, int seq): + coll_id(id), version(vers), section(sect), sequence(seq) +{ + +} + +ShapesTreeItemData::~ShapesTreeItemData(void) +{ + +} + +int ShapesTreeItemData::CollID(void) const +{ + return coll_id; +} + +int ShapesTreeItemData::Version(void) const +{ + return version; +} + +int ShapesTreeItemData::Section(void) const +{ + return section; +} + +int ShapesTreeItemData::Sequence(void) const +{ + return sequence; +} + diff --git a/Shapes/ShapesTreeItemData.h b/Shapes/ShapesTreeItemData.h new file mode 100644 index 0000000..124957c --- /dev/null +++ b/Shapes/ShapesTreeItemData.h @@ -0,0 +1,53 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef SHAPESTREEITEMDATA_H +#define SHAPESTREEITEMDATA_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "wx/treectrl.h" + +enum { + TREESECTION_COLLECTION = 1, + TREESECTION_VERSION, + TREESECTION_BITMAPS, + TREESECTION_COLORTABLES, + TREESECTION_FRAMES, + TREESECTION_SEQUENCES +}; + +class ShapesTreeItemData: public wxTreeItemData { +private: + int coll_id; + int version; + int section; + int sequence; + +public: + ShapesTreeItemData(int id=-1, int vers=-1, int sect=-1, int seq=-1); + ~ShapesTreeItemData(void); + + int CollID(void) const; + int Version(void) const; + int Section(void) const; + int Sequence(void) const; +}; + +#endif diff --git a/Shapes/ShapesView.cpp b/Shapes/ShapesView.cpp new file mode 100644 index 0000000..e95bc0c --- /dev/null +++ b/Shapes/ShapesView.cpp @@ -0,0 +1,2000 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "ShapesView.h" +#include "ShapesDocument.h" +#include "../DefaultNames.h" +#include "utilities.h" +#include + +#define INT_TO_WXSTRING(a) wxString::Format(wxT("%d"), a) + +BEGIN_EVENT_TABLE(ShapesView, wxView) +EVT_MENU(EDIT_MENU_COPY, ShapesView::MenuEditCopy) +EVT_MENU(EDIT_MENU_DELETE, ShapesView::MenuEditDelete) +EVT_MENU(EDIT_MENU_PASTE, ShapesView::MenuEditPaste) +EVT_MENU_RANGE(VIEW_MENU_COLORTABLE_0, VIEW_MENU_COLORTABLE_7, ShapesView::MenuViewCT) +EVT_MENU_RANGE(VIEW_MENU_TNSIZE_SMALL, VIEW_MENU_TNSIZE_AUTO, ShapesView::MenuViewTNSize) +EVT_MENU(VIEW_MENU_TRANSPARENCY, ShapesView::MenuViewTransparency) +EVT_MENU(VIEW_MENU_CENTERORIGIN, ShapesView::MenuViewCenterOrigin) +EVT_MENU(SHAPES_MENU_ADDCOLORTABLE, ShapesView::MenuShapesAddColorTable) +EVT_MENU(SHAPES_MENU_SAVECOLORTABLE, ShapesView::MenuShapesSaveColorTable) +EVT_MENU(SHAPES_MENU_SAVECOLORTABLETOPS, ShapesView::MenuShapesSaveColorTable) +EVT_MENU(SHAPES_MENU_ADDBITMAP, ShapesView::MenuShapesAddBitmap) +EVT_MENU(SHAPES_MENU_EXPORTBITMAP, ShapesView::MenuShapesExportBitmap) +EVT_MENU(SHAPES_MENU_EXPORTMASK, ShapesView::MenuShapesExportBitmapMask) +EVT_MENU(SHAPES_MENU_EXPORTBITMAPS, ShapesView::MenuShapesExportBitmaps) +EVT_MENU(SHAPES_MENU_EXPORTMASKS, ShapesView::MenuShapesExportBitmapMasks) +EVT_MENU(SHAPES_MENU_ADDFRAME, ShapesView::MenuShapesNewFrame) +EVT_MENU(SHAPES_MENU_ADDSEQUENCE, ShapesView::MenuShapesNewSequence) +EVT_MENU(SHAPES_MENU_GENERATEPATCH, ShapesView::MenuShapesGeneratePatch) +EVT_MENU(SHAPES_MENU_IMPORTPATCH, ShapesView::MenuShapesImportPatch) +EVT_TREE_SEL_CHANGED(-1, ShapesView::OnTreeSelect) +// bitmaps +EVT_COMMAND(BITMAP_BROWSER, wxEVT_BITMAPBROWSER, ShapesView::OnBitmapSelect) +EVT_COMMAND(BITMAP_BROWSER, wxEVT_BITMAPBROWSER_DELETE, ShapesView::BitmapDelete) +EVT_COMMAND_RANGE(CB_COLUMN_ORDER, CB_ENABLE_TRANSPARENCY, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleBitmapCheckboxes) +// color tables +EVT_COMMAND(wxID_ANY, wxEVT_CTBROWSER, ShapesView::OnCTSelect) +EVT_COMMAND(wxID_ANY, wxEVT_CTVIEW_SELECTION, ShapesView::CTColorSelect) +EVT_COMMAND(wxID_ANY, wxEVT_CTVIEW_COLOR, ShapesView::CTColorChanged) +EVT_COMMAND(CB_SELF_LUMINESCENT, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleSelfLuminCheckbox) +EVT_BUTTON(BTN_GRADIENT, ShapesView::MakeCTGradient) +// frames +EVT_COMMAND(FRAME_BROWSER, wxEVT_FRAMEBROWSER, ShapesView::OnFrameSelect) +EVT_COMMAND(FRAME_BROWSER, wxEVT_FRAMEBROWSER_DELETE, ShapesView::FrameDelete) +EVT_COMMAND(FRAME_VIEW, wxEVT_FRAMEVIEW_DRAG, ShapesView::OnFramePointDrag) +EVT_SPINCTRL(FIELD_BITMAP_INDEX, ShapesView::BitmapIndexSpin) +EVT_COMMAND_RANGE(CB_XMIRROR, CB_KEYPOINT, wxEVT_COMMAND_CHECKBOX_CLICKED, ShapesView::ToggleFrameCheckboxes) +EVT_TEXT(FIELD_ORIGIN_X, ShapesView::EditFrameFields) +EVT_TEXT(FIELD_ORIGIN_Y, ShapesView::EditFrameFields) +EVT_TEXT(FIELD_KEY_X, ShapesView::EditFrameFields) +EVT_TEXT(FIELD_KEY_Y, ShapesView::EditFrameFields) +EVT_TEXT(FIELD_FRAME_SCALEFACTOR, ShapesView::EditFrameFields) +EVT_TEXT(FIELD_MIN_LIGHT_INT, ShapesView::EditFrameFields) +// sequences +EVT_TEXT(FIELD_SEQ_NAME, ShapesView::EditSequenceFields) +EVT_BUTTON(BTN_DELETE_SEQ, ShapesView::DeleteSequence) +EVT_CHOICE(MENU_SEQ_TYPE, ShapesView::EditSequenceType) +EVT_TEXT(FIELD_SEQ_FRAMES_PER_VIEW, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_TICKS_PER_FRAME, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_LOOP_FRAME, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_KEY_FRAME, ShapesView::EditSequenceFields) +EVT_CHOICE(MENU_SEQ_XFER_MODE, ShapesView::EditSequenceXferMode) +EVT_TEXT(FIELD_SEQ_XFER_MODE_PERIOD, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_FIRST_FRAME_SND, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_KEY_FRAME_SND, ShapesView::EditSequenceFields) +EVT_TEXT(FIELD_SEQ_LAST_FRAME_SND, ShapesView::EditSequenceFields) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(ShapesView, wxView) + +ShapesView::ShapesView(void): +wxView(), mSelectedColl(-1), mSelectedVers(-1), mSelectedSequence(-1), mViewColorTable(-1) +{ + mFrame = (wxFrame *)NULL; +} + +ShapesView::~ShapesView(void) +{ +} + +bool ShapesView::OnCreate(wxDocument *doc, long WXUNUSED(flags)) +{ + wxString frameTitle = _T("ShapeFusion : Shapes : "); + + frameTitle.Append(doc->GetFilename()); + mFrame = wxGetApp().CreateChildFrame(doc, this, frameTitle, wxPoint(0, 0), wxSize(900, 600)); + mFrame->SetSizeHints(200, 200); + CreateViewMenu(mFrame->GetMenuBar()); + CreateShapesMenu(mFrame->GetMenuBar()); + menubar = mFrame->GetMenuBar(); + + // Add everything to panel, so background is same as a dialog + main_panel = new wxPanel(mFrame); + main_panel->Show(); + + mainbox = new wxBoxSizer(wxHORIZONTAL); + // create the collection tree + colltree = new wxTreeCtrl(main_panel, -1, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT); + colltree->DeleteAllItems(); + wxTreeItemId treeroot = colltree->AddRoot(doc->GetFilename()); + mainbox->Add(colltree, 2, wxEXPAND); + // empty space (e.g. what is displayed when selecting the Sequences node) + // adding at least a panel is apparently needed to make sizers work + dummy_sizer = new wxBoxSizer(wxVERTICAL); + wxPanel *dummy_panel = new wxPanel(main_panel); + dummy_sizer->Add(dummy_panel, 1, wxEXPAND); + mainbox->Add(dummy_sizer, 5, wxEXPAND); + // collection section + coll_sizer = new wxBoxSizer(wxVERTICAL); + coll_text = new wxStaticText(main_panel, -1, wxT("Collection info")); + coll_static_box = new wxStaticBox(main_panel, -1, wxT("Collection info")); + coll_inner_box = new wxStaticBoxSizer(coll_static_box, wxVERTICAL); + coll_inner_box->Add(coll_text, 0, wxALL, 5); + coll_sizer->AddStretchSpacer(); + coll_sizer->Add(coll_inner_box, 0, wxALIGN_CENTER); + coll_sizer->AddStretchSpacer(); + mainbox->Add(coll_sizer, 5, wxEXPAND); + mainbox->Show(coll_sizer, false); + // chunk section + chunk_sizer = new wxBoxSizer(wxVERTICAL); + chunk_static_box = new wxStaticBox(main_panel, -1, wxT("Version info")); + chunk_static_box->SetThemeEnabled(true); + chunk_inner_box = new wxStaticBoxSizer(chunk_static_box, wxVERTICAL); + chunk_undef_label = new wxStaticText(main_panel, -1, wxT("Not defined")); + chunk_inner_box->Add(chunk_undef_label, 0, wxCENTER | wxALL, 5); + chunk_grid = new wxFlexGridSizer(2, 4, 0, 0); + chunk_inner_box->Add(chunk_grid, 0, wxCENTER | wxALL, 5); + chunk_version_label = new wxStaticText(main_panel, -1, wxT("Version:")); + chunk_type_label = new wxStaticText(main_panel, -1, wxT("Collection type:")); + chunk_flags_label = new wxStaticText(main_panel, -1, wxT("Flags:")); + chunk_sf_label = new wxStaticText(main_panel, -1, wxT("Collection scale factor:")); + chunk_version_field = new wxTextCtrl(main_panel, -1, wxT("0")); + wxString coll_type_labels[] = { wxT("Unused"), + wxT("Wall textures"), + wxT("Objects"), + wxT("Interface graphics"), + wxT("Scenery objects") }; + chunk_type_menu = new wxChoice(main_panel, -1, wxDefaultPosition, wxDefaultSize, 5, coll_type_labels, 0); + chunk_flags_field = new wxTextCtrl(main_panel, -1, wxT("0")); + chunk_sf_field = new wxTextCtrl(main_panel, -1, wxT("0")); + chunk_grid->Add(chunk_version_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + chunk_grid->Add(chunk_version_field, 0, wxALIGN_LEFT); + chunk_grid->Add(chunk_type_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + chunk_grid->Add(chunk_type_menu, 0, wxALIGN_LEFT); + chunk_grid->Add(chunk_flags_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + chunk_grid->Add(chunk_flags_field, 0, wxALIGN_LEFT); + chunk_grid->Add(chunk_sf_label, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + chunk_grid->Add(chunk_sf_field, 0, wxALIGN_LEFT); + chunk_version_field->Enable(false); + chunk_type_menu->Enable(false); + chunk_flags_field->Enable(false); + chunk_sf_field->Enable(false); + chunk_sizer->AddStretchSpacer(); + chunk_sizer->Add(chunk_inner_box, 0, wxALIGN_CENTER); + chunk_sizer->AddStretchSpacer(); + mainbox->Add(chunk_sizer, 5, wxEXPAND); + mainbox->Show(chunk_sizer, false); + // create the color tables section + ct_outer_sizer = new wxBoxSizer(wxVERTICAL); + ctb = new CTBrowser(main_panel); + ct_count_label = new wxStaticText(main_panel, -1, wxT("N color tables")); + ct_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Color table N of M")); + ct_edit_box = new wxStaticBoxSizer(ct_edit_static_box, wxVERTICAL); + ct_view = new CTView(main_panel); + ct_inner_edit_box = new wxBoxSizer(wxHORIZONTAL); + ct_self_lumin_checkbox = new wxCheckBox(main_panel, CB_SELF_LUMINESCENT, wxT("Self-luminescent color"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE); + ct_gradient_button = new wxButton(main_panel, BTN_GRADIENT, wxT("Make gradient")); + ct_edit_box->Add(ct_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5); + ct_edit_box->Add(ct_inner_edit_box, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5); + ct_inner_edit_box->Add(ct_self_lumin_checkbox, 0, wxALIGN_CENTER); + ct_inner_edit_box->AddStretchSpacer(); + ct_inner_edit_box->Add(ct_gradient_button, 0, wxALIGN_CENTER); + ct_outer_sizer->Add(ctb, 1, wxGROW); + ct_outer_sizer->Add(ct_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10); + ct_outer_sizer->Add(ct_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10); + ct_outer_sizer->Show(ct_edit_box, false); + mainbox->Add(ct_outer_sizer, 5, wxEXPAND); + mainbox->Show(ct_outer_sizer, false); + // create the bitmaps section + b_outer_sizer = new wxBoxSizer(wxVERTICAL); + bb = new BitmapBrowser(main_panel, BITMAP_BROWSER); + bb->SetThumbnailSize(64); + b_count_label = new wxStaticText(main_panel, -1, wxT("N bitmaps")); + b_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Bitmap N of M")); + b_edit_box = new wxStaticBoxSizer(b_edit_static_box, wxHORIZONTAL); + b_edit_inner_box = new wxBoxSizer(wxVERTICAL); + b_info_label = new wxStaticText(main_panel, -1, wxT("AxB pixels")); + b_order_checkbox = new wxCheckBox(main_panel, CB_COLUMN_ORDER, wxT("Store pixels in column order")); + b_transparency_checkbox = new wxCheckBox(main_panel, CB_ENABLE_TRANSPARENCY, wxT("Enable transparency")); + b_view = new BitmapView(main_panel); + b_edit_inner_box->Add(b_info_label, 0, wxALIGN_LEFT | wxBOTTOM, 10); + b_edit_inner_box->Add(b_order_checkbox, 0, wxALIGN_LEFT); + b_edit_inner_box->Add(b_transparency_checkbox, 0, wxALIGN_LEFT); + b_edit_inner_box->AddStretchSpacer(); + b_edit_box->Add(b_edit_inner_box, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5); + b_edit_box->Add(b_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5); + b_outer_sizer->Add(bb, 1, wxGROW); + b_outer_sizer->Add(b_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10); + b_outer_sizer->Add(b_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10); + b_outer_sizer->Show(b_edit_box, false); + mainbox->Add(b_outer_sizer, 5, wxEXPAND); + mainbox->Show(b_outer_sizer, false); + // create the frames section + f_outer_sizer = new wxBoxSizer(wxVERTICAL); + // FIXME the FrameView should be initialized later, but spurious event handlers + // dereferencing it are triggered during initialization + f_view = new FrameView(main_panel, FRAME_VIEW); + fb = new FrameBrowser(main_panel, FRAME_BROWSER); + fb->SetThumbnailSize(64); + f_count_label = new wxStaticText(main_panel, -1, wxT("N frames")); + f_edit_static_box = new wxStaticBox(main_panel, -1, wxT("Frame N")); + f_edit_box = new wxStaticBoxSizer(f_edit_static_box, wxHORIZONTAL); + f_bitmap_label = new wxStaticText(main_panel, -1, wxT("Associated bitmap:")); + f_bitmap_id = new wxSpinCtrl(main_panel, FIELD_BITMAP_INDEX, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_xmirror_checkbox = new wxCheckBox(main_panel, CB_XMIRROR, wxT("X mirror")); + f_ymirror_checkbox = new wxCheckBox(main_panel, CB_YMIRROR, wxT("Y mirror")); + f_keypoint_checkbox = new wxCheckBox(main_panel, CB_KEYPOINT, wxT("Keypoint obscured")); + f_origin_x_label = new wxStaticText(main_panel, -1, wxT("Origin X:"), wxDefaultPosition, wxSize(150, -1)); + f_origin_x_field = new wxTextCtrl(main_panel, FIELD_ORIGIN_X, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_origin_y_label = new wxStaticText(main_panel, -1, wxT("Origin Y:"), wxDefaultPosition, wxSize(150, -1)); + f_origin_y_field = new wxTextCtrl(main_panel, FIELD_ORIGIN_Y, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_key_x_label = new wxStaticText(main_panel, -1, wxT("Keypoint X:"), wxDefaultPosition, wxSize(150, -1)); + f_key_x_field = new wxTextCtrl(main_panel, FIELD_KEY_X, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_key_y_label = new wxStaticText(main_panel, -1, wxT("Keypoint Y:"), wxDefaultPosition, wxSize(150, -1)); + f_key_y_field = new wxTextCtrl(main_panel, FIELD_KEY_Y, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_scalefactor_label = new wxStaticText(main_panel, -1, wxT("Scale factor:"), wxDefaultPosition, wxSize(150, -1)); + f_scalefactor_field = new wxTextCtrl(main_panel, FIELD_FRAME_SCALEFACTOR, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_mli_label = new wxStaticText(main_panel, -1, wxT("Minimum lightness (%):"), wxDefaultPosition, wxSize(150, -1)); + f_mli_field = new wxTextCtrl(main_panel, FIELD_MIN_LIGHT_INT, wxT("0"), wxDefaultPosition, wxSize(60, -1)); + f_origin_box = new wxFlexGridSizer(10, 2, 5, 0); + f_origin_box->Add(f_bitmap_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_bitmap_id, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_xmirror_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->AddStretchSpacer(); + f_origin_box->Add(f_ymirror_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->AddStretchSpacer(); + f_origin_box->Add(f_scalefactor_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_scalefactor_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_origin_x_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_origin_x_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_origin_y_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_origin_y_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_key_x_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_key_x_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_key_y_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_key_y_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_keypoint_checkbox, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->AddStretchSpacer(); + f_origin_box->Add(f_mli_label, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_origin_box->Add(f_mli_field, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + f_edit_inner_box = new wxBoxSizer(wxVERTICAL); + f_edit_inner_box->Add(f_origin_box, 0, wxALIGN_LEFT); + f_edit_box->Add(f_edit_inner_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 5); + f_edit_box->Add(f_view, 1, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, 5); + f_outer_sizer->Add(fb, 1, wxGROW); + f_outer_sizer->Add(f_count_label, 1, wxALIGN_LEFT | wxLEFT | wxTOP | wxBOTTOM, 10); + f_outer_sizer->Add(f_edit_box, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10); + f_outer_sizer->Show(f_edit_box, false); + mainbox->Add(f_outer_sizer, 5, wxEXPAND); + mainbox->Show(f_outer_sizer, false); + // create the sequences section + s_outer_static_box = new wxStaticBox(main_panel, -1, wxT("Sequence")); + s_outer_sizer = new wxStaticBoxSizer(s_outer_static_box, wxVERTICAL); + + s_box1 = new wxBoxSizer(wxHORIZONTAL); + s_outer_sizer->Add(s_box1, 0, wxEXPAND | wxALIGN_TOP | wxALL, 5); + s_name_label = new wxStaticText(main_panel, -1, wxT("Name:")); + s_name_field = new wxTextCtrl(main_panel, FIELD_SEQ_NAME, wxT("foobar")); + s_delete_button = new wxButton(main_panel, BTN_DELETE_SEQ, wxT("Delete sequence")); + s_box1->Add(s_name_label, 0, wxALIGN_CENTER | wxRIGHT, 5); + s_box1->Add(s_name_field, 1, wxALIGN_CENTER); + s_box1->Add(s_delete_button, 0, wxALIGN_CENTER | wxLEFT, 20); + + s_box2 = new wxBoxSizer(wxHORIZONTAL); + s_outer_sizer->Add(s_box2, 0, wxEXPAND | wxALIGN_TOP | wxALL, 5); + s_grid_box = new wxFlexGridSizer(5, 2, 4, 0); + s_box2->Add(s_grid_box, 0, wxEXPAND | wxALIGN_TOP); + s_type_label = new wxStaticText(main_panel, -1, wxT("Sequence type:"), wxDefaultPosition, wxSize(120, -1)); + wxString anim_type_labels[] = { wxT("Display a random frame"), + wxT("Animation with 1 view"), + wxT("Animation with 4 views"), + wxT("Animation with 5 views"), + wxT("Animation with 8 views") }; + s_type_menu = new wxChoice(main_panel, MENU_SEQ_TYPE, wxDefaultPosition, wxDefaultSize, 5, anim_type_labels, 0); + s_fpv_label = new wxStaticText(main_panel, -1, wxT("Frames per view:"), wxDefaultPosition, wxSize(120, -1)); + s_fpv_field = new wxTextCtrl(main_panel, FIELD_SEQ_FRAMES_PER_VIEW, wxT("1")); + s_tpf_label = new wxStaticText(main_panel, -1, wxT("Ticks per frame:"), wxDefaultPosition, wxSize(120, -1)); + s_tpf_field = new wxTextCtrl(main_panel, FIELD_SEQ_TICKS_PER_FRAME, wxT("1")); + s_lf_label = new wxStaticText(main_panel, -1, wxT("Loop at frame:"), wxDefaultPosition, wxSize(120, -1)); + s_lf_field = new wxTextCtrl(main_panel, FIELD_SEQ_LOOP_FRAME, wxT("0")); + s_kf_label = new wxStaticText(main_panel, -1, wxT("Key frame:"), wxDefaultPosition, wxSize(120, -1)); + s_kf_field = new wxTextCtrl(main_panel, FIELD_SEQ_KEY_FRAME, wxT("0")); + s_grid_box->Add(s_type_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_type_menu, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_fpv_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_fpv_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_tpf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_tpf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_lf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_lf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_kf_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box->Add(s_kf_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + + s_separator = new wxPanel(main_panel); + s_box2->Add(s_separator, 1, wxEXPAND); + + s_grid_box2 = new wxFlexGridSizer(5, 2, 4, 0); + s_box2->Add(s_grid_box2, 0, wxEXPAND | wxALIGN_TOP); + s_xfermode_label = new wxStaticText(main_panel, -1, wxT("Transfer mode:"), wxDefaultPosition, wxSize(140, -1)); + wxString xfermode_labels[] = { wxT("Normal"), + wxT("Fade out to black"), + wxT("50% invisibility"), + wxT("75% invisibility"), + wxT("Pulsate"), + wxT("Wobble"), + wxT("Fast wobble"), + wxT("100% static"), + wxT("50% static"), + wxT("Landscape"), + wxT("Smear"), + wxT("Fade out static"), + wxT("Pulsating static"), + wxT("Fold in"), + wxT("Fold out"), + wxT("Horizontal slide"), + wxT("Fast horizontal slide"), + wxT("Vertical slide"), + wxT("Fast vertical slide"), + wxT("Wander"), + wxT("Fast wander"), + wxT("Big landscape") + }; + s_xfermode_menu = new wxChoice(main_panel, MENU_SEQ_XFER_MODE, wxDefaultPosition, wxDefaultSize, 22, xfermode_labels, 0); + s_xferperiod_label = new wxStaticText(main_panel, -1, wxT("Transfer mode period:"), wxDefaultPosition, wxSize(150, -1)); + s_xferperiod_field = new wxTextCtrl(main_panel, FIELD_SEQ_XFER_MODE_PERIOD, wxT("1")); + s_ffs_label = new wxStaticText(main_panel, -1, wxT("First frame sound:"), wxDefaultPosition, wxSize(150, -1)); + s_ffs_field = new wxTextCtrl(main_panel, FIELD_SEQ_FIRST_FRAME_SND, wxT("0")); + s_kfs_label = new wxStaticText(main_panel, -1, wxT("Key frame sound:"), wxDefaultPosition, wxSize(150, -1)); + s_kfs_field = new wxTextCtrl(main_panel, FIELD_SEQ_KEY_FRAME_SND, wxT("0")); + s_lfs_label = new wxStaticText(main_panel, -1, wxT("Last frame sound:"), wxDefaultPosition, wxSize(150, -1)); + s_lfs_field = new wxTextCtrl(main_panel, FIELD_SEQ_LAST_FRAME_SND, wxT("0")); + s_grid_box2->Add(s_xfermode_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT, 5); + s_grid_box2->Add(s_xfermode_menu, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_xferperiod_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT, 5); + s_grid_box2->Add(s_xferperiod_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_ffs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_ffs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_kfs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_kfs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_lfs_label, 1, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + s_grid_box2->Add(s_lfs_field, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + + s_fb = new SequenceView(main_panel, wxID_ANY); + s_outer_sizer->Add(s_fb, 1, wxEXPAND | wxALL, 5); + mainbox->Add(s_outer_sizer, 5, wxEXPAND | wxLEFT | wxRIGHT | wxTOP | wxBOTTOM, 10); + mainbox->Show(s_outer_sizer, false); + + mainbox->Layout(); + main_panel->SetSizer(mainbox); +#ifdef __X__ + // X seems to require a forced resize + int x, y; + + mFrame->GetSize(&x, &y); + mFrame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y); +#endif + mFrame->Show(true); + Activate(true); + + return true; +} + +void ShapesView::OnDraw(wxDC *WXUNUSED(dc)) +{ +} + +void ShapesView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint)) +{ + unsigned int collCount = ((ShapesDocument*)GetDocument())->CollectionCount(); + + if (collCount == 0) + return; + + // update all levels of the tree control + for (unsigned int i = 0; i < collCount; i++) { + // collection name nodes + ShapesTreeItemData *itemdata = new ShapesTreeItemData(i, -1, TREESECTION_COLLECTION); + wxTreeItemId coll = colltree->AppendItem(colltree->GetRootItem(), GetName(wxT("collection"), i), + -1, -1, itemdata); + + for (unsigned int j = 0; j < 2; j++) { + // color version nodes + ShapesTreeItemData *id = new ShapesTreeItemData(i, j, TREESECTION_VERSION); + wxString label; + + if (j == COLL_VERSION_8BIT) + label = wxT("8-bit color version"); + else if (j == COLL_VERSION_TRUECOLOR) + label = wxT("True color version"); + wxTreeItemId coll2 = colltree->AppendItem(coll, label, -1, -1, id); + + if (((ShapesDocument*)GetDocument())->CollectionDefined(i, j)) { + // section nodes + ShapesTreeItemData *id_b = new ShapesTreeItemData(i, j, TREESECTION_BITMAPS), + *id_ct = new ShapesTreeItemData(i, j, TREESECTION_COLORTABLES), + *id_f = new ShapesTreeItemData(i, j, TREESECTION_FRAMES), + *id_s = new ShapesTreeItemData(i, j, TREESECTION_SEQUENCES); + wxTreeItemId coll_b = colltree->AppendItem(coll2, wxT("Bitmaps"), -1, -1, id_b), + coll_ct = colltree->AppendItem(coll2, wxT("Color tables"), -1, -1, id_ct), + coll_f = colltree->AppendItem(coll2, wxT("Frames"), -1, -1, id_f), + coll_s = colltree->AppendItem(coll2, wxT("Sequences"), -1, -1, id_s); + + for (unsigned int k = 0; k < ((ShapesDocument*)GetDocument())->CollectionSequenceCount(i, j); k++) { + // sequence nodes + ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(i, j, k); + wxString blabel; + ShapesTreeItemData *id_seq = new ShapesTreeItemData(i, j, TREESECTION_SEQUENCES, k); + + blabel << k; + if (seq->Name().Length() > 0) + blabel << wxT(" - ") << seq->Name(); + colltree->AppendItem(coll_s, blabel, -1, -1, id_seq); + } + } + } + } +} + +bool ShapesView::OnClose(bool deleteWindow) +{ + if (!GetDocument()->Close()) + return false; + Activate(false); + if (deleteWindow) { + delete mFrame; + return true; + } + return true; +} + +// return the id of the "Sequences" tree item relative to +// the specified collection and color version +wxTreeItemId ShapesView::GetSequencesTreeItem(unsigned int collection, unsigned int version) const +{ + wxTreeItemIdValue thecookie; + wxTreeItemId rootid = colltree->GetRootItem(), + collnameid = colltree->GetFirstChild(rootid, thecookie); + + // descend into the tree towards the right item + while (collnameid.IsOk()) { + ShapesTreeItemData *collname_data = dynamic_cast(colltree->GetItemData(collnameid)); + + if (collname_data->CollID() == (int)collection) { + // found right collection branch + wxTreeItemIdValue thecookieII; + wxTreeItemId collversid = colltree->GetFirstChild(collnameid, thecookieII); + + while (collversid.IsOk()) { + ShapesTreeItemData *collvers_data = dynamic_cast(colltree->GetItemData(collversid)); + + if (collvers_data->Version() == (int)version) { + // found right version node + wxTreeItemIdValue thecookieIII; + wxTreeItemId sectid = colltree->GetFirstChild(collversid, thecookieIII); + + while (sectid.IsOk()) { + ShapesTreeItemData *sect_data = dynamic_cast(colltree->GetItemData(sectid)); + + if (sect_data->Section() == TREESECTION_SEQUENCES) { + // here we are + return sectid; + } + sectid = colltree->GetNextChild(collversid, thecookieIII); + } + } + collversid = colltree->GetNextChild(collnameid, thecookieII); + } + } + collnameid = colltree->GetNextChild(rootid, thecookie); + } + return wxTreeItemId(); // ctor makes it invalid, so ok +} + +void ShapesView::MenuEditCopy(wxCommandEvent& e) +{ + ShapesTreeItemData* selected_item_data = dynamic_cast(colltree->GetItemData(colltree->GetSelection())); + + if (selected_item_data != NULL) { + switch (selected_item_data->Section()) { + case TREESECTION_BITMAPS: + DoCopyBitmap(bb->GetSelection()); + break; + case TREESECTION_VERSION: + DoCopyChunk(selected_item_data->CollID(), selected_item_data->Version()); + break; + default: + break; + } + } +} + +// handle the Edit->Delete menu command, which is context-sensitive +void ShapesView::MenuEditDelete(wxCommandEvent &e) +{ + ShapesTreeItemData *selected_item_data = dynamic_cast(colltree->GetItemData(colltree->GetSelection())); + + if (selected_item_data != NULL) { + // what should we delete? + switch (selected_item_data->Section()) { + case TREESECTION_COLORTABLES: + DoDeleteColorTable(ctb->GetSelection()); + break; + case TREESECTION_BITMAPS: + DoDeleteBitmap(bb->GetSelection()); + break; + case TREESECTION_FRAMES: + DoDeleteFrame(fb->GetSelection()); + break; + case TREESECTION_SEQUENCES: + break; + } + } +} + +void ShapesView::MenuEditPaste(wxCommandEvent& e) +{ + ShapesTreeItemData* selected_item_data = dynamic_cast(colltree->GetItemData(colltree->GetSelection())); + + if (selected_item_data != NULL) { + switch (selected_item_data->Section()) { + case TREESECTION_BITMAPS: + DoPasteBitmap(bb->GetSelection()); + break; + case TREESECTION_VERSION: + DoPasteChunk(selected_item_data->CollID(), selected_item_data->Version()); + break; + default: + break; + } + } +} + +void ShapesView::MenuViewTransparency(wxCommandEvent &e) +{ + bool showTranspPixels = e.IsChecked(); + + wxBeginBusyCursor(); + bb->SetTranspPixelsDisplay(!showTranspPixels); + b_view->SetTranspPixelsDisplay(!showTranspPixels); + fb->SetTranspPixelsDisplay(!showTranspPixels); + f_view->SetTranspPixelsDisplay(!showTranspPixels); + s_fb->SetTranspPixelsDisplay(!showTranspPixels); + wxEndBusyCursor(); +} + +void ShapesView::MenuViewCenterOrigin(wxCommandEvent &e) +{ + f_view->SetCenterOrigin(e.IsChecked()); +} + +// color table menu handler +void ShapesView::MenuViewCT(wxCommandEvent &e) +{ + mViewColorTable = e.GetId() - VIEW_MENU_COLORTABLE_0; + + ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable( + mSelectedColl, mSelectedVers, mViewColorTable); + + wxBeginBusyCursor(); + bb->SetColorTable(ctp); + b_view->SetColorTable(ctp); + fb->SetColorTable(ctp); + f_view->SetColorTable(ctp); + s_fb->SetColorTable(ctp); + wxEndBusyCursor(); +} + +// thumbnail size menu handler +void ShapesView::MenuViewTNSize(wxCommandEvent &e) +{ + int size = -1; + + switch (e.GetId()) { + case VIEW_MENU_TNSIZE_SMALL: + size = 32; + break; + case VIEW_MENU_TNSIZE_MEDIUM: + size = 64; + break; + case VIEW_MENU_TNSIZE_LARGE: + size = 128; + break; + case VIEW_MENU_TNSIZE_AUTO: + size = -1; + break; + } + wxBeginBusyCursor(); + bb->SetThumbnailSize(size); + fb->SetThumbnailSize(size); + s_fb->SetThumbnailSize(size); + wxEndBusyCursor(); +} + +void ShapesView::MenuShapesAddColorTable(wxCommandEvent &e) +{ + wxFileDialog *dlg = new wxFileDialog(mFrame, wxT("Import a color table"), wxT(""), wxT(""), + wxT("Photoshop color table|*.act|Gimp palette|*.gpl"), wxOPEN); + + if (dlg->ShowModal() == wxID_OK) { + wxString filename = dlg->GetPath(); + std::ifstream ifs(filename.mb_str(), std::ios::binary); + + if (ifs.good()) { + ShapesColorTable *newct = new ShapesColorTable(ifs, filename.AfterLast('.')), + *firstct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, 0); + + ifs.close(); + if (newct->ColorCount() > 0) { + if (newct->GetColor(0)->Red() != 0 || newct->GetColor(0)->Green() != 0 || newct->GetColor(0)->Blue() != 255<<8) + wxMessageBox(wxT("The first color of the table being imported is not the usual Marathon chroma key color" + " (no red, no green, maximum blue). It should be corrected manually to avoid problems."), + wxT("Invalid chroma key color"), wxOK | wxICON_WARNING, mFrame); + if (firstct != NULL) { + // handle cases in which the new color table has more or less colors than existing ones + if (newct->ColorCount() > firstct->ColorCount()) { + // more colors, append dummy colors to existing tables + unsigned int numcolors = newct->ColorCount() - firstct->ColorCount(), + numcts = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers); + + for (unsigned int i = 0; i < numcts; i++) { + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, i); + + for (unsigned int j = 0; j < numcolors; j++) + ct->InsertColor(new ShapesColor(0, 0, 0, numcolors + j)); + } + } else if (newct->ColorCount() < firstct->ColorCount()) { + // less colors, append dummy colors to the new table + unsigned int numcolors = firstct->ColorCount() - newct->ColorCount(); + + for (unsigned int i = 0; i < numcolors; i++) + newct->InsertColor(new ShapesColor(0, 0, 0, newct->ColorCount() + i)); + } + } + ((ShapesDocument*)GetDocument())->InsertColorTable(newct, mSelectedColl, mSelectedVers); + ((ShapesDocument*)GetDocument())->Modify(true); + // update the GUI + ctb->AddColorTable(newct); + unsigned int colorTableCount = ((ShapesDocument*)GetDocument())->CollectionColorTableCount( + mSelectedColl, mSelectedVers); + wxMenu *colortables_submenu; + menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu); + for (unsigned int i = 0; i < colortables_submenu->GetMenuItemCount(); i++) { + menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < colorTableCount); + menubar->Check(VIEW_MENU_COLORTABLE_0 + mViewColorTable, i == (unsigned int)mViewColorTable); + } + } else { + wxString errormsg; + + errormsg << wxT("Sorry, could not load a color table from ") << filename << wxT(" because the file format is unknown or the file contains no colors."); + wxMessageBox(errormsg, wxT("Error loading color table"), wxOK | wxICON_ERROR, mFrame); + delete newct; + } + } else { + wxString errormsg; + + errormsg << wxT("Sorry, could not load a color table from ") << filename << wxT(" because the file is not readable."); + wxMessageBox(errormsg, wxT("Error loading color table"), wxOK | wxICON_ERROR, mFrame); + } + } + dlg->Destroy(); +} + +// prompt the user and save the selected color table, either in +// Gimp or PhotoShop format (depending on event id) +void ShapesView::MenuShapesSaveColorTable(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + int selection = ctb->GetSelection(); + + if (selection >= 0) { + bool ps = (e.GetId() == SHAPES_MENU_SAVECOLORTABLETOPS); + wxString prompt = wxString::Format(wxT("Save color table %d"), selection), + name, ctpath; + + if (ps) { + name = wxString::Format(wxT("ColorTable%d.act"), selection); + ctpath = wxFileSelector(prompt, wxT(""), name, wxT(""), + wxT("PhotoShop color table|*.act"), + wxSAVE | wxOVERWRITE_PROMPT); + } else { + name = wxString::Format(wxT("ColorTable%d.gpl"), selection); + ctpath = wxFileSelector(prompt, wxT(""), name, wxT(""), + wxT("Gimp color table|*.gpl"), + wxSAVE | wxOVERWRITE_PROMPT); + } + + if (!ctpath.empty()) { + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, selection); + int err = 0; + + if (ps) + err = ct->SaveToPhotoshop(ctpath); + else + err = ct->SaveToGimp(ctpath); + + if (err != 0) { + wxString errormsg; + + errormsg << wxT("Sorry, could not save color table to ") << ctpath << wxT("."); + wxMessageBox(errormsg, wxT("Error saving color table"), wxOK | wxICON_ERROR, mFrame); + } + } + } + } +} + +void ShapesView::MenuShapesAddBitmap(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + wxFileDialog *dlg = new wxFileDialog(mFrame, wxT("Choose a bitmap to add"), wxT(""), wxT(""), + wxT("Common bitmap files (BMP, JPEG, PNG, GIF, TIFF)|*.bmp;*.jpg;*.jpeg;*.tif;*.tiff;*.png;*.gif"), + wxOPEN); + + if (dlg->ShowModal() == wxID_OK) { + wxString filename = dlg->GetPath(); + wxImage img; + + if (img.LoadFile(filename)) { + wxBeginBusyCursor(); + // we have the wxImage now. Encode it to a new bitmap + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable); + ShapesBitmap *newbmp = new ShapesBitmap(img, ct); + + // automagically initialize bitmap flags + if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _object_collection || + ((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _scenery_collection) { + // compress weapons, monsters and scenery + newbmp->SetBytesPerRow(-1); + } else if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _interface_collection) { + // interface elements are row-ordered (not so important with A1 actually) + newbmp->SetColumnOrdered(false); + } + ((ShapesDocument*)GetDocument())->InsertBitmap(newbmp, mSelectedColl, mSelectedVers); + + // update the GUI + unsigned int bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); + ShapesBitmap *pnewbitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, bitmap_count-1); + wxString count_string = wxString::Format(wxT("%u bitmap"), bitmap_count); + + bb->AddBitmap(pnewbitmap); + fb->AddBitmap(pnewbitmap); + if (bitmap_count != 1) + count_string << wxT("s"); + b_count_label->SetLabel(count_string); + + wxEndBusyCursor(); + ((ShapesDocument*)GetDocument())->Modify(true); + } else { + wxString errormsg; + + errormsg << wxT("Sorry, could not load bitmap from ") << filename << wxT("."); + wxMessageBox(errormsg, wxT("Error adding bitmap"), wxOK | wxICON_ERROR, mFrame); + } + } + dlg->Destroy(); + } +} + +// export selected bitmap to a BMP file +void ShapesView::MenuShapesExportBitmap(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + int selection = bb->GetSelection(); + + if (selection >= 0) { + wxString prompt = wxString::Format(wxT("Export bitmap %d"), selection), + name = wxString::Format(wxT("bitmap%.3d.bmp"), selection), + path = wxFileSelector(prompt, wxT(""), name, wxT(""), wxT("BMP image|*.bmp"), wxSAVE | wxOVERWRITE_PROMPT); + + if (!path.empty()) { + ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection); + ShapesColorTable *colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable); + + bitmap->SaveToBMP(path, colorTable); + } + } + } +} + +void ShapesView::MenuShapesExportBitmapMask(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + int selection = bb->GetSelection(); + + if (selection >= 0) { + wxString prompt = wxString::Format(wxT("Export bitmap %d mask"), selection), + name = wxString::Format(wxT("bitmap%.3dmask.bmp"), selection), + path = wxFileSelector(prompt, wxT(""), name, wxT(""), wxT("BMP image|*.bmp"), wxSAVE | wxOVERWRITE_PROMPT); + + if (!path.empty()) { + ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection); + + bitmap->SaveMaskToBMP(path); + } + } + } +} + +// export all bitmaps of the selected collection to separate BMP files in a folder +void ShapesView::MenuShapesExportBitmaps(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + wxString dirPath = wxDirSelector(wxT("Select destination folder")); + + if (!dirPath.empty()) { + ShapesColorTable *colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable); + + wxBeginBusyCursor(); + for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++) { + wxString name = wxString::Format(wxT("bitmap%.3d.bmp"), i); + ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i); + + bitmap->SaveToBMP(dirPath + wxT("/") + name, colorTable); + } + wxEndBusyCursor(); + } + } +} + +void ShapesView::MenuShapesExportBitmapMasks(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + wxString dirPath = wxDirSelector(wxT("Select destination folder")); + + if (!dirPath.empty()) { + wxBeginBusyCursor(); + for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++) { + wxString name = wxString::Format(wxT("bitmap%.3dmask.bmp"), i); + ShapesBitmap *bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i); + + bitmap->SaveMaskToBMP(dirPath + wxT("/") + name); + } + wxEndBusyCursor(); + } + } +} + +void ShapesView::MenuShapesNewFrame(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + // append an empty frame + ShapesFrame *newframe = new ShapesFrame(); + + newframe->SetScaleFactor(((ShapesDocument*)GetDocument())->CollectionScaleFactor(mSelectedColl, mSelectedVers)); + if (((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers) > ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)) { + newframe->SetBitmapIndex(((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)); + } + ((ShapesDocument*)GetDocument())->InsertFrame(newframe, mSelectedColl, mSelectedVers); + fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers)-1)); + // update frame count label + unsigned int frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers); + wxString count_string = wxString::Format(wxT("%u frame"), frame_count); + + if (frame_count != 1) + count_string << wxT("s"); + f_count_label->SetLabel(count_string); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +void ShapesView::MenuShapesNewSequence(wxCommandEvent &e) +{ + if (((ShapesDocument*)GetDocument()) != NULL && mSelectedColl != -1 && mSelectedVers != -1) { + // append an empty sequence + ShapesSequence *newseq = new ShapesSequence(); + + ((ShapesDocument*)GetDocument())->InsertSequence(newseq, mSelectedColl, mSelectedVers); + + // insert the new entry in the main tree + wxTreeItemId thenode = GetSequencesTreeItem(mSelectedColl, mSelectedVers); + int seq_id = ((ShapesDocument*)GetDocument())->CollectionSequenceCount(mSelectedColl, mSelectedVers) - 1; + ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, seq_id); + ShapesTreeItemData *itemdata = new ShapesTreeItemData(mSelectedColl, mSelectedVers, TREESECTION_SEQUENCES, seq_id); + wxString label; + + label << seq_id; + if (seq->Name().Length() > 0) + label << wxT(" - ") << seq->Name(); + colltree->AppendItem(thenode, label, -1, -1, itemdata); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +void ShapesView::MenuShapesGeneratePatch(wxCommandEvent&) +{ + ShapesDocument* document = (ShapesDocument*) GetDocument(); + + if (document == NULL) { + return; + } + + // prompt the user for a base for the patch + wxFileDialog dlg(mFrame, wxT("Choose a base file (e.g. standard Infinity shapes)"), wxT(""), wxT(""), wxT("Shapes files (*.shpA)|*.shpA|All files (*.*)|*.*"), wxOPEN); + if (dlg.ShowModal() != wxID_OK) { + return; + } + + ShapesDocument base; + if (!base.DoOpenDocument(dlg.GetPath())) { + return; + } + + // prompt the user for a patch location + wxString path = wxFileSelector(wxT("Export patch file"), wxT(""), wxT("Shapes Patch.ShPa"), wxT(""), wxT("Shapes patch|*.ShPa"), wxSAVE | wxOVERWRITE_PROMPT); + + if (path.empty()) { + return; + } + +#if wxUSE_STD_IOSTREAM + wxSTD ofstream stream(path.mb_str(), wxSTD ios_base::out | wxSTD ios_base::binary | wxSTD ios_base::trunc); +#else + wxFileOutputStream stream(path); + if (!stream.IsOk()) { + return; + } +#endif + document->SavePatch(stream, base); +} + +void ShapesView::MenuShapesImportPatch(wxCommandEvent&) +{ + ShapesDocument* document = (ShapesDocument*) GetDocument(); + + if (document == NULL) { + return; + } + + // prompt the user for a patch + wxString path = wxFileSelector(wxT("Choose a patch file"), wxT(""), wxT(""), wxT(""), wxT("Patch files (*.ShPa)|*.ShPa|All files (*.*)|*.*"), wxOPEN); + + if (path.empty()) { + return; + } + +#if wxUSE_STD_IOSTREAM + wxSTD ifstream stream(path.mb_str(), wxSTD ios_base::in | wxSTD ios_base::binary); +#else + wxFileInputStream stream(path); + if (!stream.IsOk()) { + return; + } +#endif + + if (!document->LoadPatch(stream)) { + wxMessageBox(wxT("Error loading shapes patch; the patch may be partially applied!"), wxT("Error loading shapes patch"), wxOK | wxICON_ERROR, mFrame); + } + + colltree->Unselect(); + colltree->CollapseAll(); + mSelectedColl = -1; + mSelectedVers = -1; + mSelectedSequence = -1; + mViewColorTable = -1; + mainbox->Show(dummy_sizer, true); + mainbox->Show(coll_sizer, false); + mainbox->Show(chunk_sizer, false); + mainbox->Show(b_outer_sizer, false); + mainbox->Show(ct_outer_sizer, false); + mainbox->Show(f_outer_sizer, false); + mainbox->Show(s_outer_sizer, false); +} + +// user selected a tree entry +void ShapesView::OnTreeSelect(wxTreeEvent &e) +{ + ShapesTreeItemData *data = dynamic_cast(colltree->GetItemData(e.GetItem())); + + if (data) { + int new_coll = data->CollID(), + new_vers = data->Version(), + new_section = data->Section(); + + if (new_coll != mSelectedColl || new_vers != mSelectedVers) { + // user has moved to another collection/version + + // first clear the user interface + wxMenu *colortables_submenu; + menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu); + unsigned int ctmenucount = colortables_submenu->GetMenuItemCount(); + + mViewColorTable = -1; + ctb->Clear(); + ct_view->SetColorTable(NULL); + bb->Freeze(); + bb->Clear(); + b_view->SetBitmap(NULL); + fb->Freeze(); + fb->Clear(); + f_view->SetFrame(NULL); + f_view->SetBitmap(NULL); + s_fb->Clear(); + for (unsigned int i = 0; i < ctmenucount; i++) + menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false); + menubar->Enable(SHAPES_MENU_EXPORTBITMAP, false); + menubar->Enable(SHAPES_MENU_EXPORTMASK, false); + + // set collection info panel + coll_static_box->SetLabel(wxString::Format(wxT("Global info for collection %d"), new_coll)); + + wxString collinfo_s; + collinfo_s << wxT("Status: ") << ((ShapesDocument*)GetDocument())->CollectionStatus(new_coll) << wxT("\n"); + collinfo_s << wxT("Flags: ") << ((ShapesDocument*)GetDocument())->CollectionFlags(new_coll) << wxT("\n\n"); + if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, COLL_VERSION_8BIT)) + collinfo_s << wxT("8-bit color version present\n"); + else + collinfo_s << wxT("No 8-bit color version\n"); + if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, COLL_VERSION_TRUECOLOR)) + collinfo_s << wxT("True color version present"); + else + collinfo_s << wxT("No true color version"); + coll_text->SetLabel(collinfo_s); + + if (new_coll != -1 && new_vers != -1) { + if (new_vers == COLL_VERSION_TRUECOLOR) + chunk_static_box->SetLabel(wxT("Shapes for true color and OpenGL display")); + else + chunk_static_box->SetLabel(wxT("Shapes for 8-bit color display")); + + if (((ShapesDocument*)GetDocument())->CollectionDefined(new_coll, new_vers)) { + // a defined collection has been selected + unsigned int ct_count = ((ShapesDocument*)GetDocument())->CollectionColorTableCount(new_coll, new_vers), + bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(new_coll, new_vers), + frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(new_coll, new_vers); + wxString count_string; + + wxBeginBusyCursor(); + menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, true); + menubar->Enable(SHAPES_MENU_ADDBITMAP, true); + menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, true); + menubar->Enable(SHAPES_MENU_EXPORTMASKS, true); + menubar->Enable(SHAPES_MENU_ADDFRAME, true); + menubar->Enable(SHAPES_MENU_ADDSEQUENCE, true); + + // chunk info panel + chunk_version_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionVersion(new_coll, new_vers))); + chunk_type_menu->SetSelection(((ShapesDocument*)GetDocument())->CollectionType(new_coll, new_vers)); + chunk_flags_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionFlags(new_coll, new_vers))); + chunk_sf_field->ChangeValue(INT_TO_WXSTRING(((ShapesDocument*)GetDocument())->CollectionScaleFactor(new_coll, new_vers))); + + // color tables + mViewColorTable = 0; + for (unsigned int i = 0; i < ct_count; i++) + ctb->AddColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, i)); + for (unsigned int i = 0; i < ctmenucount; i++) + menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < ct_count); + if (ct_count > 0) + menubar->Check(VIEW_MENU_COLORTABLE_0, true); + count_string << ct_count << wxT(" color table"); + if (ct_count != 1) + count_string << wxT("s"); + if (ct_count > 0) + count_string << wxT(", ") << ((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)->ColorCount() << wxT(" colors per table"); + ct_count_label->SetLabel(count_string); + + // bitmaps + bb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)); + b_view->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)); + for (unsigned int i = 0; i < bitmap_count; i++) + bb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(new_coll, new_vers, i)); + count_string.Clear(); + count_string << bitmap_count << wxT(" bitmap"); + if (bitmap_count != 1) + count_string << wxT("s"); + b_count_label->SetLabel(count_string); + + // frames + fb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)); + f_view->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, 0)); + for (unsigned int i = 0; i < bitmap_count; i++) + fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(new_coll, new_vers, i)); + for (unsigned int i = 0; i < frame_count; i++) + fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(new_coll, new_vers, i)); + count_string.Clear(); + count_string << frame_count << wxT(" frame"); + if (frame_count != 1) + count_string << wxT("s"); + f_count_label->SetLabel(count_string); + + wxEndBusyCursor(); + } else { + menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, false); + menubar->Enable(SHAPES_MENU_ADDBITMAP, false); + menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, false); + menubar->Enable(SHAPES_MENU_EXPORTMASKS, false); + menubar->Enable(SHAPES_MENU_ADDFRAME, false); + menubar->Enable(SHAPES_MENU_ADDSEQUENCE, false); + } + } else { + menubar->Enable(SHAPES_MENU_ADDCOLORTABLE, false); + menubar->Enable(SHAPES_MENU_ADDBITMAP, false); + menubar->Enable(SHAPES_MENU_EXPORTBITMAPS, false); + menubar->Enable(SHAPES_MENU_EXPORTMASKS, false); + menubar->Enable(SHAPES_MENU_ADDFRAME, false); + menubar->Enable(SHAPES_MENU_ADDSEQUENCE, false); + } + mSelectedColl = new_coll; + mSelectedVers = new_vers; + bb->Thaw(); + fb->Thaw(); + } + + // handle sequence selection + mSelectedSequence = data->Sequence(); + if (mSelectedSequence > -1) { + ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(new_coll, new_vers, mSelectedSequence); + + // setup sequence panel controls + s_outer_static_box->SetLabel(wxString::Format(wxT("Sequence %d of %u"), + mSelectedSequence, ((ShapesDocument*)GetDocument())->CollectionSequenceCount(new_coll, new_vers))); + s_name_field->ChangeValue(seq->Name()); + switch (seq->NumberOfViews()) { + case UNANIMATED: s_type_menu->SetSelection(0); break; + case ANIMATED_1: s_type_menu->SetSelection(1); break; + case ANIMATED_3TO4: s_type_menu->SetSelection(2); break; + case ANIMATED_4: s_type_menu->SetSelection(2); break; + case ANIMATED_3TO5: s_type_menu->SetSelection(3); break; + case ANIMATED_5: s_type_menu->SetSelection(3); break; + case ANIMATED_2TO8: s_type_menu->SetSelection(4); break; + case ANIMATED_5TO8: s_type_menu->SetSelection(4); break; + case ANIMATED_8: s_type_menu->SetSelection(4); break; + default: + s_type_menu->SetSelection(0); + wxMessageBox(wxString::Format(wxT("This sequence has an unknown type %d, and ShapeFusion can not handle it. Something strange may happen now!"), seq->NumberOfViews()), + wxT("Warning"), wxOK | wxICON_ERROR, mFrame); + break; + } + s_fpv_field->ChangeValue(INT_TO_WXSTRING(seq->FramesPerView())); + s_tpf_field->ChangeValue(INT_TO_WXSTRING(seq->TicksPerFrame())); + s_lf_field->ChangeValue(INT_TO_WXSTRING(seq->LoopFrame())); + s_kf_field->ChangeValue(INT_TO_WXSTRING(seq->KeyFrame())); + s_xfermode_menu->SetSelection(seq->TransferMode()); + s_xferperiod_field->ChangeValue(INT_TO_WXSTRING(seq->TransferModePeriod())); + s_ffs_field->ChangeValue(INT_TO_WXSTRING(seq->FirstFrameSound())); + s_kfs_field->ChangeValue(INT_TO_WXSTRING(seq->KeyFrameSound())); + s_lfs_field->ChangeValue(INT_TO_WXSTRING(seq->LastFrameSound())); + // setup the sequence view + wxBeginBusyCursor(); + s_fb->Freeze(); + s_fb->Clear(); + s_fb->SetColorTable(((ShapesDocument*)GetDocument())->GetColorTable(new_coll, new_vers, mViewColorTable)); + for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); i++) + s_fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i)); + for (unsigned int i = 0; i < ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers); i++) + s_fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, i)); + s_fb->SetSeqParameters(seq->NumberOfViews(), seq->FramesPerView(), &seq->mFrameIndexes, this); + s_fb->Thaw(); + wxEndBusyCursor(); + } + + menubar->SetLabel(EDIT_MENU_DELETE, _("Delete")); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_PASTE, false); + + // handle section selection: show/hide editing panels + mainbox->Show(dummy_sizer, false); + mainbox->Show(coll_sizer, false); + mainbox->Show(chunk_sizer, false); + mainbox->Show(b_outer_sizer, false); + mainbox->Show(ct_outer_sizer, false); + mainbox->Show(f_outer_sizer, false); + mainbox->Show(s_outer_sizer, false); + switch (new_section) { + case TREESECTION_COLLECTION: + mainbox->Show(coll_sizer, true); + break; + case TREESECTION_VERSION: + mainbox->Show(chunk_sizer, true); + chunk_inner_box->Show(chunk_undef_label, !((ShapesDocument*)GetDocument())->CollectionDefined(mSelectedColl, mSelectedVers)); + chunk_inner_box->Show(chunk_grid, ((ShapesDocument*)GetDocument())->CollectionDefined(mSelectedColl, mSelectedVers)); + + menubar->Enable(EDIT_MENU_COPY, true); + menubar->Enable(EDIT_MENU_PASTE, true); + break; + case TREESECTION_BITMAPS: + mainbox->Show(b_outer_sizer, true); + b_outer_sizer->Show(b_edit_box, bb->GetSelection() != -1); + b_outer_sizer->Show(b_count_label, bb->GetSelection() == -1); + break; + case TREESECTION_COLORTABLES: + mainbox->Show(ct_outer_sizer, true); + ct_outer_sizer->Show(ct_edit_box, ctb->GetSelection() != -1); + ct_outer_sizer->Show(ct_count_label, ctb->GetSelection() == -1); + break; + case TREESECTION_FRAMES: + mainbox->Show(f_outer_sizer, true); + f_outer_sizer->Show(f_edit_box, fb->GetSelection() != -1); + f_outer_sizer->Show(f_count_label, fb->GetSelection() == -1); + break; + case TREESECTION_SEQUENCES: + menubar->SetLabel(EDIT_MENU_DELETE, _("Delete sequence")); + if (mSelectedSequence > -1) { + mainbox->Show(s_outer_sizer, true); + menubar->Enable(EDIT_MENU_DELETE, true); + } else { + mainbox->Show(dummy_sizer, true); + } + break; + } + mainbox->Layout(); + } +} + +// selection event in the bitmap browser +void ShapesView::OnBitmapSelect(wxCommandEvent &e) +{ + int selection = e.GetInt(); + + if (selection < 0) { + // deselection + b_view->SetBitmap(NULL); + b_outer_sizer->Show(b_count_label, true); + b_outer_sizer->Show(b_edit_box, false); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete")); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_PASTE, false); + menubar->Enable(SHAPES_MENU_EXPORTBITMAP, false); + menubar->Enable(SHAPES_MENU_EXPORTMASK, false); + } else { + ShapesBitmap *sel_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, selection); + + // set labels + wxString info_label = wxString::Format(wxT("%dx%d pixels, "), sel_bitmap->Width(), sel_bitmap->Height()); + + if (sel_bitmap->BytesPerRow() > 0) + info_label << wxT("plain encoding"); + else + info_label << wxT("RLE"); + b_info_label->SetLabel(info_label); + b_edit_static_box->SetLabel(wxString::Format(wxT("Bitmap %d of %d"), + selection, ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers))); + // set flag check boxes + b_order_checkbox->SetValue(sel_bitmap->IsColumnOrdered()); + b_transparency_checkbox->SetValue(sel_bitmap->IsTransparent()); + // set bitmap view + b_view->SetBitmap(sel_bitmap); + b_outer_sizer->Show(b_count_label, false); + b_outer_sizer->Show(b_edit_box, true); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete bitmap")); + menubar->Enable(EDIT_MENU_COPY, true); + menubar->Enable(EDIT_MENU_DELETE, true); + menubar->Enable(EDIT_MENU_PASTE, true); + menubar->Enable(SHAPES_MENU_EXPORTBITMAP, true); + menubar->Enable(SHAPES_MENU_EXPORTMASK, true); + } + b_outer_sizer->Layout(); +} + +// handle a delete event from the bitmap browser +void ShapesView::BitmapDelete(wxCommandEvent &e) +{ + DoDeleteBitmap(e.GetSelection()); +} + +void ShapesView::DoCopyBitmap(int which) +{ + ShapesBitmap* bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, which); + ShapesColorTable* colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable); + + bitmap->ClipboardCopy(colorTable); +} + +void ShapesView::DoDeleteColorTable(int which) +{ + if (which >= 0) { + // first do like a color table deselection + ct_view->SetColorTable(NULL); + ct_outer_sizer->Show(ct_count_label, true); + ct_outer_sizer->Show(ct_edit_box, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete")); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_PASTE, false); + ctb->Freeze(); + ctb->Clear(); + // delete + ((ShapesDocument*)GetDocument())->DeleteColorTable(mSelectedColl, mSelectedVers, which); + // update the view color table + if (mViewColorTable == which) { + mViewColorTable = 0; + ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable( + mSelectedColl, mSelectedVers, mViewColorTable); + + wxBeginBusyCursor(); + bb->SetColorTable(ctp); + b_view->SetColorTable(ctp); + fb->SetColorTable(ctp); + f_view->SetColorTable(ctp); + s_fb->SetColorTable(ctp); + wxEndBusyCursor(); + } else if (mViewColorTable > which) { + mViewColorTable = mViewColorTable - 1; + ShapesColorTable *ctp = ((ShapesDocument*)GetDocument())->GetColorTable( + mSelectedColl, mSelectedVers, mViewColorTable); + + wxBeginBusyCursor(); + bb->SetColorTable(ctp); + b_view->SetColorTable(ctp); + fb->SetColorTable(ctp); + f_view->SetColorTable(ctp); + s_fb->SetColorTable(ctp); + wxEndBusyCursor(); + } + // reset other gui elements + unsigned int colorTableCount = ((ShapesDocument*)GetDocument())->CollectionColorTableCount( + mSelectedColl, mSelectedVers); + + for (unsigned int i = 0; i < colorTableCount; i++) + ctb->AddColorTable(((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, i)); + ctb->Thaw(); + wxMenu *colortables_submenu; + menubar->FindItem(VIEW_MENU_COLORTABLE_0, &colortables_submenu); + for (unsigned int i = 0; i < colortables_submenu->GetMenuItemCount(); i++) { + menubar->Enable(VIEW_MENU_COLORTABLE_0 + i, i < colorTableCount); + menubar->Check(VIEW_MENU_COLORTABLE_0 + mViewColorTable, i == (unsigned int)mViewColorTable); + } + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +void ShapesView::DoDeleteBitmap(int which) +{ + if (which >= 0) { + // fist make sure no GUI element references that bitmap anymore + bb->Freeze(); + bb->Clear(); // FIXME just remove that bitmap + fb->Freeze(); + fb->ClearBitmaps(); // FIXME just remove that bitmap + b_outer_sizer->Show(b_count_label, true); + b_outer_sizer->Show(b_edit_box, false); + b_view->SetBitmap(NULL); + // delete + ((ShapesDocument*)GetDocument())->DeleteBitmap(mSelectedColl, mSelectedVers, which); + // update the GUI + unsigned int bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); + + for (unsigned int i = 0; i < bitmap_count; i++) { + ShapesBitmap *bmp = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i); + + bb->AddBitmap(bmp); + fb->AddBitmap(bmp); + } + bb->Thaw(); + fb->RebuildThumbnails(); // FIXME just rebuild dirty frames + fb->Thaw(); + + wxString count_string; + + count_string << bitmap_count << wxT(" bitmap"); + if (bitmap_count != 1) + count_string << wxT("s"); + b_count_label->SetLabel(count_string); + mFrame->Layout(); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +void ShapesView::DoDeleteFrame(int which) +{ + if (which >= 0) { + // first make sure no GUI element references that frame anymore + fb->Freeze(); + fb->Clear(); // FIXME just remove THAT frame + f_outer_sizer->Show(f_count_label, true); + f_outer_sizer->Show(f_edit_box, false); + f_view->SetFrame(NULL); + // delete + ((ShapesDocument*)GetDocument())->DeleteFrame(mSelectedColl, mSelectedVers, which); + + unsigned int frame_count = ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers), + bitmap_count = ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers); + + for (unsigned int i = 0; i < bitmap_count; i++) + fb->AddBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, i)); + for (unsigned int i = 0; i < frame_count; i++) + fb->AddFrame(((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, i)); + fb->Thaw(); + + wxString count_string; + + count_string << frame_count << wxT(" frame"); + if (frame_count != 1) + count_string << wxT("s"); + f_count_label->SetLabel(count_string); + mFrame->Layout(); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +void ShapesView::DoPasteBitmap(int which) +{ + ShapesBitmap* bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, which); + ShapesColorTable* colorTable = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, mViewColorTable); + + wxBeginBusyCursor(); + bitmap->ClipboardPaste(colorTable); + + // automagically initialize bitmap flags + if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _object_collection || + ((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _scenery_collection) { + // compress weapons, monsters and scenery + bitmap->SetBytesPerRow(-1); + } else if (((ShapesDocument*)GetDocument())->CollectionType(mSelectedColl, mSelectedVers) == _interface_collection) { + // interface elements are row-ordered (not so important with A1 actually) + bitmap->SetColumnOrdered(false); + } + + ((ShapesDocument*)GetDocument())->Modify(true); + bb->RebuildThumbnail(bb->GetSelection()); + bb->Refresh(); + b_view->SetBitmap(bitmap); + fb->Freeze(); + fb->RebuildThumbnails(); + fb->Thaw(); + wxEndBusyCursor(); +} + +void ShapesView::DoCopyChunk(unsigned int coll, unsigned int chunk) +{ + ShapesChunk* c = ((ShapesDocument*)GetDocument())->GetChunk(coll, chunk); + if (c) { + c->ClipboardCopy(); + } +} + +void ShapesView::DoPasteChunk(unsigned int coll, unsigned int chunk) +{ + ShapesChunk* c = ((ShapesDocument*)GetDocument())->GetChunk(coll, chunk); + if (c) { + c->ClipboardPaste(); + ((ShapesDocument*)GetDocument())->Modify(true); + mSelectedColl = -1; + mSelectedVers = -1; + mSelectedSequence = -1; + + colltree->DeleteAllItems(); + OnUpdate(0, 0); + } +} + +void ShapesView::ToggleBitmapCheckboxes(wxCommandEvent &e) +{ + ShapesBitmap *sel_bitmap = b_view->GetBitmap(); + + if (sel_bitmap != NULL) { + switch (e.GetId()) { + case CB_COLUMN_ORDER: + sel_bitmap->SetColumnOrdered(e.IsChecked()); + ((ShapesDocument*)GetDocument())->Modify(true); + break; + case CB_ENABLE_TRANSPARENCY: + sel_bitmap->SetTransparent(e.IsChecked()); + bb->RebuildThumbnail(bb->GetSelection()); + bb->Refresh(); + b_view->SetBitmap(sel_bitmap); + // FIXME also update the FrameBrowser and all that + ((ShapesDocument*)GetDocument())->Modify(true); + break; + } + } +} + +// callback for selections in the color table browser +void ShapesView::OnCTSelect(wxCommandEvent &e) +{ + int selection = e.GetInt(); + + if (selection < 0) { + // deselection + ct_view->SetColorTable(NULL); + ct_outer_sizer->Show(ct_count_label, true); + ct_outer_sizer->Show(ct_edit_box, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, false); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, false); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete")); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_PASTE, false); + } else { + // selection + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, mSelectedVers, selection); + + ct_view->SetColorTable(ct); + ct_edit_static_box->SetLabel(wxString::Format(wxT("Color table %d of %d, %d colors per table"), selection, + ((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers), + ct->ColorCount())); + ct_outer_sizer->Show(ct_count_label, false); + ct_outer_sizer->Show(ct_edit_box, true); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLE, true); + menubar->Enable(SHAPES_MENU_SAVECOLORTABLETOPS, true); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete color table")); + // FIXME make sure there is at least one color table for now + if (((ShapesDocument*)GetDocument())->CollectionColorTableCount(mSelectedColl, mSelectedVers) > 1) + menubar->Enable(EDIT_MENU_DELETE, true); + else + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_PASTE, false); + } + ct_self_lumin_checkbox->Disable(); + ct_gradient_button->Disable(); + ct_outer_sizer->Layout(); +} + +// callback for color selections in the color table editor +void ShapesView::CTColorSelect(wxCommandEvent &e) +{ + ct_self_lumin_checkbox->Disable(); + ct_gradient_button->Disable(); + switch (e.GetInt()) { + default: // more colors selected + ct_gradient_button->Enable(); + case 1: // just one color selected + ct_self_lumin_checkbox->Enable(); + // set the checkbox value + { + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, + mSelectedVers, ctb->GetSelection()); + vector selection = ct_view->GetSelection(); + bool someAreOn = false, + someAreOff = false; + + for (unsigned int i = 0; i < selection.size(); i++) { + if (selection[i]) { + if (ct->GetColor(i)->Luminescent()) + someAreOn = true; + else + someAreOff = true; + } + } + if (someAreOn && someAreOff) + ct_self_lumin_checkbox->Set3StateValue(wxCHK_UNDETERMINED); + else if (someAreOn && !someAreOff) + ct_self_lumin_checkbox->Set3StateValue(wxCHK_CHECKED); + else + ct_self_lumin_checkbox->Set3StateValue(wxCHK_UNCHECKED); + } + case 0: // no colors selected + break; + } +} + +// callback for color alteration in the color table editor +void ShapesView::CTColorChanged(wxCommandEvent &e) +{ + ((ShapesDocument*)GetDocument())->Modify(true); + ctb->Refresh(); + // refresh thumbnails if needed + if (ctb->GetSelection() == mViewColorTable) { + bb->Freeze(); + bb->RebuildThumbnails(); + bb->Thaw(); + fb->Freeze(); + fb->RebuildThumbnails(); + fb->Thaw(); + } +} + +// callback for the "self luminescent color" checkbox +void ShapesView::ToggleSelfLuminCheckbox(wxCommandEvent &e) +{ + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, + mSelectedVers, ctb->GetSelection()); + vector selection = ct_view->GetSelection(); + + for (unsigned int i = 0; i < selection.size(); i++) { + if (selection[i]) + ct->GetColor(i)->SetLuminescent(e.IsChecked()); + } + ((ShapesDocument*)GetDocument())->Modify(true); + ctb->Refresh(); + ct_view->Refresh(); + // TODO invalidate thumbnails if needed +} + +// callback for the "make gradient" button in the color table editor +void ShapesView::MakeCTGradient(wxCommandEvent &e) +{ + vector selection = ct_view->GetSelection(); + int firstIndex = -1, lastIndex = -1; + + // find first and last selected items + for (unsigned int i = 0; i < selection.size(); i++) { + if (selection[i]) { + if (firstIndex == -1) + firstIndex = i; + lastIndex = i; + } + } + if (firstIndex > -1 && firstIndex < lastIndex) { + // linearly interpolate colors in between + ShapesColorTable *ct = ((ShapesDocument*)GetDocument())->GetColorTable(mSelectedColl, + mSelectedVers, ctb->GetSelection()); + int r1 = ct->GetColor(firstIndex)->Red(), + g1 = ct->GetColor(firstIndex)->Green(), + b1 = ct->GetColor(firstIndex)->Blue(), + r2 = ct->GetColor(lastIndex)->Red(), + g2 = ct->GetColor(lastIndex)->Green(), + b2 = ct->GetColor(lastIndex)->Blue(), + delta = lastIndex - firstIndex; + + for (int k = firstIndex+1; k < lastIndex; k++) { + ShapesColor *color = ct->GetColor(k); + + color->SetRed(r1 + (r2-r1)*(k-firstIndex)/delta); + color->SetGreen(g1 + (g2-g1)*(k-firstIndex)/delta); + color->SetBlue(b1 + (b2-b1)*(k-firstIndex)/delta); + } + } + ((ShapesDocument*)GetDocument())->Modify(true); + ctb->Refresh(); + ct_view->Refresh(); + // refresh thumbnails if needed + if (ctb->GetSelection() == mViewColorTable) { + bb->Freeze(); + bb->RebuildThumbnails(); + bb->Thaw(); + fb->Freeze(); + fb->RebuildThumbnails(); + fb->Thaw(); + } +} + +// callback for selections in the frame browser +void ShapesView::OnFrameSelect(wxCommandEvent &e) +{ + int selection = e.GetInt(); + + if (selection < 0) { + f_view->SetFrame(NULL); + f_view->SetBitmap(NULL); + f_outer_sizer->Show(f_count_label, true); + f_outer_sizer->Show(f_edit_box, false); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete")); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_DELETE, false); + menubar->Enable(EDIT_MENU_PASTE, false); + } else { + ShapesFrame *sel_frame = ((ShapesDocument*)GetDocument())->GetFrame(mSelectedColl, mSelectedVers, selection); + ShapesBitmap *assoc_bitmap = NULL; + + // set labels + f_edit_static_box->SetLabel(wxString::Format(wxT("Frame %d of %u"), + selection, ((ShapesDocument*)GetDocument())->CollectionFrameCount(mSelectedColl, mSelectedVers))); + // set frame view + f_view->SetFrame(sel_frame); + if (sel_frame->BitmapIndex() >= 0) + assoc_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, sel_frame->BitmapIndex()); + f_view->SetBitmap(assoc_bitmap); + // set controls + f_bitmap_id->SetRange(-1, ((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers) - 1); + f_bitmap_id->SetValue(sel_frame->BitmapIndex()); + f_xmirror_checkbox->SetValue(sel_frame->IsXmirrored()); + f_ymirror_checkbox->SetValue(sel_frame->IsYmirrored()); + f_keypoint_checkbox->SetValue(sel_frame->IsKeypointObscured()); + f_origin_x_field->ChangeValue(INT_TO_WXSTRING(sel_frame->OriginX())); + f_origin_y_field->ChangeValue(INT_TO_WXSTRING(sel_frame->OriginY())); + f_key_x_field->ChangeValue(INT_TO_WXSTRING(sel_frame->KeyX())); + f_key_y_field->ChangeValue(INT_TO_WXSTRING(sel_frame->KeyY())); + f_scalefactor_field->ChangeValue(INT_TO_WXSTRING(sel_frame->ScaleFactor())); + f_mli_field->ChangeValue(INT_TO_WXSTRING((int)roundf(sel_frame->MinimumLightIntensity() * 100.0))); + f_outer_sizer->Show(f_count_label, false); + f_outer_sizer->Show(f_edit_box, true); + menubar->SetLabel(EDIT_MENU_DELETE, wxT("Delete frame")); + menubar->Enable(EDIT_MENU_DELETE, true); + menubar->Enable(EDIT_MENU_COPY, false); + menubar->Enable(EDIT_MENU_PASTE, false); + } + f_outer_sizer->Layout(); +} + +// handle a delete event from the frame browser +void ShapesView::FrameDelete(wxCommandEvent &e) +{ + DoDeleteFrame(e.GetSelection()); +} + +// handle an event from the FrameView: update the values +// in the fields and mark the document as modified +void ShapesView::OnFramePointDrag(wxCommandEvent &e) +{ + ShapesFrame *frame = f_view->GetFrame(); + + if (frame != NULL) { + f_origin_x_field->ChangeValue(INT_TO_WXSTRING(frame->OriginX())); + f_origin_y_field->ChangeValue(INT_TO_WXSTRING(frame->OriginY())); + f_key_x_field->ChangeValue(INT_TO_WXSTRING(frame->KeyX())); + f_key_y_field->ChangeValue(INT_TO_WXSTRING(frame->KeyY())); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +// bitmap index change in the frame panel +void ShapesView::BitmapIndexSpin(wxSpinEvent &e) +{ + int newid = e.GetPosition(); + ShapesFrame *sel_frame = f_view->GetFrame(); + + if (sel_frame != NULL) { + sel_frame->SetBitmapIndex(newid); + f_view->SetBitmap(((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, newid)); + f_view->SetFrame(sel_frame); + fb->RebuildThumbnail(fb->GetSelection()); + fb->Refresh(); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +// checkbox toggle in the frame panel +void ShapesView::ToggleFrameCheckboxes(wxCommandEvent &e) +{ + ShapesFrame *sel_frame = f_view->GetFrame(); + + if (sel_frame != NULL) { + switch (e.GetId()) { + case CB_XMIRROR: sel_frame->SetXmirrored(e.IsChecked()); break; + case CB_YMIRROR: sel_frame->SetYmirrored(e.IsChecked()); break; + case CB_KEYPOINT: sel_frame->SetKeypointObscured(e.IsChecked()); break; + } + // update display + if (e.GetId() != CB_KEYPOINT) { + fb->RebuildThumbnail(fb->GetSelection()); + fb->Refresh(); + f_view->SetFrame(sel_frame); + } + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +// user messed with fields in the frame panel +void ShapesView::EditFrameFields(wxCommandEvent &e) +{ + ShapesFrame *sel_frame = f_view->GetFrame(); + wxString s = e.GetString(); + + if (sel_frame != NULL) { + long v = 0; + + if (s.ToLong(&v)) { + bool recalculate_world_fields = false; + + switch (e.GetId()) { + case FIELD_ORIGIN_X: + sel_frame->SetOriginX(v); + recalculate_world_fields = true; + break; + case FIELD_ORIGIN_Y: + sel_frame->SetOriginY(v); + recalculate_world_fields = true; + break; + case FIELD_KEY_X: + sel_frame->SetKeyX(v); + recalculate_world_fields = true; + break; + case FIELD_KEY_Y: + sel_frame->SetKeyY(v); + recalculate_world_fields = true; + break; + case FIELD_FRAME_SCALEFACTOR: + sel_frame->SetScaleFactor(v); + recalculate_world_fields = true; + break; + case FIELD_MIN_LIGHT_INT: + if (v > 100) { + wxBell(); + f_mli_field->ChangeValue(wxT("100")); + v = 100; + } else if (v < 0) { + wxBell(); + f_mli_field->ChangeValue(wxT("0")); + v = 0; + } + sel_frame->SetMinimumLightIntensity(v / 100.0); + break; + } + // recalculate world_* fields if needed and possible + if (recalculate_world_fields && sel_frame->BitmapIndex() >= 0 + && sel_frame->BitmapIndex() < (int)((ShapesDocument*)GetDocument())->CollectionBitmapCount(mSelectedColl, mSelectedVers)) { + ShapesBitmap *assoc_bitmap = ((ShapesDocument*)GetDocument())->GetBitmap(mSelectedColl, mSelectedVers, sel_frame->BitmapIndex()); + int w = assoc_bitmap->Width(), + h = assoc_bitmap->Height(), + scale_factor = sel_frame->ScaleFactor(); + + sel_frame->SetWorldLeft(-scale_factor * sel_frame->OriginX()); + sel_frame->SetWorldTop(scale_factor * sel_frame->OriginY()); + sel_frame->SetWorldRight(scale_factor * (w - sel_frame->OriginX())); + sel_frame->SetWorldBottom(-scale_factor * (h - sel_frame->OriginY())); + sel_frame->SetWorldX0(scale_factor * (sel_frame->KeyX() - sel_frame->OriginX())); + sel_frame->SetWorldY0(-scale_factor * (sel_frame->KeyY() - sel_frame->OriginY())); + } + f_view->Refresh(); + ((ShapesDocument*)GetDocument())->Modify(true); + } + } +} + +// callback for "delete sequence" button clicks +void ShapesView::DeleteSequence(wxCommandEvent &e) +{ + // first delete the sequence for real + ((ShapesDocument*)GetDocument())->DeleteSequence(mSelectedColl, mSelectedVers, mSelectedSequence); + + // for updating the tree control we could just delete the selected + // sequence item, but then ShapesTreeItemData structures associated + // to the following items would be broken and everything would crash. + // We could correct them, but reinserting all items is simpler. + wxTreeItemId seqnode = GetSequencesTreeItem(mSelectedColl, mSelectedVers); + + colltree->SelectItem(seqnode); + colltree->DeleteChildren(seqnode); + for (unsigned int k = 0; k < ((ShapesDocument*)GetDocument())->CollectionSequenceCount(mSelectedColl, mSelectedVers); k++) { + ShapesSequence *seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, k); + wxString label; + ShapesTreeItemData *seqdata = new ShapesTreeItemData(mSelectedColl, mSelectedVers, TREESECTION_SEQUENCES, k); + + label << k; + if (seq->Name().Len() > 0) + label << wxT(" - ") << seq->Name(); + colltree->AppendItem(seqnode, label, -1, -1, seqdata); + } + + mSelectedSequence = -1; + ((ShapesDocument*)GetDocument())->Modify(true); +} + +// sequence type menu in the sequence editor +void ShapesView::EditSequenceType(wxCommandEvent &e) +{ + if (mSelectedSequence >= 0) { + ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence); + int real_nov, old_nov; + + old_nov = ActualNumberOfViews(sel_seq->NumberOfViews()); + // always use ANIMATED_4, ANIMATED_5, ANIMATED_8 + // and never other values like ANIMATED_3TO4. Apparently + // nobody knows the real meaning of these values + switch (s_type_menu->GetSelection()) { + case 0: sel_seq->SetNumberOfViews(UNANIMATED); break; + case 1: sel_seq->SetNumberOfViews(ANIMATED_1); break; + case 2: sel_seq->SetNumberOfViews(ANIMATED_4); break; + case 3: sel_seq->SetNumberOfViews(ANIMATED_5); break; + case 4: sel_seq->SetNumberOfViews(ANIMATED_8); break; + } + real_nov = ActualNumberOfViews(sel_seq->NumberOfViews()); + + // Let's handle sequence frames changes... + if (real_nov > old_nov) { + // We are adding one (or more) view + // We need to add FramesPerView() * (real_nov - old_nov) + // to the END of the frame_index array + for (int i = 0; i < sel_seq->FramesPerView() * (real_nov - old_nov); i++) + sel_seq->mFrameIndexes.push_back(-1); + } else if (real_nov < old_nov) { + // We are removing one (or more) view + // We need to remove FramesPerView() * (old_nov - real_nov) + // from the END of the frame_index array + for (int i = 0; i < sel_seq->FramesPerView() * (old_nov - real_nov); i++) + sel_seq->mFrameIndexes.pop_back(); + } else { + // Hmm, number of views unchanged, don't bother... + } + s_fb->SetSeqParameters(sel_seq->NumberOfViews(), sel_seq->FramesPerView(), &sel_seq->mFrameIndexes, this); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +// transfer mode menu in the sequence editor +void ShapesView::EditSequenceXferMode(wxCommandEvent &e) +{ + if (mSelectedSequence >= 0) { + ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence); + + sel_seq->SetTransferMode(s_xfermode_menu->GetSelection()); + ((ShapesDocument*)GetDocument())->Modify(true); + } +} + +// user messed with fields in the sequence editor +void ShapesView::EditSequenceFields(wxCommandEvent &e) +{ + if (mSelectedSequence >= 0) { + ShapesSequence *sel_seq = ((ShapesDocument*)GetDocument())->GetSequence(mSelectedColl, mSelectedVers, mSelectedSequence); + wxString s = e.GetString(); + + if (sel_seq != NULL) { + if (e.GetId() == FIELD_SEQ_NAME) { + sel_seq->SetName(s.Left(32)); + // update the tree item label + wxTreeItemId seqnode = GetSequencesTreeItem(mSelectedColl, mSelectedVers); + wxTreeItemIdValue cookie; + wxTreeItemId id = colltree->GetFirstChild(seqnode, cookie); + + while (id.IsOk()) { + ShapesTreeItemData *itemdata = dynamic_cast(colltree->GetItemData(id)); + + if (itemdata->Sequence() == mSelectedSequence) { + // here we are + wxString blabel; + + blabel << mSelectedSequence; + if (sel_seq->Name().Length() > 0) + blabel << wxT(" - ") << sel_seq->Name(); + colltree->SetItemText(id, blabel); + break; + } + id = colltree->GetNextChild(seqnode, cookie); + } + ((ShapesDocument*)GetDocument())->Modify(true); + } else { + // numeric fields + long v; + + if (s.ToLong(&v)) { + switch (e.GetId()) { + case FIELD_SEQ_FRAMES_PER_VIEW: + // must update the SequenceView too + if (v != sel_seq->FramesPerView()) { + int real_nov = ActualNumberOfViews(sel_seq->NumberOfViews()), + old_fpv = sel_seq->FramesPerView(); + short old_indexes[real_nov * old_fpv]; + + for (int i = 0; i < real_nov * old_fpv; i++) + old_indexes[i] = sel_seq->mFrameIndexes[i]; + sel_seq->SetFramesPerView(v); + // try to preserve existing frame + // references as much as possible + sel_seq->mFrameIndexes.clear(); + for (int i = 0; i < real_nov; i++) { + for (int j = 0; j < v; j++) { + if (j < old_fpv) + sel_seq->mFrameIndexes.push_back(old_indexes[i*old_fpv + j]); + else + sel_seq->mFrameIndexes.push_back(-1); + } + } + s_fb->SetSeqParameters(sel_seq->NumberOfViews(), v, &sel_seq->mFrameIndexes, this); + } + break; + case FIELD_SEQ_TICKS_PER_FRAME: + sel_seq->SetTicksPerFrame(v); + break; + case FIELD_SEQ_LOOP_FRAME: + sel_seq->SetLoopFrame(v); + break; + case FIELD_SEQ_KEY_FRAME: + sel_seq->SetKeyFrame(v); + break; + case FIELD_SEQ_XFER_MODE_PERIOD: + sel_seq->SetTransferModePeriod(v); + break; + case FIELD_SEQ_FIRST_FRAME_SND: + sel_seq->SetFirstFrameSound(v); + break; + case FIELD_SEQ_KEY_FRAME_SND: + sel_seq->SetKeyFrameSound(v); + break; + case FIELD_SEQ_LAST_FRAME_SND: + sel_seq->SetLastFrameSound(v); + break; + } + ((ShapesDocument*)GetDocument())->Modify(true); + } + } + } + } +} + diff --git a/Shapes/ShapesView.h b/Shapes/ShapesView.h new file mode 100644 index 0000000..3ed5cd0 --- /dev/null +++ b/Shapes/ShapesView.h @@ -0,0 +1,269 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SHAPESVIEW_H +#define SHAPESVIEW_H + +#include "wx/docview.h" +#include "wx/treectrl.h" +#include "wx/spinctrl.h" +#include "wx/statline.h" +#include "../ShapeFusionApp.h" +#include "ShapesTreeItemData.h" +#include "CTBrowser.h" +#include "CTView.h" +#include "BitmapBrowser.h" +#include "BitmapView.h" +#include "FrameBrowser.h" +#include "FrameView.h" +#include "SequenceView.h" +#include "../ShapeFusionMenus.h" + +class ShapesView: public wxView +{ + DECLARE_DYNAMIC_CLASS(ShapesView) +private: + // control ids + enum { + // color tables + CB_SELF_LUMINESCENT, + BTN_GRADIENT, + // bitmaps + BITMAP_BROWSER, + CB_COLUMN_ORDER, + CB_ENABLE_TRANSPARENCY, + // frames + FRAME_BROWSER, + FRAME_VIEW, + FIELD_BITMAP_INDEX, + CB_XMIRROR, + CB_YMIRROR, + CB_KEYPOINT, + FIELD_ORIGIN_X, + FIELD_ORIGIN_Y, + FIELD_KEY_X, + FIELD_KEY_Y, + FIELD_FRAME_SCALEFACTOR, + FIELD_MIN_LIGHT_INT, + // sequences + FIELD_SEQ_NAME, + BTN_DELETE_SEQ, + MENU_SEQ_TYPE, + FIELD_SEQ_NUMBER_OF_VIEWS, + FIELD_SEQ_FRAMES_PER_VIEW, + FIELD_SEQ_TICKS_PER_FRAME, + FIELD_SEQ_LOOP_FRAME, + FIELD_SEQ_KEY_FRAME, + MENU_SEQ_XFER_MODE, + FIELD_SEQ_XFER_MODE_PERIOD, + FIELD_SEQ_FIRST_FRAME_SND, + FIELD_SEQ_KEY_FRAME_SND, + FIELD_SEQ_LAST_FRAME_SND, + }; + + wxBoxSizer *mainbox; + wxPanel *main_panel; + wxMenuBar *menubar; + wxTreeCtrl *colltree; + wxBoxSizer *dummy_sizer; + // widgets for collection info + wxBoxSizer *coll_sizer; + wxStaticBox *coll_static_box; + wxStaticBoxSizer *coll_inner_box; + wxStaticText *coll_text; + // widgets for chunk info + wxBoxSizer *chunk_sizer; + wxStaticBox *chunk_static_box; + wxStaticBoxSizer *chunk_inner_box; + wxStaticText *chunk_undef_label; + wxFlexGridSizer *chunk_grid; + wxStaticText *chunk_version_label, + *chunk_type_label, + *chunk_flags_label, + *chunk_sf_label; + wxTextCtrl *chunk_version_field, + *chunk_flags_field, + *chunk_sf_field; + wxChoice *chunk_type_menu; + // widgets for color tables section + wxBoxSizer *ct_outer_sizer; + CTBrowser *ctb; + wxStaticText *ct_count_label; + wxStaticBox *ct_edit_static_box; + wxStaticBoxSizer *ct_edit_box; + CTView *ct_view; + wxBoxSizer *ct_inner_edit_box; + wxCheckBox *ct_self_lumin_checkbox; + wxButton *ct_gradient_button; + // widgets for bitmaps section + wxBoxSizer *b_outer_sizer, + *b_edit_inner_box; + BitmapBrowser *bb; + wxStaticText *b_count_label; + wxStaticBox *b_edit_static_box; + wxStaticBoxSizer *b_edit_box; + wxCheckBox *b_order_checkbox, + *b_transparency_checkbox; + wxStaticText *b_info_label; + BitmapView *b_view; + // widgets for frames section + wxBoxSizer *f_outer_sizer, + *f_edit_inner_box; + FrameBrowser *fb; + wxStaticText *f_count_label; + wxStaticBox *f_edit_static_box; + wxStaticBoxSizer *f_edit_box; + wxStaticText *f_bitmap_label; + wxSpinCtrl *f_bitmap_id; + wxTextCtrl *f_origin_x_field, + *f_origin_y_field, + *f_key_x_field, + *f_key_y_field, + *f_scalefactor_field; + wxCheckBox *f_xmirror_checkbox, + *f_ymirror_checkbox, + *f_keypoint_checkbox; + FrameView *f_view; + wxFlexGridSizer *f_origin_box; + wxStaticText *f_origin_x_label, + *f_origin_y_label, + *f_key_x_label, + *f_key_y_label, + *f_scalefactor_label, + *f_mli_label, + *f_w_left_label, + *f_w_right_label, + *f_w_top_label, + *f_w_bottom_label, + *f_w_x0_label, + *f_w_y0_label; + wxTextCtrl *f_mli_field, + *f_w_left_field, + *f_w_right_field, + *f_w_top_field, + *f_w_bottom_field, + *f_w_x0_field, + *f_w_y0_field; + // widgets for sequences section + wxStaticBoxSizer *s_outer_sizer; + wxStaticBox *s_outer_static_box; + wxBoxSizer *s_box1; + wxStaticText *s_name_label; + wxTextCtrl *s_name_field; + wxButton *s_delete_button; + wxBoxSizer *s_box2; + wxFlexGridSizer *s_grid_box; + wxStaticText *s_type_label; + wxChoice *s_type_menu; + wxStaticText *s_fpv_label; + wxTextCtrl *s_fpv_field; + wxStaticText *s_tpf_label; + wxTextCtrl *s_tpf_field; + wxStaticText *s_lf_label; + wxTextCtrl *s_lf_field; + wxStaticText *s_kf_label; + wxTextCtrl *s_kf_field; + wxPanel *s_separator; + wxFlexGridSizer *s_grid_box2; + wxStaticText *s_xfermode_label; + wxChoice *s_xfermode_menu; + wxStaticText *s_xferperiod_label; + wxTextCtrl *s_xferperiod_field; + wxStaticText *s_ffs_label, + *s_kfs_label, + *s_lfs_label; + wxTextCtrl *s_ffs_field, + *s_kfs_field, + *s_lfs_field; + SequenceView *s_fb; + + int mSelectedColl, + mSelectedVers, + mSelectedSequence, + mViewColorTable; + wxFrame *mFrame; + +protected: + DECLARE_EVENT_TABLE(); + +public: + ShapesView(); + ~ShapesView(void); + + bool OnCreate(wxDocument *doc, long flags); + void OnDraw(wxDC *dc); + void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL); + bool OnClose(bool deleteWindow = true); + wxTreeItemId GetSequencesTreeItem(unsigned int collection, unsigned int version) const; + // menu event callbacks + void MenuFileOpen(wxCommandEvent &e); + void MenuFileSave(wxCommandEvent&); + void MenuFileQuit(wxCommandEvent &e); + void MenuEditCopy(wxCommandEvent& e); + void MenuEditDelete(wxCommandEvent &e); + void MenuEditPaste(wxCommandEvent& e); + void MenuViewCT(wxCommandEvent &e); + void MenuViewTNSize(wxCommandEvent &e); + void MenuViewTransparency(wxCommandEvent &e); + void MenuViewCenterOrigin(wxCommandEvent &e); + void MenuShapesAddColorTable(wxCommandEvent &e); + void MenuShapesSaveColorTable(wxCommandEvent &e); + void MenuShapesSaveColorTableToPS(wxCommandEvent &e); + void MenuShapesAddBitmap(wxCommandEvent &e); + void MenuShapesExportBitmap(wxCommandEvent &e); + void MenuShapesExportBitmapMask(wxCommandEvent &e); + void MenuShapesExportBitmaps(wxCommandEvent &e); + void MenuShapesExportBitmapMasks(wxCommandEvent &e); + void MenuShapesNewFrame(wxCommandEvent &e); + void MenuShapesNewSequence(wxCommandEvent &e); + void MenuShapesGeneratePatch(wxCommandEvent& e); + void MenuShapesImportPatch(wxCommandEvent& e); + // control callbacks + void OnTreeSelect(wxTreeEvent &e); + void OnBitmapSelect(wxCommandEvent &e); + void BitmapDelete(wxCommandEvent &e); + void OnCTSelect(wxCommandEvent &e); + void CTColorSelect(wxCommandEvent &e); + void CTColorChanged(wxCommandEvent &e); + void ToggleSelfLuminCheckbox(wxCommandEvent &e); + void MakeCTGradient(wxCommandEvent &e); + void ToggleBitmapCheckboxes(wxCommandEvent &e); + void OnFrameSelect(wxCommandEvent &e); + void FrameDelete(wxCommandEvent &e); + void OnFramePointDrag(wxCommandEvent &e); + void BitmapIndexSpin(wxSpinEvent &e); + void ToggleFrameCheckboxes(wxCommandEvent &e); + void EditFrameFields(wxCommandEvent &e); + void DeleteSequence(wxCommandEvent &e); + void EditSequenceType(wxCommandEvent &e); + void EditSequenceXferMode(wxCommandEvent &e); + void EditSequenceFields(wxCommandEvent &e); + + void DoCopyBitmap(int which); + void DoPasteBitmap(int which); + + void DoCopyChunk(unsigned int coll, unsigned int chunk); + void DoPasteChunk(unsigned int coll, unsigned int chunk); + + void DoDeleteColorTable(int which); + void DoDeleteBitmap(int which); + void DoDeleteFrame(int which); + +}; + +#endif diff --git a/Shapes/utilities.cpp b/Shapes/utilities.cpp new file mode 100644 index 0000000..7eeeb3e --- /dev/null +++ b/Shapes/utilities.cpp @@ -0,0 +1,183 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "ShapesElements.h" +#include "utilities.h" + +// convert an 8-bit ShapesBitmap to a RGB wxImage using the provided color table. +// renders transparent pixels as white instead of using +// the chroma-key color. NOTE: this routine assumes valid pointers. +wxImage ShapesBitmapToImage(ShapesBitmap *bp, ShapesColorTable *ct, bool white_transparency) +{ + int w = bp->Width(), + h = bp->Height(); + bool transparency_enabled = bp->IsTransparent(); + wxImage img(w, h); + unsigned char *imgbuf = img.GetData(), + *inp = bp->Pixels(), + *outp = imgbuf; + unsigned int colors_per_table = ct->ColorCount(); + + for (int i = 0; i < w * h; i++) { + unsigned char value = *inp++; + + if (value == 0 && transparency_enabled && white_transparency) { + *outp++ = 255; + *outp++ = 255; + *outp++ = 255; + } else if (value < colors_per_table) { + ShapesColor *color = ct->GetColor(value); + + *outp++ = color->Red() >> 8; + *outp++ = color->Green() >> 8; + *outp++ = color->Blue() >> 8; + } else { + wxLogError(wxT("[utilities ShapesBitmapToImage] Pixel value %u with just %u colors/table. Aborting"), + value, colors_per_table); + break; + } + } + return img; +} + +// create a wxBitmap thumbnail of the given wxImage. If the major wxImage +// dimension is greater than the specified thumbnail size, the wxImage +// will be scaled down (keeping its aspect ratio). If the wxImage is smaller, +// it will be just converted to a wxBitmap. +wxBitmap ImageThumbnail(wxImage &img, int tn_size, bool filtering) +{ + int w = img.GetWidth(), + h = img.GetHeight(); + + // scale the wxImage down to thumbnail size if larger + if (w > tn_size || h > tn_size) { + int new_w, new_h; + + if (w > h) { + new_w = tn_size; + new_h = new_w * h / w; + if (new_h < 1) + new_h = 1; + } else { + new_h = tn_size; + new_w = new_h * w / h; + if (new_w < 1) + new_w = 1; + } + + if (filtering) { + // wx doesn't allow nice scaling, so we supply here. The thing works this way: + // 1) calculate where each source pixel will end up in the final image + // 2) add the source pixel value to the destination pixel + // 3) divide each destination pixel by the number of pixels + // that were added there. + // It's nothing more than a brutal pixel-level average, but results are quite good. + wxImage scaledimg(new_w, new_h); + unsigned char *src = img.GetData(), + *srcp = src, + *dst = scaledimg.GetData(); + unsigned int pixcount = new_w * new_h, + *tempbuf = new unsigned int[pixcount * 3], + *countbuf = new unsigned int[pixcount]; + + memset(tempbuf, 0, pixcount * 3 * sizeof(unsigned int)); + memset(countbuf, 0, pixcount * sizeof(unsigned int)); + // sum + for (int y = 0; y < h; y++) { + unsigned int dsty = (y * new_h) / h * new_w; + + for (int x = 0; x < w; x++) { + unsigned int i = x * new_w / w + dsty, + *tempp = &tempbuf[3 * i]; + + *tempp++ += *srcp++; + *tempp++ += *srcp++; + *tempp += *srcp++; + countbuf[i]++; + } + } + // divide + unsigned int *tempp = tempbuf, + *countp = countbuf; + unsigned char *dstp = dst; + + for (unsigned int i = 0; i < pixcount; i++) { + unsigned int count = *countp++; + + if (count == 0) { + *dstp++ = 0; + *dstp++ = 0; + *dstp++ = 0; + } else { + *dstp++ = *tempp++ / count; + *dstp++ = *tempp++ / count; + *dstp++ = *tempp++ / count; + } + } + + delete[] tempbuf; + delete[] countbuf; + return wxBitmap(scaledimg); + } else { + // ugly (but fast and simple) wx scaler + img.Rescale(new_w, new_h); + return wxBitmap(img); + } + } else { + return wxBitmap(img); + } +} + +// create the "bad item" (red 'X') thumbnail +wxBitmap BadThumbnail(int tn_size) +{ + wxImage newimg(tn_size, tn_size); + unsigned char *imgbuf = newimg.GetData(), *p = imgbuf; + + for (int y = 0; y < tn_size; y++) { + for (int x = 0; x < tn_size; x++) { + if (x == y || (tn_size - x - 1) == y || (x - 1) == y || (x + 1) == y + || (tn_size - x - 2) == y || (tn_size - x) == y) { + *p++ = 255; + *p++ = 0; + *p++ = 0; + } else { + *p++ = 255; + *p++ = 255; + *p++ = 255; + } + } + } + return wxBitmap(newimg); +} + +// compute (squared) distance between given RGB colours (range [0;1]). +// This is used to quantize imported bitmaps against collection palettes. +// The formula seems to work quite well even for photos and very bad +// destination palettes. It was taken from the article "Colour metric" +// by T. Riemersma, available under a Creative Commons license at +// http://www.compuphase.com/cmetric.htm. +float ColourDistance(float r1, float g1, float b1, float r2, float g2, float b2) +{ + float rMean = (r1 + r2) / 2.0, + deltaR = r1 - r2, + deltaG = g1 - g2, + deltaB = b1 - b2; + + return (2.0+rMean)*deltaR*deltaR + 4.0*deltaG*deltaG + (2.0+1.0-rMean)*deltaB*deltaB; +} + diff --git a/Shapes/utilities.h b/Shapes/utilities.h new file mode 100644 index 0000000..067e9a4 --- /dev/null +++ b/Shapes/utilities.h @@ -0,0 +1,32 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef UTILITIES_H +#define UTILITIES_H + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif +#include "wx/image.h" + +wxImage ShapesBitmapToImage(ShapesBitmap *bp, ShapesColorTable *ct, bool white_transparency); +wxBitmap ImageThumbnail(wxImage &img, int tn_size, bool filtering); +wxBitmap BadThumbnail(int tn_size); +float ColourDistance(float r1, float g1, float b1, float r2, float g2, float b2); + +#endif diff --git a/Sounds/Makefile.am b/Sounds/Makefile.am new file mode 100644 index 0000000..30172c9 --- /dev/null +++ b/Sounds/Makefile.am @@ -0,0 +1,6 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libsounds.a + +libsounds_a_SOURCES = SoundsDocument.h SoundsElements.h SoundsView.h \ + SoundsDocument.cpp SoundsView.cpp SoundsElements.cpp diff --git a/Sounds/Makefile.in b/Sounds/Makefile.in new file mode 100644 index 0000000..4856a74 --- /dev/null +++ b/Sounds/Makefile.in @@ -0,0 +1,466 @@ +# Makefile.in generated by automake 1.11.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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 = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = Sounds +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libsounds_a_AR = $(AR) $(ARFLAGS) +libsounds_a_LIBADD = +am_libsounds_a_OBJECTS = SoundsDocument.$(OBJEXT) SoundsView.$(OBJEXT) \ + SoundsElements.$(OBJEXT) +libsounds_a_OBJECTS = $(am_libsounds_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsounds_a_SOURCES) +DIST_SOURCES = $(libsounds_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libsounds.a +libsounds_a_SOURCES = SoundsDocument.h SoundsElements.h SoundsView.h \ + SoundsDocument.cpp SoundsView.cpp SoundsElements.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Sounds/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Sounds/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libsounds.a: $(libsounds_a_OBJECTS) $(libsounds_a_DEPENDENCIES) + -rm -f libsounds.a + $(libsounds_a_AR) libsounds.a $(libsounds_a_OBJECTS) $(libsounds_a_LIBADD) + $(RANLIB) libsounds.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoundsDocument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoundsElements.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SoundsView.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-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/Sounds/SoundsDocument.cpp b/Sounds/SoundsDocument.cpp new file mode 100644 index 0000000..6ab6fb6 --- /dev/null +++ b/Sounds/SoundsDocument.cpp @@ -0,0 +1,255 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if wxUSE_STD_IOSTREAM + #include "wx/ioswrap.h" +#else + #include "wx/txtstrm.h" +#endif + +#include "SoundsDocument.h" +#include "SoundsView.h" + +// Construct four-character-code +#define FOUR_CHARS_TO_INT(a,b,c,d) (((unsigned int)(a) << 24) | ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d)) + +enum { + _sound_8bit = 0, + _sound_16bit, + NUMBER_OF_SOUND_SOURCES +}; + +IMPLEMENT_DYNAMIC_CLASS(SoundsDocument, wxDocument) + +SoundsDocument::SoundsDocument(): wxDocument(), SoundsElement(true), mM2Demo(false) +{ + // We need storage for our sound sources... + mSoundDefinitions.resize(NUMBER_OF_SOUND_SOURCES); +} + +SoundsDocument::~SoundsDocument() +{ +} + +SoundsDefinition *SoundsDocument::GetSoundDefinition(unsigned short source_index, unsigned short sound_index) +{ + if (source_index > mSoundDefinitions.size()) + return NULL; + if (sound_index > mSoundDefinitions[source_index].size()) + return NULL; + return mSoundDefinitions[source_index][sound_index]; +} + +SoundsDefinition *SoundsDocument::Get8BitSoundDefinition(unsigned short sound_index) +{ + return GetSoundDefinition(_sound_8bit, sound_index); +} + +SoundsDefinition *SoundsDocument::Get16BitSoundDefinition(unsigned short sound_index) +{ + return GetSoundDefinition(_sound_16bit, sound_index); +} + +void SoundsDocument::AddSoundDefinition(void) +{ + // As there's always two versions (8-bit/16-bit) of the same sound, we add both there... + SoundsDefinition *snd8 = new SoundsDefinition(), + *snd16 = new SoundsDefinition(); + + // We add 8-bit... + mSoundDefinitions[_sound_8bit].push_back(snd8); + // ... and 16-bit + mSoundDefinitions[_sound_16bit].push_back(snd16); + + // We mark ourselves as modified... + Modify(true); +} + +void SoundsDocument::DeleteSoundDefinition(unsigned int index) +{ + // We check we really have that much sounds... + if (index > mSoundDefinitions[_sound_8bit].size()) + return; + + // We remove 8-bit version + mSoundDefinitions[_sound_8bit].erase(mSoundDefinitions[_sound_8bit].begin() + index); + // We remove 16-bit version + mSoundDefinitions[_sound_16bit].erase(mSoundDefinitions[_sound_16bit].begin() + index); + + // We mark ourselves as modified... + Modify(true); +} + +bool SoundsDocument::DoOpenDocument(const wxString& file) +{ + bool wxOpen = wxDocument::DoOpenDocument(file); + + if (!(wxOpen && mGoodData)) { + wxLogError(wxT("[SoundsDocument] There was an error while loading, see log")); + return false; + } + return true; +} + +unsigned int SoundsDocument::GetSizeInFile(void) +{ + unsigned int size = SIZEOF_sound_file_header; + + for (unsigned int i = 0; i < mSoundDefinitions.size(); i++) + for (unsigned int j = 0; j < mSoundDefinitions[i].size(); j++) + size += mSoundDefinitions[i][j]->GetSizeInFile(); + + return size; +} + +#if wxUSE_STD_IOSTREAM +wxSTD ostream& SoundsDocument::SaveObject(wxSTD ostream& stream) +#else +wxOutputStream& SoundsDocument::SaveObject(wxOutputStream& stream) +#endif +{ + BigEndianBuffer filebuffer(GetSizeInFile()); + + unsigned int source_count = mSoundDefinitions.size(); + unsigned int sound_count = mSoundDefinitions[0].size(); + + filebuffer.WriteLong(mVersion); + filebuffer.WriteLong(mTag); + + if (mM2Demo) { + filebuffer.WriteShort(mSoundCount); + filebuffer.WriteShort(0); + } else { + filebuffer.WriteShort(source_count); + filebuffer.WriteShort(sound_count); + } + + filebuffer.Position(SIZEOF_sound_file_header); + + unsigned int current_sound_offset = SIZEOF_sound_file_header + + source_count * sound_count * SIZEOF_sound_definition; + + for (unsigned int i = 0; i < mSoundDefinitions.size(); i++) { + for (unsigned int j = 0; j < mSoundDefinitions[i].size(); j++) { + mSoundDefinitions[i][j]->SaveObject(filebuffer, current_sound_offset); + } + } + +#if wxUSE_STD_IOSTREAM + stream.write((char *)filebuffer.Data(), filebuffer.Size()); +#else + stream.Write((char *)filebuffer.Data(), filebuffer.Size()); +#endif + + return stream; +} + +#if wxUSE_STD_IOSTREAM +wxSTD istream& SoundsDocument::LoadObject(wxSTD istream& stream) +#else +wxInputStream& SoundsDocument::LoadObject(wxInputStream& stream) +#endif +{ +#if wxUSE_STD_IOSTREAM + stream.seekg(0, std::ios::end); + wxInt32 filesize = stream.tellg(); + stream.seekg(0, std::ios::beg); +#else + wxInt32 filesize = stream.GetSize(); +#endif + + BigEndianBuffer filebuffer(filesize); + +#if wxUSE_STD_IOSTREAM + stream.read((char *)filebuffer.Data(), filebuffer.Size()); +#else + stream.Read((char *)filebuffer.Data(), filebuffer.Size()); +#endif + + mVersion = filebuffer.ReadLong(); + mTag = filebuffer.ReadLong(); + mSourceCount = filebuffer.ReadShort(); + mSoundCount = filebuffer.ReadShort(); + + if ((mVersion != 0 && mVersion != 1) || mTag != FOUR_CHARS_TO_INT('s','n','d','2')) { + wxLogError(wxT("[SoundsDocument] Error loading : Incorrect version/tag, (%d/%x)"), mVersion, mTag); + return stream; + } + + if (mSoundCount < 0 || mSourceCount < 0) { + wxLogError(wxT("[SoundsDocument] Error loading : Incorrect Sound/Source count (%d/%d)"), mSoundCount, mSourceCount); + return stream; + } + + if (mSoundCount == 0) { + /* Handling Marathon 2 Demo + * We have to swap our counts + */ + mSoundCount = mSourceCount; + mSourceCount = 1; + mM2Demo = true; + } + + if (IsVerbose()) { + wxLogDebug(wxT("[SoundsDocument] Version: %d"), mVersion); + wxLogDebug(wxT("[SoundsDocument] Tag: %d"), mTag); + wxLogDebug(wxT("[SoundsDocument] Source Count: %d"), mSourceCount); + wxLogDebug(wxT("[SoundsDocument] Sound Count: %d"), mSoundCount); + } + + /* We move to the end of the Sound file header */ + filebuffer.Position(SIZEOF_sound_file_header); + + /* Now we load 8-bit and 16-bit sounds */ + for (int i = 0; i < mSourceCount; i++) { + for (int j = 0; j < mSoundCount; j++) { + SoundsDefinition *snd = new SoundsDefinition(IsVerbose()); + + if (IsVerbose()) + wxLogDebug(wxT("[SoundsDocument] Loading source %d, sound %d"), i, j); + + unsigned int oldpos = filebuffer.Position(); + + snd->LoadObject(filebuffer); + + if (!snd->IsGood()) { + wxLogError(wxT("[SoundsDocument] Error loading sound definition. Skipping...")); + return stream; + } + + filebuffer.Position(oldpos + SIZEOF_sound_definition); + + mSoundDefinitions[i].push_back(snd); + } + } + + mGoodData = true; + return stream; +} + diff --git a/Sounds/SoundsDocument.h b/Sounds/SoundsDocument.h new file mode 100644 index 0000000..32b24ab --- /dev/null +++ b/Sounds/SoundsDocument.h @@ -0,0 +1,77 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __SOUNDDOCUMENT_H__ +#define __SOUNDDOCUMENT_H__ + +#include "wx/docview.h" +#include "wx/cmdproc.h" +#include "SoundsElements.h" + +class SoundsDocument: public wxDocument, public SoundsElement +{ + DECLARE_DYNAMIC_CLASS(SoundsDocument) + +private: + /* Marathon Sound Header */ + int mVersion; + int mTag; + + short mSourceCount; // usually 2 (8-bit, 16-bit) + short mSoundCount; + + // immediately followed by source_count*sound_count sound_definition structures + std::vector< std::vector > mSoundDefinitions; + + /* some of our needed info */ + bool mM2Demo; + +public: + SoundsDocument(void); + ~SoundsDocument(void); + + int GetVersion(void) const {return mVersion;} + int GetTag(void) const {return mTag;} + + unsigned int GetSourceCount(void) const {return mSourceCount;} + unsigned int GetSoundCount(void) const {return mSoundCount;} + + SoundsDefinition *GetSoundDefinition(unsigned short source_index, unsigned short sound_index); + SoundsDefinition *Get8BitSoundDefinition(unsigned short sound_index); + SoundsDefinition *Get16BitSoundDefinition(unsigned short sound_index); + + void AddSoundDefinition(void); + void DeleteSoundDefinition(unsigned int index); + + bool IsM2DemoFile(void) const {return mM2Demo;} + void SetM2DemoFile(bool b) {mM2Demo = b;} + + bool DoOpenDocument(const wxString& file); + + // Utilities + unsigned int GetSizeInFile(void); +#if wxUSE_STD_IOSTREAM + wxSTD ostream& SaveObject(wxSTD ostream& stream); + wxSTD istream& LoadObject(wxSTD istream& stream); +#else + wxOutputStream& SaveObject(wxOutputStream& stream); + wxInputStream& LoadObject(wxInputStream& stream); +#endif +}; + +#endif diff --git a/Sounds/SoundsElements.cpp b/Sounds/SoundsElements.cpp new file mode 100644 index 0000000..efb19c9 --- /dev/null +++ b/Sounds/SoundsElements.cpp @@ -0,0 +1,698 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if wxUSE_STD_IOSTREAM + #include "wx/ioswrap.h" +#else + #include "wx/txtstrm.h" +#endif +#include "wx/filename.h" +#include "wx/sound.h" + +#include "SoundsElements.h" +#include "../LittleEndianBuffer.h" + +#include + +#define FOUR_CHARS_TO_INT(a,b,c,d) (((unsigned int)(a) << 24) | ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d)) + +struct sf_adapter +{ +public: + sf_adapter(std::vector& data) : data_(data), p_(data.begin()) { } + + static sf_count_t get_filelen(void *pv) { + return ((sf_adapter*) pv)->_get_filelen(); + } + + static sf_count_t seek(sf_count_t offset, int whence, void *pv) { + return ((sf_adapter*) pv)->_seek(offset, whence); + } + + static sf_count_t read(void *ptr, sf_count_t count, void *pv) { + return ((sf_adapter*) pv)->_read(ptr, count); + } + + static sf_count_t write(const void *ptr, sf_count_t count, void *pv) { + return ((sf_adapter*) pv)->_write(ptr, count); + } + + static sf_count_t tell(void *pv) { + return ((sf_adapter*) pv)->_tell(); + } + +private: + std::vector& data_; + std::vector::iterator p_; + + sf_count_t _get_filelen() { + return data_.size(); + } + + sf_count_t _seek(sf_count_t offset, int whence) { + if (whence == SEEK_SET) + p_ = data_.begin() + offset; + else if (whence == SEEK_END) + p_ = data_.end() - offset; + else if (whence == SEEK_CUR) + p_ += offset; + + return ((p_ >= data_.begin() && p_ <= data_.end()) ? 0 : -1); + } + + sf_count_t _read(void *ptr, sf_count_t count) { + if (p_ >= data_.end()) return -1; + char *dst = reinterpret_cast(ptr); + int i = 0; + for (; i < count && p_ < data_.end(); ++i) + { + *(dst++) = *(p_++); + } + + return i; + } + + sf_count_t _write(const void *ptr, sf_count_t count) { + if (p_ >= data_.end()) return -1; + + const char *src = reinterpret_cast(ptr); + int i = 0; + for (; i < count && p_ < data_.end(); ++i) + { + *(p_++) = *(src++); + } + + return i; + } + + sf_count_t _tell() { + return p_ - data_.begin(); + } + +}; + +AppleSoundHeader::AppleSoundHeader(bool verbose): SoundsElement(verbose) +{ +} + +AppleSoundHeader::~AppleSoundHeader() +{ +} + +bool AppleSoundHeader::operator==(const AppleSoundHeader& right) const +{ + return (mSixteenBit == right.mSixteenBit && + mStereo == right.mStereo && + mSigned == right.mSigned && + mBytesPerFrame == right.mBytesPerFrame && + mSampleRate == right.mSampleRate && + mLoopStart == right.mLoopStart && + mLoopEnd == right.mLoopEnd && + mBaseFrequency == right.mBaseFrequency && + mData == right.mData); +} + +BigEndianBuffer& AppleSoundHeader::LoadObject(BigEndianBuffer& buffer) +{ + unsigned char headerType = buffer.Data()[buffer.Position() + 20]; + switch (headerType) { + case standardSoundHeader: + { + mBytesPerFrame = 1; + mSigned = false; + mStereo = false; + mSixteenBit = false; + + buffer.ReadULong(); // sample pointer + + int frames = buffer.ReadLong(); + mSampleRate = buffer.ReadULong(); + mLoopStart = buffer.ReadLong(); + mLoopEnd = buffer.ReadLong(); + + buffer.ReadUChar(); // type + mBaseFrequency = buffer.ReadUChar(); + + mData.resize(frames); + buffer.ReadBlock(mData.size(), &mData[0]); + break; + } + case extendedSoundHeader: + case compressedSoundHeader: + { + buffer.ReadULong(); // samplePtr + mStereo = (buffer.ReadLong() == 2); + mSampleRate = buffer.ReadULong(); + mLoopStart = buffer.ReadLong(); + mLoopEnd = buffer.ReadLong(); + + buffer.ReadUChar(); // type + mBaseFrequency = buffer.ReadUChar(); + + int frames = buffer.ReadLong(); + + if (headerType == compressedSoundHeader) { + buffer.Position(buffer.Position() + 10); // AIFF rate + buffer.ReadULong(); // marker chunk + unsigned int format = buffer.ReadULong(); + buffer.ReadULong(); // future use + buffer.ReadULong(); // stateVars + buffer.ReadULong(); // leftOverSamples + short comp_id = buffer.ReadShort(); + if (format != FOUR_CHARS_TO_INT('t', 'w', 'o', 's') || comp_id != -1) { + wxLogError(wxT("[AppleSoundHeader] Unsupported compression format '%.4s.'"), &format); + mGoodData = false; + return buffer; + } + mSigned = true; + buffer.ReadShort(); // packetSize + buffer.ReadShort(); // unused + mSixteenBit = (buffer.ReadShort() == 16); + } else { + mSigned = false; + buffer.Position(buffer.Position() + 22); + mSixteenBit = (buffer.ReadShort() == 16); + buffer.Position(buffer.Position() + 14); + } + + mBytesPerFrame = (mSixteenBit ? 2 : 1) * (mStereo ? 2 : 1); + mData.resize(frames * mBytesPerFrame); + buffer.ReadBlock(mData.size(), &mData[0]); + break; + } + default: + wxLogError(wxT("[AppleSoundHeader] Unknown header type %.2x."), headerType); + mGoodData = false; + return buffer; + } + + mGoodData = true; + return buffer; +} + +BigEndianBuffer& AppleSoundHeader::SaveObject(BigEndianBuffer& buffer) +{ + if (mSixteenBit || mStereo || mSigned) { + // extended or compressed sound header + buffer.WriteULong(0); // samplePtr + buffer.WriteLong(mStereo ? 2 : 1); + buffer.WriteULong(mSampleRate); + buffer.WriteLong(mLoopStart); + buffer.WriteLong(mLoopEnd); + + buffer.WriteUChar((mSigned && !mSixteenBit) ? compressedSoundHeader : extendedSoundHeader); + buffer.WriteUChar(mBaseFrequency); + buffer.WriteLong(mData.size() / mBytesPerFrame); + buffer.WriteZeroes(10); // AIFF rate + buffer.WriteULong(0); // marker chunk + if (mSigned && !mSixteenBit) { + buffer.Write4CharCode('t', 'w', 'o', 's'); + buffer.WriteLong(0); // futureUse2 + buffer.WriteULong(0); // stateVars + buffer.WriteULong(0); // leftOverSamples + buffer.WriteShort(-1); // compressionID + buffer.WriteShort(0); // packetSize + buffer.WriteShort(0); // synthID + buffer.WriteShort(mSixteenBit ? 16 : 8); + } else { + buffer.WriteULong(0); // instrument chunks + buffer.WriteULong(0); // AESRecording + buffer.WriteShort(mSixteenBit ? 16 : 8); + buffer.WriteZeroes(14); // futureUse1 through futureUse4 + } + buffer.WriteBlock(mData.size(), &mData[0]); + } else { + // standard sound header + buffer.WriteULong(0); // sample ptr + buffer.WriteLong(mData.size()); // frames + buffer.WriteULong(mSampleRate); + buffer.WriteLong(mLoopStart); + buffer.WriteLong(mLoopEnd); + buffer.WriteUChar(standardSoundHeader); + buffer.WriteUChar(mBaseFrequency); + buffer.WriteBlock(mData.size(), &mData[0]); + } + + return buffer; +} + +static const int kBufferSize = 8192; + +// RAII for SNDFILE* +class SNDFILE_ptr { +public: + SNDFILE_ptr(SNDFILE* file) : mFile(file) {} + ~SNDFILE_ptr() { if (mFile) sf_close(mFile); mFile = 0; } + SNDFILE* get() { return mFile; } +private: + SNDFILE_ptr(const SNDFILE_ptr&); + SNDFILE_ptr& operator= (const SNDFILE_ptr&); + SNDFILE* mFile; +}; + +bool AppleSoundHeader::LoadFromFile(wxString path) +{ + SF_INFO inputInfo; + SNDFILE_ptr infile(sf_open(path.fn_str(), SFM_READ, &inputInfo)); + if (!infile.get()) { + wxLogError(wxT("[AppleSoundHeader] libsndfile could not open file.")); + return false; + } + + mSixteenBit = !(inputInfo.format & (SF_FORMAT_PCM_S8 | SF_FORMAT_PCM_U8)); + if (inputInfo.samplerate <= 44100) { + mSampleRate = inputInfo.samplerate << 16; + } else { + mSampleRate = 44100 << 16; + } + mStereo = (inputInfo.channels >= 2); + mSigned = false; + mBytesPerFrame = (mSixteenBit ? 2 : 1) * (mStereo ? 2 : 1); + mLoopStart = mLoopEnd = 0; + mBaseFrequency = 60; + + SF_INFO outputInfo; + outputInfo.samplerate = mSampleRate >> 16; + outputInfo.channels = mStereo ? 2 : 1; + if (mSixteenBit) { + outputInfo.format = SF_FORMAT_PCM_16 | SF_FORMAT_RAW | SF_ENDIAN_BIG; + } else { + outputInfo.format = SF_FORMAT_PCM_U8 | SF_FORMAT_RAW | SF_ENDIAN_BIG; + } + + SF_VIRTUAL_IO virtual_io = { + &sf_adapter::get_filelen, + &sf_adapter::seek, + &sf_adapter::read, + &sf_adapter::write, + &sf_adapter::tell }; + + mData.resize(inputInfo.frames * mBytesPerFrame); + sf_adapter adapter(mData); + + SNDFILE_ptr outfile(sf_open_virtual(&virtual_io, SFM_WRITE, &outputInfo, &adapter)); + if (!outfile.get()) { + wxLogError(wxT("[AppleSoundHeader] libsndfile write error.")); + return false; + } + + int frames_remaining = inputInfo.frames; + while (frames_remaining > 0) { + int buf[kBufferSize * 2]; + int frames = std::min(kBufferSize, frames_remaining); + + if (sf_readf_int(infile.get(), buf, frames) != frames) { + wxLogError(wxT("[AppleSoundHeader] libsndfile read error.")); + return false; + } + if (sf_writef_int(outfile.get(), buf, frames) != frames) { + wxLogError(wxT("[AppleSoundHeader] libsndfile write error.")); + return false; + } + + frames_remaining -= frames; + } + + return true; +} + +bool AppleSoundHeader::SaveToWaveOrAiff(wxString path, bool aiff) +{ + int inputFormat; + int outputFormat; + + if (mSixteenBit) { + inputFormat = outputFormat = SF_FORMAT_PCM_16; + } else if (mSigned) { + inputFormat = SF_FORMAT_PCM_S8; + outputFormat = SF_FORMAT_PCM_U8; + } else { + inputFormat = outputFormat = SF_FORMAT_PCM_U8; + } + + SF_INFO outputInfo; + outputInfo.samplerate = mSampleRate >> 16; + outputInfo.channels = mStereo ? 2 : 1; + if (aiff) { + outputInfo.format = SF_FORMAT_AIFF | outputFormat; + } else { + outputInfo.format = SF_FORMAT_WAV | outputFormat; + } + + SNDFILE* outfile = sf_open(path.fn_str(), SFM_WRITE, &outputInfo); + + SF_VIRTUAL_IO virtual_io = { + &sf_adapter::get_filelen, + &sf_adapter::seek, + &sf_adapter::read, + &sf_adapter::write, + &sf_adapter::tell }; + + sf_adapter adapter(mData); + + SF_INFO inputInfo; + inputInfo.samplerate = mSampleRate >> 16; + inputInfo.channels = mStereo ? 2 : 1; + inputInfo.format = SF_FORMAT_RAW | inputFormat | SF_ENDIAN_BIG; + + SNDFILE* infile = sf_open_virtual(&virtual_io, SFM_READ, &inputInfo, &adapter); + + int frames_remaining = mData.size() / mBytesPerFrame; + while (frames_remaining) { + int buf[kBufferSize * 2]; + int frames = std::min(kBufferSize, frames_remaining); + if (sf_readf_int(infile, buf, frames) != frames) { + wxLogError(wxT("[AppleSoundHeader] libsndfile read error")); + sf_close(infile); + sf_close(outfile); + return false; + } + if (sf_writef_int(outfile, buf, frames) != frames) { + wxLogError(wxT("[AppleSoundHeader] libsndfile write error")); + sf_close(infile); + sf_close(outfile); + return false; + } + + frames_remaining -= frames; + } + + sf_close(infile); + sf_close(outfile); + + return true; +} + +void AppleSoundHeader::PlaySound(void) +{ + wxString tempfile = wxFileName::CreateTempFileName(wxT("sf")) + wxString(wxT(".wav")); + + wxBeginBusyCursor(); + SaveToWave(tempfile); + wxSound(tempfile).Play(wxSOUND_SYNC); + wxRemoveFile(tempfile); + wxEndBusyCursor(); +} + +unsigned int AppleSoundHeader::Size(void) +{ + if (mSixteenBit || mStereo || mSigned) { + // compressed or extended header + return mData.size() + 64; + } else { + return mData.size() + 22; + } +} + +unsigned char* AppleSoundHeader::Data(void) +{ + return &mData[0]; +} + +SoundsDefinition::SoundsDefinition(bool verbose): SoundsElement(verbose) +{ + mSoundCode = -1; + mBehaviorIndex = _sound_is_quiet; + mFlags = 0; + mChance = _always; + mSounds.clear(); +} + +SoundsDefinition::~SoundsDefinition() +{ +} + +bool SoundsDefinition::HaveSameAttributesAs(const SoundsDefinition& right) const +{ + return ((mSoundCode == right.mSoundCode) && + (mBehaviorIndex == right.mBehaviorIndex) && + (mFlags == right.mFlags) && + (mChance == right.mChance) && + (mLowPitch == right.mLowPitch) && + (mHighPitch == right.mHighPitch)); +} + +bool SoundsDefinition::HaveSameSoundsAs(const SoundsDefinition& right) const +{ + return (mSounds == right.mSounds); +} + +bool SoundsDefinition::operator== (const SoundsDefinition& right) const +{ + return (HaveSameAttributesAs(right) && HaveSameSoundsAs(right)); +} + +bool SoundsDefinition::operator!=(const SoundsDefinition& right) const +{ + return (!HaveSameAttributesAs(right) || !HaveSameSoundsAs(right)); +} + +unsigned int SoundsDefinition::GetSizeInFile(void) +{ + unsigned int size = SIZEOF_sound_definition; + + for (unsigned int i = 0; i < mSounds.size(); i++) + size += mSounds[i].Size(); + return size; +} + +short SoundsDefinition::GetChance(void) const +{ + for (int i = 0; i < 10; i++) { + if (mChance == 32768*i/10) + return i; + } + wxLogDebug(wxT("Invalid chance %d"), mChance); + return -1; +} + +void SoundsDefinition::SetChance(short chance) +{ + if (chance < 0 || chance > 10) + wxLogDebug(wxT("Invalid chance %d"), mChance); + mChance = 32768*chance/10; +} + +BigEndianBuffer& SoundsDefinition::SaveObject(BigEndianBuffer& buffer, unsigned int& offset) +{ + unsigned int oldpos = buffer.Position(); + + // We write sound_definition header + buffer.WriteShort(mSoundCode); + + buffer.WriteShort(mBehaviorIndex); + buffer.WriteUShort(mFlags); + + buffer.WriteUShort(mChance); + + float low_pitch_integer, low_pitch_fractional, + high_pitch_integer, high_pitch_fractional; + long low_pitch = 0, high_pitch = 0; + + // float to fixed + low_pitch_fractional = modff(mLowPitch, &low_pitch_integer); + low_pitch |= (((short)low_pitch_integer) << 16) & 0xffff0000; + low_pitch |= (short)roundf(low_pitch_fractional * 0xffff) & 0x0000ffff; + + high_pitch_fractional = modff(mHighPitch, &high_pitch_integer); + high_pitch |= (((short)high_pitch_integer) << 16) & 0xffff0000; + high_pitch |= (short)roundf(high_pitch_fractional * 0xffff) & 0x0000ffff; + + buffer.WriteLong(low_pitch); + buffer.WriteLong(high_pitch); + + buffer.WriteShort(mSounds.size()); + buffer.WriteUShort(mPermutationsPlayed); + + // We need to recalculate those fields... + unsigned long single_length = (mSounds.size() >= 1 ? mSounds[0].Size() : 0); + unsigned long total_length = single_length; + std::vector soundOffsets; + soundOffsets.push_back(0); + + // ... and the corresponding offsets ... + for (unsigned int i = 1; i < mSounds.size(); i++) { + soundOffsets.push_back(total_length); + total_length += mSounds[i].Size(); + } + + // ... and write everything + buffer.WriteLong(offset); + buffer.WriteLong(single_length); + buffer.WriteLong(total_length); + + // We have to pad with zeroes, as engine always expect MAXIMUM_PERMUTATIONS_PER_SOUND sound offsets... + for (unsigned int i = 0; i < MAXIMUM_PERMUTATIONS_PER_SOUND; i++) { + if (i < soundOffsets.size()) + buffer.WriteLong(soundOffsets[i]); + else + buffer.WriteLong(0); + } + + buffer.WriteULong(mLastPlayed); + + // Now, we write actual sound data where it belongs... + buffer.Position(offset); + + for (unsigned int i = 0; i < mSounds.size(); i++) { + mSounds[i].SaveObject(buffer); + } + + // We put back position to the end of the written sound_definition... + buffer.Position(oldpos + SIZEOF_sound_definition); + // ... and add our total_length to the offset, so that next invocation + // writes its sound data at the correct place. + offset += total_length; + + return buffer; +} + +BigEndianBuffer& SoundsDefinition::LoadObject(BigEndianBuffer& buffer) +{ + mSoundCode = buffer.ReadShort(); + + mBehaviorIndex = buffer.ReadShort(); + mFlags = buffer.ReadUShort(); + + mChance = buffer.ReadUShort(); + + if ((mBehaviorIndex > NUMBER_OF_SOUND_BEHAVIOR_DEFINITIONS) || (mChance > _ten_percent)) { + wxLogError(wxT("[SoundsDefinition] incorrect Behavior/Chance (%d/%d)"), mBehaviorIndex, mChance); + return buffer; + } + + wxInt32 low_pitch_fixed, high_pitch_fixed; + + low_pitch_fixed = buffer.ReadLong(); + high_pitch_fixed = buffer.ReadLong(); + + mLowPitch = ((low_pitch_fixed >> 16) & 0xffff) + (float)(low_pitch_fixed & 0xffff) / 65536.0; // convert fixed point [0,1] to float + mHighPitch = ((high_pitch_fixed >> 16) & 0xffff) + (float)(high_pitch_fixed & 0xffff) / 65536.0; // convert fixed point [0,1] to float + + short permutations = buffer.ReadShort(); + + if (permutations < 0 || permutations > MAXIMUM_PERMUTATIONS_PER_SOUND) { + wxLogError(wxT("[SoundsDefinition] incorrect permutation count : %d"), permutations); + return buffer; + } + + mPermutationsPlayed = buffer.ReadUShort(); + int groupOffset = buffer.ReadULong(); + int singleLength = buffer.ReadULong(); + int totalLength = buffer.ReadULong(); + + // Bug fix for RED Sounds : When groupOffset is out of bounds, consider sound empty. + if (groupOffset < 0) + permutations = 0; + + if (permutations != 0 && (unsigned int)(groupOffset + totalLength) > buffer.Size()) { + wxLogError(wxT("[SoundsDefinition] incorrect group offset / total length (%d/%d)"), groupOffset, totalLength); + return buffer; + } + + std::vector soundOffsets; + + soundOffsets.resize(MAXIMUM_PERMUTATIONS_PER_SOUND); + for (unsigned int i = 0; i < MAXIMUM_PERMUTATIONS_PER_SOUND; i++) { + soundOffsets[i] = buffer.ReadLong(); + } + + mLastPlayed = buffer.ReadULong(); + + if (IsVerbose()) { + wxLogDebug(wxT("[SoundsDefinition] Sound Code: %d"), mSoundCode); + wxLogDebug(wxT("[SoundsDefinition] Behavior Index: %d"), mBehaviorIndex); + wxLogDebug(wxT("[SoundsDefinition] Flags: %d"), mFlags); + wxLogDebug(wxT("[SoundsDefinition] Chance: %d"), mChance); + wxLogDebug(wxT("[SoundsDefinition] Low Pitch: %f"), mLowPitch); + wxLogDebug(wxT("[SoundsDefinition] High Pitch: %f"), mHighPitch); + wxLogDebug(wxT("[SoundsDefinition] Permutations: %d"), permutations); + wxLogDebug(wxT("[SoundsDefinition] Permutations Played: %d"), mPermutationsPlayed); + wxLogDebug(wxT("[SoundsDefinition] Group Offset: %d"), groupOffset); + wxLogDebug(wxT("[SoundsDefinition] Single Length: %d"), singleLength); + wxLogDebug(wxT("[SoundsDefinition] Total Length: %d"), totalLength); + wxLogDebug(wxT("[SoundsDefinition] Last Played: %d"), mLastPlayed); + } + + // Now we load actual sound data + // We save our current position, 'coz we need to restore it at the end + unsigned int oldpos = buffer.Position(); + + for (short i = 0; i < permutations; i++) { + unsigned int size = 0; + if (permutations == 1) + size = singleLength; + else if (i == permutations - 1) + size = totalLength - soundOffsets[i]; + else + size = soundOffsets[i + 1] - soundOffsets[i]; + + AppleSoundHeader sndbuffer(IsVerbose()); + + buffer.Position(groupOffset + soundOffsets[i]); + sndbuffer.LoadObject(buffer); + if (sndbuffer.IsGood()) { + mSounds.push_back(sndbuffer); + } else { + mGoodData = false; + return buffer; + } + } + + buffer.Position(oldpos); + + mGoodData = true; + return buffer; +} + +AppleSoundHeader* SoundsDefinition::GetPermutation(unsigned int permutation_index) +{ + if (permutation_index >= mSounds.size()) + return NULL; + return &mSounds[permutation_index]; +} + +void SoundsDefinition::DeletePermutation(unsigned int permutation_index) +{ + mSounds.erase(mSounds.begin() + permutation_index); +} + +AppleSoundHeader* SoundsDefinition::NewPermutation(wxString path) +{ + if (mSounds.size() >= MAXIMUM_PERMUTATIONS_PER_SOUND) { + return NULL; + } + + AppleSoundHeader header(IsVerbose()); + if (header.LoadFromFile(path)) { + mSounds.push_back(header); + return &mSounds.back(); + } else { + return NULL; + } +} diff --git a/Sounds/SoundsElements.h b/Sounds/SoundsElements.h new file mode 100644 index 0000000..d502742 --- /dev/null +++ b/Sounds/SoundsElements.h @@ -0,0 +1,230 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SOUNDSELEMENTS_H +#define SOUNDSELEMENTS_H + +#include +#include +using std::vector; + +#include "../BigEndianBuffer.h" + +/* ---------- constants */ + +#define MAXIMUM_PERMUTATIONS_PER_SOUND 5 +#define SOUND_FILE_VERSION 1 +#define SIZEOF_sound_file_header 260 +#define SIZEOF_sound_definition 64 + +enum /* sound behaviors */ +{ + _sound_is_quiet, + _sound_is_normal, + _sound_is_loud, + NUMBER_OF_SOUND_BEHAVIOR_DEFINITIONS +}; + +enum // Sounds flags +{ + _sound_cannot_be_restarted= 0x0001, + _sound_does_not_self_abort= 0x0002, + _sound_resists_pitch_changes= 0x0004, // 0.5 external pitch changes + _sound_cannot_change_pitch= 0x0008, // no external pitch changes + _sound_cannot_be_obstructed= 0x0010, // ignore obstructions + _sound_cannot_be_media_obstructed= 0x0020, // ignore media obstructions + _sound_is_ambient= 0x0040 // will not be loaded unless _ambient_sound_flag is asserted +}; + +enum /* sound chances */ +{ + _ten_percent= 32768*9/10, + _twenty_percent= 32768*8/10, + _thirty_percent= 32768*7/10, + _fourty_percent= 32768*6/10, + _fifty_percent= 32768*5/10, + _sixty_percent= 32768*4/10, + _seventy_percent= 32768*3/10, + _eighty_percent= 32768*2/10, + _ninty_percent= 32768*1/10, + _always= 0 +}; + +/* ---------- structures */ + +/*typedef struct { + short sound_index; +} ambient_sound_definition; + +typedef struct { + short sound_index; +} random_sound_definition;*/ + +class SoundsElement // : public wxObject +{ +private: + bool mVerboseLoading; + +protected: + // So that subclasses can change their status + bool mGoodData; + +public: + SoundsElement(bool verbose) : mVerboseLoading(verbose), mGoodData(false) {} + ~SoundsElement(void) {} + + bool IsGood() const {return mGoodData;} + bool IsVerbose() const {return mVerboseLoading;} +}; + +class AppleSoundHeader : public SoundsElement +{ +private: + // Stuff for reading System 7 Sound info + /*sampled sound header encoding options*/ + enum { + standardSoundHeader = 0x00, + extendedSoundHeader = 0xFF, + compressedSoundHeader = 0xFE + }; + + bool mSixteenBit; + bool mStereo; + bool mSigned; + int mBytesPerFrame; + unsigned int mSampleRate; // 16.16 unsigned fixed + int mLoopStart; + int mLoopEnd; + unsigned char mBaseFrequency; + + std::vector mData; + + bool SaveToWaveOrAiff(wxString path, bool aiff); + +public: + AppleSoundHeader(bool verbose = false); + ~AppleSoundHeader(); + + bool operator==(const AppleSoundHeader& right) const; + + bool LoadFromFile(wxString path); + bool LoadFromWave(wxString path); + bool SaveToWave(wxString path) { return SaveToWaveOrAiff(path, false); } + bool LoadFromAiff(wxString path); + bool SaveToAiff(wxString path) { return SaveToWaveOrAiff(path, true); } + void PlaySound(void); + + bool IsSixteenBit() const { return mSixteenBit; } + bool IsStereo() const { return mStereo; } + bool IsSigned() const { return mSigned; } + int GetBytesPerFrame() const { return mBytesPerFrame; } + unsigned int GetSampleRate() const { return mSampleRate; } + + void SetSixteenBit(bool s) { mSixteenBit = s; } + void SetStereo(bool s) { mStereo = s; } + void SetSigned(bool s) { mSigned = s; } + void SetBytesPerFrame(int b) { mBytesPerFrame = b; } + void SetSampleRate(unsigned int sr) { mSampleRate = sr; } + + // Utilities + unsigned int Size(void); + unsigned char* Data(void); + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +class SoundsDefinition : public SoundsElement +{ +private: + /* Marathon Sound Definition */ + short mSoundCode; + short mBehaviorIndex; + unsigned short mFlags; + unsigned short mChance; // play sound if AbsRandom()>=chance + /* if low_pitch==0, use FIXED_ONE; + * if high_pitch==0 use low pitch; + * else choose in [low_pitch,high_pitch] + */ + float mLowPitch, mHighPitch; + /* filled in later */ +// short mPermutations; + unsigned short mPermutationsPlayed; +// int mGroupOffset, mSingleLength, mTotalLength; // magic numbers necessary to load sounds +// std::vector mSoundOffsets; + std::vector mSounds; + unsigned int mLastPlayed; // machine ticks + // Pointer to loaded sound and size of sound object pointed to +// short *ptr; +// int size; + + bool mRemap8bit; + +public: + SoundsDefinition(bool verbose = false); + ~SoundsDefinition(); + + bool HaveSameAttributesAs(const SoundsDefinition& right) const; + bool HaveSameSoundsAs(const SoundsDefinition& right) const; + bool operator== (const SoundsDefinition& right) const; + bool operator!=(const SoundsDefinition& right) const; + + short GetSoundCode(void) const {return mSoundCode;} + short GetBehaviorIndex(void) const {return mBehaviorIndex;} + + bool IsNotRestartable(void) const {return mFlags & _sound_cannot_be_restarted;} + bool IsNotSelfAbortable(void) const {return mFlags & _sound_does_not_self_abort;} + bool IsPitchChangeResistant(void) const {return mFlags & _sound_resists_pitch_changes;} + bool IsNotPitchChangeable(void) const {return mFlags & _sound_cannot_change_pitch;} + bool IsNotObstructed(void) const {return mFlags & _sound_cannot_be_obstructed;} + bool IsNotMediaObstructed(void) const {return mFlags & _sound_cannot_be_media_obstructed;} + bool IsAmbient(void) const {return mFlags & _sound_is_ambient;} + + short GetChance(void) const; + + float GetLowPitch(void) const {return mLowPitch;} + float GetHighPitch(void) const {return mHighPitch;} + + void SetSoundCode(short s) {mSoundCode = s;} + void SetBehaviorIndex(int i) {mBehaviorIndex = i;} + + void SetNotRestartable(bool f) {mFlags |= _sound_cannot_be_restarted;} + void SetNotSelfAbortable(bool f) {mFlags |= _sound_does_not_self_abort;} + void SetPitchChangeResistant(bool b) {mFlags |= _sound_resists_pitch_changes;} + void SetNotPitchChangeable(bool b) {mFlags |= _sound_cannot_change_pitch;} + void SetNotObstructed(bool b) {mFlags |= _sound_cannot_be_obstructed;} + void SetNotMediaObstructed(bool b) {mFlags |= _sound_cannot_be_media_obstructed;} + void SetAmbient(bool b) {mFlags |= _sound_is_ambient;} + + void SetChance(short i); + + void SetLowPitch(int p) {mLowPitch = p;} + void SetHighPitch(int p) {mHighPitch = p;} + + unsigned int GetPermutationCount(void) const {return mSounds.size();} + void DeletePermutation(unsigned int permutation_index); + AppleSoundHeader* GetPermutation(unsigned int permutation_index); + AppleSoundHeader* NewPermutation(wxString path); + + // Utilities + unsigned int GetSizeInFile(void); + BigEndianBuffer& SaveObject(BigEndianBuffer& buffer, unsigned int& offset); + BigEndianBuffer& LoadObject(BigEndianBuffer& buffer); +}; + +#endif + diff --git a/Sounds/SoundsView.cpp b/Sounds/SoundsView.cpp new file mode 100644 index 0000000..f4ea028 --- /dev/null +++ b/Sounds/SoundsView.cpp @@ -0,0 +1,582 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/wfstream.h" + +#include "../ShapeFusionApp.h" +#include "../ShapeFusionMenus.h" +#include "../DefaultNames.h" +#include "SoundsView.h" + +BEGIN_EVENT_TABLE(SoundsView, wxView) + EVT_LISTBOX(SOUND_CLASS_LIST, SoundsView::SoundClassChanged) + EVT_TEXT(SOUND_CLASS_ID_FIELD, SoundsView::SoundClassIdChanged) + EVT_RADIOBOX(SOUND_VOLUME_RADIO_BUTTON, SoundsView::VolumeButtonChanged) + EVT_CHOICE(SOUND_CHANCE_MENU, SoundsView::ChanceMenuChanged) + EVT_CHECKBOX(SOUND_FLAGS_RESTART, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_ABORT, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_RESIST, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_CHANGE, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_OBSTRUCTED, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_MOBSTRUCTED, SoundsView::FlagsChanged) + EVT_CHECKBOX(SOUND_FLAGS_AMBIENT, SoundsView::FlagsChanged) + EVT_LISTBOX(SOUND_EIGHT_BIT_PERMUTATIONS_LIST, SoundsView::SoundPermutationSelected) + EVT_LISTBOX(SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST, SoundsView::SoundPermutationSelected) + EVT_LISTBOX_DCLICK(SOUND_EIGHT_BIT_PERMUTATIONS_LIST, SoundsView::SoundPermutationDoubleClicked) + EVT_LISTBOX_DCLICK(SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST, SoundsView::SoundPermutationDoubleClicked) + EVT_MENU(EDIT_MENU_DELETE, SoundsView::MenuDelete) + EVT_MENU(SOUNDS_MENU_ADDCLASS, SoundsView::MenuAddSoundClass) + EVT_MENU(SOUNDS_MENU_EXPORT, SoundsView::MenuExportSound) + EVT_MENU(SOUNDS_MENU_IMPORT, SoundsView::MenuImportSound) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(SoundsView, wxView) + +SoundsView::SoundsView(): mSoundClass(wxNOT_FOUND), mSoundSource(wxNOT_FOUND), mSoundPermutation(wxNOT_FOUND) +{ + frame = NULL; + menubar = NULL; + payload = NULL; +} + +// What to do when a view is created. Creates actual +// windows for displaying the view. +bool SoundsView::OnCreate(wxDocument *doc, long WXUNUSED(flags)) +{ + wxString frameTitle = _T("ShapeFusion : Sounds : "); + + frameTitle.Append(doc->GetFilename()); + + frame = wxGetApp().CreateChildFrame(doc, this, frameTitle, wxPoint(0, 0), wxSize(600, 400), wxDEFAULT_FRAME_STYLE);// & ~ (wxRESIZE_BORDER | wxRESIZE_BOX | wxMAXIMIZE_BOX)); + + payload = (SoundsDocument*)doc; + + menubar = frame->GetMenuBar(); + CreateSoundsMenu(menubar); + + // Because we can always add sound classes + menubar->Enable(SOUNDS_MENU_ADDCLASS, true); + + wxString volume_labels[] = { wxT("Soft"), wxT("Medium"), wxT("Loud") }; + wxString chances_labels[] = { wxT("100%"), wxT("90%"), wxT("80%"), wxT("70%"), wxT("60%"), wxT("50%"), wxT("40%"), wxT("30%"), wxT("20%"), wxT("10%") }; + + main_panel = new wxPanel(frame); + main_panel->Show(); + + sound_class_text = new wxStaticText(main_panel, wxID_ANY, wxT("Sound classes: ")); + sound_class_id_text = new wxStaticText(main_panel, wxID_ANY, wxT("Class ID: ")); + sound_class_id_field = new wxTextCtrl(main_panel, SOUND_CLASS_ID_FIELD, wxT("")); + + sound_class_number_text = new wxStaticText(main_panel, wxID_ANY, wxT("Class number: ")); + sound_class_number_field = new wxStaticText(main_panel, SOUND_CLASS_NUMBER_FIELD, wxT("")); + + sound_class_list = new wxListBox(main_panel, (wxWindowID)SOUND_CLASS_LIST); + + sound_flag_restart_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_RESTART, wxT("Cannot be restarted")); + sound_flag_abort_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_ABORT, wxT("Does not self-abort")); + sound_flag_resist_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_RESIST, wxT("Resists pitch changes")); + sound_flag_change_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_CHANGE, wxT("Can't change pitch")); + sound_flag_obstructed_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_OBSTRUCTED, wxT("Can't be obstructed")); + sound_flag_mobstructed_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_MOBSTRUCTED, wxT("Can't be media obstructed")); + sound_flag_ambient_checkbox = new wxCheckBox(main_panel, SOUND_FLAGS_AMBIENT, wxT("Is ambient")); + + sound_volume_radio_button = new wxRadioBox(main_panel, SOUND_VOLUME_RADIO_BUTTON, wxT("Volume"), wxDefaultPosition, wxDefaultSize, 3, volume_labels, 3, wxRA_SPECIFY_COLS); + + sound_chance_text = new wxStaticText(main_panel, wxID_ANY, wxT("Chance: ")); + sound_chance_menu = new wxChoice(main_panel, SOUND_CHANCE_MENU, wxDefaultPosition, wxDefaultSize, 10, chances_labels); + + sound_low_pitch_text = new wxStaticText(main_panel, wxID_ANY, wxT("Low pitch: ")); + sound_low_pitch_field = new wxTextCtrl(main_panel, SOUND_LOW_PITCH_FIELD); + sound_high_pitch_text = new wxStaticText(main_panel, wxID_ANY, wxT("High pitch: ")); + sound_high_pitch_field = new wxTextCtrl(main_panel, SOUND_HIGH_PITCH_FIELD); + + sound_eight_bit_text = new wxStaticText(main_panel, wxID_ANY, wxT("8-bit sounds:")); + sound_eight_bit_list = new wxListBox(main_panel, (wxWindowID)SOUND_EIGHT_BIT_PERMUTATIONS_LIST); + + sound_sixteen_bit_text = new wxStaticText(main_panel, wxID_ANY, wxT("16-bit sounds: ")); + sound_sixteen_bit_list = new wxListBox(main_panel, (wxWindowID)SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST); + + sound_remap_check_box = new wxCheckBox(main_panel, SOUND_REMAP_CHECK_BOX, wxT("Remap 8-bit")); + + frame_sizer = new wxBoxSizer(wxHORIZONTAL); + sound_class_sizer = new wxBoxSizer(wxVERTICAL); + sound_class_header_sizer = new wxFlexGridSizer(2, 2, 0, 0); + sound_editor_sizer = new wxBoxSizer(wxVERTICAL); + sound_flags_sizer = new wxStaticBoxSizer(wxVERTICAL, main_panel, wxT("Flags")); + sound_menus_sizer = new wxFlexGridSizer(2, 3, 0, 0); + sound_permutation_sizer = new wxBoxSizer(wxHORIZONTAL); + sound_eight_bit_sizer = new wxBoxSizer(wxVERTICAL); + sound_sixteen_bit_sizer = new wxBoxSizer(wxVERTICAL); + + sound_class_header_sizer->Add(sound_class_id_text, 0, wxALIGN_CENTER_VERTICAL, 0); + sound_class_header_sizer->Add(sound_class_id_field, 0, 0, 0); + sound_class_header_sizer->Add(sound_class_number_text, 0, wxALIGN_CENTER_VERTICAL, 0); + sound_class_header_sizer->Add(sound_class_number_field, 0, 0, 0); + + sound_class_sizer->Add(sound_class_text, 0, 0, 0); + sound_class_sizer->Add(sound_class_header_sizer, 0, 0, 0); + sound_class_sizer->Add(sound_class_list, 1, wxEXPAND, 0); + + sound_flags_sizer->Add(sound_flag_restart_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_abort_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_resist_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_change_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_obstructed_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_mobstructed_checkbox, 0, 0, 0); + sound_flags_sizer->Add(sound_flag_ambient_checkbox, 0, 0, 0); + + sound_menus_sizer->Add(sound_chance_text, 0, wxALIGN_CENTER_VERTICAL, 0); + sound_menus_sizer->Add(sound_chance_menu, 0, 0, 0); + sound_menus_sizer->Add(sound_low_pitch_text, 0, wxALIGN_CENTER_VERTICAL, 0); + sound_menus_sizer->Add(sound_low_pitch_field, 0, 0, 0); + sound_menus_sizer->Add(sound_high_pitch_text, 0, wxALIGN_CENTER_VERTICAL, 0); + sound_menus_sizer->Add(sound_high_pitch_field, 0, 0, 0); + + sound_eight_bit_sizer->Add(sound_eight_bit_text, 0, 0, 0); + sound_eight_bit_sizer->Add(sound_eight_bit_list, 1, wxEXPAND | wxRIGHT, 5); + sound_sixteen_bit_sizer->Add(sound_sixteen_bit_text, 0, 0, 0); + sound_sixteen_bit_sizer->Add(sound_sixteen_bit_list, 1, wxEXPAND, 0); + sound_sixteen_bit_sizer->Add(sound_remap_check_box, 0, 0, 0); + + sound_permutation_sizer->Add(sound_eight_bit_sizer, 1, wxEXPAND, 0); + sound_permutation_sizer->Add(sound_sixteen_bit_sizer, 1, wxEXPAND, 0); + + sound_editor_sizer->Add(sound_flags_sizer, 0, 0, 0); + sound_editor_sizer->AddSpacer(1); + sound_editor_sizer->Add(sound_volume_radio_button, 0, 0, 0); + sound_editor_sizer->AddSpacer(1); + sound_editor_sizer->Add(sound_menus_sizer, 0, 0, 0); + sound_editor_sizer->AddSpacer(5); + sound_editor_sizer->Add(sound_permutation_sizer, 1, wxEXPAND, 0); + + frame_sizer->Add(sound_class_sizer, 0, wxEXPAND | wxALL, 5); + frame_sizer->AddSpacer(5); + frame_sizer->Add(sound_editor_sizer, 0, wxEXPAND | wxALL, 5); + + main_panel->SetSizer(frame_sizer); + frame_sizer->Layout(); + frame_sizer->SetSizeHints(frame); + + frame->Show(true); +#ifdef __X__ + // X seems to require a forced resize + int x, y; + frame->GetSize(&x, &y); + frame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y); +#endif + + return true; +} + +// Sneakily gets used for default print/preview +// as well as drawing on the screen. +void SoundsView::OnDraw(wxDC *dc) +{ +} + +void SoundsView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint)) +{ + bool gequals = true; + + sound_class_list->Clear(); + for (unsigned int i = 0; i < payload->GetSoundCount(); i++) { + sound_class_list->Append(GetName(wxT("sound"), i)); + // We check if there is a difference between 8-bit and 16-bit + // SoundsDefinitions + SoundsDefinition *def8 = payload->Get8BitSoundDefinition(i), + *def16 = payload->Get16BitSoundDefinition(i); + bool equals = false; + + if (def8 != NULL && def16 != NULL) + equals = def8->HaveSameAttributesAs(*def16); + else if (def8 == NULL && def16 == NULL) + equals = true; + + if (!equals) + wxLogDebug(wxT("Sound source different at %d"), i); + gequals = gequals && equals; + } + if (!gequals) { + // FIXME : Update this when we have a "complete" editor... + wxMessageDialog msg(frame, + wxT("It seems 8-bit and 16-bit versions of some of this Sound file " + "sounds have differences. This editor will replace 16-bit sounds " + "flags with those from 8-bit sounds, to ensure consistency. " + "If you really need to be able to change 16-bit flags independently, " + "please file a feature request."), + wxT("Warning !"), wxOK | wxICON_WARNING); + + msg.ShowModal(); + } + Update(); +} + +void SoundsView::Update(void) +{ + // We disable our menuitems, in case selection is invalid + menubar->Enable(SOUNDS_MENU_IMPORT, false); + menubar->Enable(SOUNDS_MENU_EXPORT, false); + menubar->Enable(EDIT_MENU_DELETE, false); + + if (sound_class_list->GetCount() == 0) { + // There is no sound class + // We cannot have a selection + mSoundPermutation = wxNOT_FOUND; + mSoundSource = wxNOT_FOUND; + + } else { + // We have a sound class + + // Make sure we always have something selected + mSoundClass = sound_class_list->GetSelection(); + if (mSoundClass == wxNOT_FOUND) { + wxLogDebug(wxT("[SoundsView] There is no sound selected. Selecting first item...")); + sound_class_list->SetSelection(0); + mSoundClass = sound_class_list->GetSelection(); + } + + // We build the permutations listbox + sound_eight_bit_list->Clear(); + sound_sixteen_bit_list->Clear(); + + SoundsDefinition *def = payload->Get8BitSoundDefinition(mSoundClass); + if (def) { + for (unsigned int i = 0; i < def->GetPermutationCount(); i++) { + sound_eight_bit_list->Append(wxString::Format(wxT("%d"), def->GetPermutation(i)->Size())); + } + } + + def = payload->Get16BitSoundDefinition(mSoundClass); + if (def) { + for (unsigned int i = 0; i < def->GetPermutationCount(); i++) { + sound_sixteen_bit_list->Append(wxString::Format(wxT("%d"), def->GetPermutation(i)->Size())); + } + } + + // As soon as we have a sound class selected, we can + // - import a sound into it + // - delete it + menubar->Enable(SOUNDS_MENU_IMPORT, true); + menubar->Enable(EDIT_MENU_DELETE, true); + + if (payload->Get8BitSoundDefinition(mSoundClass)->GetPermutationCount() != 0) { + // There is 8-bit sounds, we select first + mSoundSource = 0; + mSoundPermutation = 0; + sound_eight_bit_list->SetSelection(0); + // We deselect 16-bit list + sound_sixteen_bit_list->SetSelection(wxNOT_FOUND); + } else { + // There is no 8-bit sounds + if (payload->Get16BitSoundDefinition(mSoundClass)->GetPermutationCount() != 0) { + // We have 16-bit sounds, we select this one... + mSoundSource = 1; + mSoundPermutation = 0; + sound_sixteen_bit_list->SetSelection(0); + // We deselect 8-bit list + sound_eight_bit_list->SetSelection(wxNOT_FOUND); + } else { + // There is neither 8-bit nor 16-bit sounds, don't select anything + sound_eight_bit_list->SetSelection(wxNOT_FOUND); + sound_sixteen_bit_list->SetSelection(wxNOT_FOUND); + mSoundSource = wxNOT_FOUND; + mSoundPermutation = wxNOT_FOUND; + } + } + + // We enable this, our selection is valid... + menubar->Enable(SOUNDS_MENU_EXPORT, true); + + def = payload->Get8BitSoundDefinition(mSoundClass); + + sound_class_number_field->SetLabel(wxString::Format(wxT("%d"), mSoundClass)); + sound_class_id_field->ChangeValue(wxString::Format(wxT("%d"), def->GetSoundCode())); + + sound_volume_radio_button->SetSelection(def->GetBehaviorIndex()); + sound_chance_menu->SetSelection(def->GetChance()); + + sound_flag_restart_checkbox->SetValue(def->IsNotRestartable()); + sound_flag_abort_checkbox->SetValue(def->IsNotSelfAbortable()); + sound_flag_resist_checkbox->SetValue(def->IsPitchChangeResistant()); + sound_flag_change_checkbox->SetValue(def->IsNotPitchChangeable()); + sound_flag_obstructed_checkbox->SetValue(def->IsNotObstructed()); + sound_flag_mobstructed_checkbox->SetValue(def->IsNotMediaObstructed()); + sound_flag_ambient_checkbox->SetValue(def->IsAmbient()); + sound_low_pitch_field->ChangeValue(wxString::Format(wxT("%g"), def->GetLowPitch())); + sound_high_pitch_field->ChangeValue(wxString::Format(wxT("%g"), def->GetHighPitch())); + } +} + +// Clean up windows used for displaying the view. +bool SoundsView::OnClose(bool deleteWindow) +{ + if (!GetDocument()->Close()) + return false; + SetFrame((wxFrame *) NULL); + Activate(false); + if (deleteWindow) { + delete frame; + return true; + } + return true; +} + +void SoundsView::SoundClassChanged(wxCommandEvent &e) +{ + Update(); +} + +void SoundsView::SoundClassIdChanged(wxCommandEvent& e) +{ + long v; + if (e.GetString().ToLong(&v)) + { + SoundsDefinition* def = payload->Get8BitSoundDefinition(mSoundClass); + def->SetSoundCode(v); + + def = payload->Get16BitSoundDefinition(mSoundClass); + def->SetSoundCode(v); + } + GetDocument()->Modify(true); +} + +void SoundsView::VolumeButtonChanged(wxCommandEvent &e) +{ + SoundsDefinition *def = payload->Get8BitSoundDefinition(mSoundClass); + def->SetBehaviorIndex(sound_volume_radio_button->GetSelection()); + + def = payload->Get16BitSoundDefinition(mSoundClass); + def->SetBehaviorIndex(sound_volume_radio_button->GetSelection()); + GetDocument()->Modify(true); +} + +void SoundsView::ChanceMenuChanged(wxCommandEvent &e) +{ + SoundsDefinition *def = payload->Get8BitSoundDefinition(mSoundClass); + def->SetChance(sound_chance_menu->GetSelection()); + + def = payload->Get16BitSoundDefinition(mSoundClass); + def->SetChance(sound_chance_menu->GetSelection()); + GetDocument()->Modify(true); +} + +void SoundsView::FlagsChanged(wxCommandEvent &e) +{ + SoundsDefinition *def8 = payload->Get8BitSoundDefinition(mSoundClass); + SoundsDefinition *def16 = payload->Get16BitSoundDefinition(mSoundClass); + switch (e.GetId()) { + case SOUND_FLAGS_RESTART: + def8->SetNotRestartable(e.IsChecked()); + def16->SetNotRestartable(e.IsChecked()); + break; + case SOUND_FLAGS_ABORT: + def8->SetNotSelfAbortable(e.IsChecked()); + def16->SetNotSelfAbortable(e.IsChecked()); + break; + case SOUND_FLAGS_RESIST: + def8->SetPitchChangeResistant(e.IsChecked()); + def16->SetPitchChangeResistant(e.IsChecked()); + break; + case SOUND_FLAGS_CHANGE: + def8->SetNotPitchChangeable(e.IsChecked()); + def16->SetNotPitchChangeable(e.IsChecked()); + break; + case SOUND_FLAGS_OBSTRUCTED: + def8->SetNotObstructed(e.IsChecked()); + def16->SetNotObstructed(e.IsChecked()); + break; + case SOUND_FLAGS_MOBSTRUCTED: + def8->SetNotMediaObstructed(e.IsChecked()); + def16->SetNotMediaObstructed(e.IsChecked()); + break; + case SOUND_FLAGS_AMBIENT: + def8->SetAmbient(e.IsChecked()); + def16->SetAmbient(e.IsChecked()); + break; + default: + wxLogDebug(wxT("Invalid control id in FlagsChanged")); + break; + } + GetDocument()->Modify(true); +} + +void SoundsView::LowPitchValueChanged(wxScrollEvent &e) +{ + long int l; + + sound_low_pitch_field->GetValue().ToLong(&l); + + SoundsDefinition *def = payload->Get8BitSoundDefinition(mSoundClass); + def->SetLowPitch(l); + + def = payload->Get16BitSoundDefinition(mSoundClass); + def->SetLowPitch(l); + GetDocument()->Modify(true); +} + +void SoundsView::HighPitchValueChanged(wxScrollEvent &e) +{ + long int l; + + sound_high_pitch_field->GetValue().ToLong(&l); + + SoundsDefinition *def = payload->Get8BitSoundDefinition(mSoundClass); + def->SetHighPitch(l); + + def = payload->Get16BitSoundDefinition(mSoundClass); + def->SetHighPitch(l); + GetDocument()->Modify(true); +} + +void SoundsView::MenuDelete(wxCommandEvent &e) +{ + wxWindow *win = sound_class_list->FindFocus(); + + switch (win->GetId()) { + case SOUND_CLASS_LIST: + wxLogDebug(wxT("Delete Sound Class")); + break; + case SOUND_EIGHT_BIT_PERMUTATIONS_LIST: + case SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST: + { + if (mSoundClass == wxNOT_FOUND || mSoundSource == wxNOT_FOUND || mSoundPermutation == wxNOT_FOUND) { + return; + } + + SoundsDefinition* def = payload->GetSoundDefinition(mSoundSource, mSoundClass); + def->DeletePermutation(mSoundPermutation); + Update(); + GetDocument()->Modify(true); + break; + } + default: + break; + } +} + +void SoundsView::MenuAddSoundClass(wxCommandEvent &e) +{ + wxLogDebug(wxT("Adding an item")); + payload->AddSoundDefinition(); + + // We add the new Sound class item by hand + sound_class_list->Append(wxString::Format(wxT("Sound %d"), sound_class_list->GetCount())); + + GetDocument()->Modify(true); + + Update(); +} + +void SoundsView::MenuImportSound(wxCommandEvent &e) +{ + wxWindow* w = wxWindow::FindFocus(); + SoundsDefinition* definition = 0; + if (w == static_cast(sound_sixteen_bit_list)) { + definition = payload->Get16BitSoundDefinition(mSoundClass); + } else if (w == static_cast(sound_eight_bit_list)) { + definition = payload->Get8BitSoundDefinition(mSoundClass); + } else { + wxMessageDialog msg(frame, wxT("Sorry, you need to select a sound class and 8-bit or 16-bit to import a sound"), wxT("Error: No selection"), wxOK | wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + + if (definition->GetPermutationCount() >= MAXIMUM_PERMUTATIONS_PER_SOUND) { + wxMessageDialog msg(frame, wxT("There are already five permutations for this sound"), wxT("Error: permutation limit reached"), wxOK | wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + + wxFileDialog dlg(frame, wxT("Choose a sound file to add"), wxT(""), wxT(""), wxT("Common sound files (AIFF, WAV)|*.aif;*.wav"), wxOPEN); + if (dlg.ShowModal() == wxID_OK) { + if (definition->NewPermutation(dlg.GetPath()) == NULL) { + wxMessageDialog msg(frame, wxT("Error importing sound"), wxT("Error"), wxOK | wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + } + + GetDocument()->Modify(true); + + Update(); +} + +void SoundsView::MenuExportSound(wxCommandEvent &e) +{ + if (mSoundClass == wxNOT_FOUND || mSoundSource == wxNOT_FOUND || mSoundPermutation == wxNOT_FOUND) { + wxMessageDialog msg(frame, wxT("Sorry, you need to select a sound class and a permutation to export a sound"), wxT("Error : No selection"), wxOK | wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + + wxFileDialog dlg(frame, wxT("Choose a file name :"), wxT(""), wxString::Format(wxT("Sound %d-%d.wav"), mSoundClass, mSoundPermutation), wxT("WAV files (*.wav)|*.wav|AIFF files (*.aif)|*.aif"), wxSAVE | wxOVERWRITE_PROMPT); + + if (dlg.ShowModal() == wxID_OK) { + SoundsDefinition *def = payload->GetSoundDefinition(mSoundSource, mSoundClass); + AppleSoundHeader *sound = def->GetPermutation(mSoundPermutation); + bool result = false; + + switch (dlg.GetFilterIndex()) { + case 0: // Selected *.wav + result = sound->SaveToWave(dlg.GetPath()); + break; + case 1: // Selected *.aif + result = sound->SaveToAiff(dlg.GetPath()); + break; + default: + break; + } + + if (!result) + wxLogDebug(wxT("[SoundsView] Error exporting sound")); + } +} + +void SoundsView::SoundPermutationSelected(wxCommandEvent &e) +{ + // We unselect the other permutation field + if (e.GetId() == SOUND_EIGHT_BIT_PERMUTATIONS_LIST) { + wxLogDebug(wxT("Selected 8-bit")); + sound_sixteen_bit_list->SetSelection(wxNOT_FOUND); + mSoundSource = 0; + mSoundPermutation = sound_eight_bit_list->GetSelection(); + } else if (e.GetId() == SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST) { + wxLogDebug(wxT("Selected 16-bit")); + sound_eight_bit_list->SetSelection(wxNOT_FOUND); + mSoundSource = 1; + mSoundPermutation = sound_sixteen_bit_list->GetSelection(); + } +} + +void SoundsView::SoundPermutationDoubleClicked(wxCommandEvent &e) +{ + SoundsDefinition *def = payload->GetSoundDefinition(mSoundSource, mSoundClass); + def->GetPermutation(mSoundPermutation)->PlaySound(); +} + diff --git a/Sounds/SoundsView.h b/Sounds/SoundsView.h new file mode 100644 index 0000000..6f9ec59 --- /dev/null +++ b/Sounds/SoundsView.h @@ -0,0 +1,128 @@ +/* + * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton) + * + * ShapeFusion 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. + * + * ShapeFusion 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 ShapeFusion; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __SOUNDSVIEW_H__ +#define __SOUNDSVIEW_H__ + +#include "wx/docview.h" +#include "SoundsDocument.h" + +class SoundsView: public wxView +{ + DECLARE_DYNAMIC_CLASS(SoundsView) +private: + // control ids + enum { + SOUND_CLASS_ID_FIELD, + SOUND_CLASS_NUMBER_FIELD, + SOUND_CLASS_LIST, + SOUND_FLAGS_RESTART, + SOUND_FLAGS_ABORT, + SOUND_FLAGS_RESIST, + SOUND_FLAGS_CHANGE, + SOUND_FLAGS_OBSTRUCTED, + SOUND_FLAGS_MOBSTRUCTED, + SOUND_FLAGS_AMBIENT, + SOUND_VOLUME_RADIO_BUTTON, + SOUND_CHANCE_MENU, + SOUND_LOW_PITCH_FIELD, + SOUND_HIGH_PITCH_FIELD, + SOUND_EIGHT_BIT_PERMUTATIONS_LIST, + SOUND_SIXTEEN_BIT_PERMUTATIONS_LIST, + SOUND_REMAP_CHECK_BOX + }; + + wxBoxSizer *frame_sizer; + wxPanel *main_panel; + wxSizer *sound_class_sizer; + wxSizer *sound_class_header_sizer; + wxStaticText *sound_class_text; + wxStaticText *sound_class_id_text; + wxTextCtrl *sound_class_id_field; + wxStaticText *sound_class_number_text; + wxStaticText *sound_class_number_field; + wxListBox *sound_class_list; + wxSizer *sound_editor_sizer; + wxSizer *sound_flags_sizer; + wxCheckBox *sound_flag_restart_checkbox; + wxCheckBox *sound_flag_abort_checkbox; + wxCheckBox *sound_flag_resist_checkbox; + wxCheckBox *sound_flag_change_checkbox; + wxCheckBox *sound_flag_obstructed_checkbox; + wxCheckBox *sound_flag_mobstructed_checkbox; + wxCheckBox *sound_flag_ambient_checkbox; + wxRadioBox *sound_volume_radio_button; + wxSizer *sound_menus_sizer; + wxStaticText *sound_chance_text; + wxChoice *sound_chance_menu; + wxStaticText *sound_low_pitch_text; + wxTextCtrl *sound_low_pitch_field; + wxStaticText *sound_high_pitch_text; + wxTextCtrl *sound_high_pitch_field; + wxSizer *sound_permutation_sizer; + wxSizer *sound_eight_bit_sizer; + wxStaticText *sound_eight_bit_text; + wxListBox *sound_eight_bit_list; + wxSizer *sound_sixteen_bit_sizer; + wxStaticText *sound_sixteen_bit_text; + wxListBox *sound_sixteen_bit_list; + wxCheckBox *sound_remap_check_box; + + wxFrame *frame; + wxMenuBar *menubar; + SoundsDocument *payload; + int mSoundClass, + mSoundSource, + mSoundPermutation; + +public: + SoundsView(void); + ~SoundsView(void) {}; + + bool OnCreate(wxDocument *doc, long flags); + void OnDraw(wxDC *dc); + void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL); + bool OnClose(bool deleteWindow = true); + + void Update(void); + + void SoundClassChanged(wxCommandEvent &e); + void SoundClassIdChanged(wxCommandEvent& e); + void AddSound(wxCommandEvent &e); + void RemoveSound(wxCommandEvent &e); + void SourceRadioButtonChanged(wxCommandEvent &e); + void VolumeButtonChanged(wxCommandEvent &e); + void ChanceMenuChanged(wxCommandEvent &e); + void FlagsChanged(wxCommandEvent &e); + void LowPitchValueChanged(wxScrollEvent &e); + void HighPitchValueChanged(wxScrollEvent &e); + void SoundPermutationSelected(wxCommandEvent &e); + void SoundPermutationDoubleClicked(wxCommandEvent &e); + + // Menu events + void MenuDelete(wxCommandEvent &e); + void MenuAddSoundClass(wxCommandEvent &e); + void MenuImportSound(wxCommandEvent &e); + void MenuExportSound(wxCommandEvent &e); + + void ExportSound(wxString filepath); + +protected: + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..db11b60 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,2202 @@ +# generated automatically by aclocal 1.11.2 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant . +# +# 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. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [$4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES + +dnl --------------------------------------------------------------------------- +dnl Author: wxWidgets development team, +dnl Francesco Montorsi, +dnl Bob McCown (Mac-testing) +dnl Creation date: 24/11/2001 +dnl RCS-ID: $Id$ +dnl --------------------------------------------------------------------------- + +dnl =========================================================================== +dnl Table of Contents of this macro file: +dnl ------------------------------------- +dnl +dnl SECTION A: wxWidgets main macros +dnl - WX_CONFIG_OPTIONS +dnl - WX_CONFIG_CHECK +dnl - WXRC_CHECK +dnl - WX_STANDARD_OPTIONS +dnl - WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl - WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl SECTION B: wxWidgets-related utilities +dnl - WX_LIKE_LIBNAME +dnl - WX_ARG_ENABLE_YESNOAUTO +dnl - WX_ARG_WITH_YESNOAUTO +dnl +dnl SECTION C: messages to the user +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl - WX_BOOLOPT_SUMMARY +dnl +dnl The special "WX_DEBUG_CONFIGURE" variable can be set to 1 to enable extra +dnl debug output on stdout from these macros. +dnl =========================================================================== + + +dnl --------------------------------------------------------------------------- +dnl Macros for wxWidgets detection. Typically used in configure.in as: +dnl +dnl AC_ARG_ENABLE(...) +dnl AC_ARG_WITH(...) +dnl ... +dnl WX_CONFIG_OPTIONS +dnl ... +dnl ... +dnl WX_CONFIG_CHECK([2.6.0], [wxWin=1]) +dnl if test "$wxWin" != 1; then +dnl AC_MSG_ERROR([ +dnl wxWidgets must be installed on your system +dnl but wx-config script couldn't be found. +dnl +dnl Please check that wx-config is in path, the directory +dnl where wxWidgets libraries are installed (returned by +dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or +dnl equivalent variable and wxWidgets version is 2.3.4 or above. +dnl ]) +dnl fi +dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +dnl +dnl LIBS="$LIBS $WX_LIBS" +dnl +dnl If you want to support standard --enable-debug/unicode/shared options, you +dnl may do the following: +dnl +dnl ... +dnl AC_CANONICAL_SYSTEM +dnl +dnl # define configure options +dnl WX_CONFIG_OPTIONS +dnl WX_STANDARD_OPTIONS([debug,unicode,shared,toolkit,wxshared]) +dnl +dnl # basic configure checks +dnl ... +dnl +dnl # we want to always have DEBUG==WX_DEBUG and UNICODE==WX_UNICODE +dnl WX_DEBUG=$DEBUG +dnl WX_UNICODE=$UNICODE +dnl +dnl WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl WX_CONFIG_CHECK([2.8.0], [wxWin=1],,[html,core,net,base],[$WXCONFIG_FLAGS]) +dnl WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl # write the output files +dnl AC_CONFIG_FILES([Makefile ...]) +dnl AC_OUTPUT +dnl +dnl # optional: just to show a message to the user +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl +dnl --------------------------------------------------------------------------- + + +dnl --------------------------------------------------------------------------- +dnl WX_CONFIG_OPTIONS +dnl +dnl adds support for --wx-prefix, --wx-exec-prefix, --with-wxdir and +dnl --wx-config command line options +dnl --------------------------------------------------------------------------- + +AC_DEFUN([WX_CONFIG_OPTIONS], +[ + AC_ARG_WITH(wxdir, + [ --with-wxdir=PATH Use uninstalled version of wxWidgets in PATH], + [ wx_config_name="$withval/wx-config" + wx_config_args="--inplace"]) + AC_ARG_WITH(wx-config, + [ --with-wx-config=CONFIG wx-config script to use (optional)], + wx_config_name="$withval" ) + AC_ARG_WITH(wx-prefix, + [ --with-wx-prefix=PREFIX Prefix where wxWidgets is installed (optional)], + wx_config_prefix="$withval", wx_config_prefix="") + AC_ARG_WITH(wx-exec-prefix, + [ --with-wx-exec-prefix=PREFIX + Exec prefix where wxWidgets is installed (optional)], + wx_config_exec_prefix="$withval", wx_config_exec_prefix="") +]) + +dnl Helper macro for checking if wx version is at least $1.$2.$3, set's +dnl wx_ver_ok=yes if it is: +AC_DEFUN([_WX_PRIVATE_CHECK_VERSION], +[ + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt $1; then + wx_ver_ok=yes + else + if test $wx_config_major_version -eq $1; then + if test $wx_config_minor_version -gt $2; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq $2; then + if test $wx_config_micro_version -ge $3; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi +]) + +dnl --------------------------------------------------------------------------- +dnl WX_CONFIG_CHECK(VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND +dnl [, WX-LIBS [, ADDITIONAL-WX-CONFIG-FLAGS]]]]) +dnl +dnl Test for wxWidgets, and define WX_C*FLAGS, WX_LIBS and WX_LIBS_STATIC +dnl (the latter is for static linking against wxWidgets). Set WX_CONFIG_NAME +dnl environment variable to override the default name of the wx-config script +dnl to use. Set WX_CONFIG_PATH to specify the full path to wx-config - in this +dnl case the macro won't even waste time on tests for its existence. +dnl +dnl Optional WX-LIBS argument contains comma- or space-separated list of +dnl wxWidgets libraries to link against. If it is not specified then WX_LIBS +dnl and WX_LIBS_STATIC will contain flags to link with all of the core +dnl wxWidgets libraries. +dnl +dnl Optional ADDITIONAL-WX-CONFIG-FLAGS argument is appended to wx-config +dnl invocation command in present. It can be used to fine-tune lookup of +dnl best wxWidgets build available. +dnl +dnl Example use: +dnl WX_CONFIG_CHECK([2.6.0], [wxWin=1], [wxWin=0], [html,core,net] +dnl [--unicode --debug]) +dnl --------------------------------------------------------------------------- + +dnl +dnl Get the cflags and libraries from the wx-config script +dnl +AC_DEFUN([WX_CONFIG_CHECK], +[ + dnl do we have wx-config name: it can be wx-config or wxd-config or ... + if test x${WX_CONFIG_NAME+set} != xset ; then + WX_CONFIG_NAME=wx-config + fi + + if test "x$wx_config_name" != x ; then + WX_CONFIG_NAME="$wx_config_name" + fi + + dnl deal with optional prefixes + if test x$wx_config_exec_prefix != x ; then + wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix" + WX_LOOKUP_PATH="$wx_config_exec_prefix/bin" + fi + if test x$wx_config_prefix != x ; then + wx_config_args="$wx_config_args --prefix=$wx_config_prefix" + WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin" + fi + if test "$cross_compiling" = "yes"; then + wx_config_args="$wx_config_args --host=$host_alias" + fi + + dnl don't search the PATH if WX_CONFIG_NAME is absolute filename + if test -x "$WX_CONFIG_NAME" ; then + AC_MSG_CHECKING(for wx-config) + WX_CONFIG_PATH="$WX_CONFIG_NAME" + AC_MSG_RESULT($WX_CONFIG_PATH) + else + AC_PATH_PROG(WX_CONFIG_PATH, $WX_CONFIG_NAME, no, "$WX_LOOKUP_PATH:$PATH") + fi + + if test "$WX_CONFIG_PATH" != "no" ; then + WX_VERSION="" + + min_wx_version=ifelse([$1], ,2.2.1,$1) + if test -z "$5" ; then + AC_MSG_CHECKING([for wxWidgets version >= $min_wx_version]) + else + AC_MSG_CHECKING([for wxWidgets version >= $min_wx_version ($5)]) + fi + + dnl don't add the libraries ($4) to this variable as this would result in + dnl an error when it's used with --version below + WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args $5" + + WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` + wx_config_major_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + wx_config_minor_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + wx_config_micro_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + wx_requested_major_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + wx_requested_minor_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + wx_requested_micro_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + _WX_PRIVATE_CHECK_VERSION([$wx_requested_major_version], + [$wx_requested_minor_version], + [$wx_requested_micro_version]) + + if test -n "$wx_ver_ok"; then + AC_MSG_RESULT(yes (version $WX_VERSION)) + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs $4` + + dnl is this even still appropriate? --static is a real option now + dnl and WX_CONFIG_WITH_ARGS is likely to contain it if that is + dnl what the user actually wants, making this redundant at best. + dnl For now keep it in case anyone actually used it in the past. + AC_MSG_CHECKING([for wxWidgets static library]) + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs $4 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + + dnl starting with version 2.2.6 wx-config has --cppflags argument + wx_has_cppflags="" + if test $wx_config_major_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_minor_version -eq 2; then + if test $wx_config_micro_version -ge 6; then + wx_has_cppflags=yes + fi + fi + fi + fi + fi + + dnl starting with version 2.7.0 wx-config has --rescomp option + wx_has_rescomp="" + if test $wx_config_major_version -gt 2; then + wx_has_rescomp=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -ge 7; then + wx_has_rescomp=yes + fi + fi + fi + if test "x$wx_has_rescomp" = x ; then + dnl cannot give any useful info for resource compiler + WX_RESCOMP= + else + WX_RESCOMP=`$WX_CONFIG_WITH_ARGS --rescomp` + fi + + if test "x$wx_has_cppflags" = x ; then + dnl no choice but to define all flags like CFLAGS + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags $4` + WX_CPPFLAGS=$WX_CFLAGS + WX_CXXFLAGS=$WX_CFLAGS + + WX_CFLAGS_ONLY=$WX_CFLAGS + WX_CXXFLAGS_ONLY=$WX_CFLAGS + else + dnl we have CPPFLAGS included in CFLAGS included in CXXFLAGS + WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags $4` + WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags $4` + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags $4` + + WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"` + WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"` + fi + + ifelse([$2], , :, [$2]) + + else + + if test "x$WX_VERSION" = x; then + dnl no wx-config at all + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(no (version $WX_VERSION is not new enough)) + fi + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + if test ! -z "$5"; then + + wx_error_message=" + The configuration you asked for $PACKAGE_NAME requires a wxWidgets + build with the following settings: + $5 + but such build is not available. + + To see the wxWidgets builds available on this system, please use + 'wx-config --list' command. To use the default build, returned by + 'wx-config --selected-config', use the options with their 'auto' + default values." + + fi + + wx_error_message=" + The requested wxWidgets build couldn't be found. + $wx_error_message + + If you still get this error, then check that 'wx-config' is + in path, the directory where wxWidgets libraries are installed + (returned by 'wx-config --libs' command) is in LD_LIBRARY_PATH + or equivalent variable and wxWidgets version is $1 or above." + + ifelse([$3], , AC_MSG_ERROR([$wx_error_message]), [$3]) + + fi + else + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + ifelse([$3], , :, [$3]) + + fi + + AC_SUBST(WX_CPPFLAGS) + AC_SUBST(WX_CFLAGS) + AC_SUBST(WX_CXXFLAGS) + AC_SUBST(WX_CFLAGS_ONLY) + AC_SUBST(WX_CXXFLAGS_ONLY) + AC_SUBST(WX_LIBS) + AC_SUBST(WX_LIBS_STATIC) + AC_SUBST(WX_VERSION) + AC_SUBST(WX_RESCOMP) + + dnl need to export also WX_VERSION_MINOR and WX_VERSION_MAJOR symbols + dnl to support wxpresets bakefiles (we export also WX_VERSION_MICRO for completeness): + WX_VERSION_MAJOR="$wx_config_major_version" + WX_VERSION_MINOR="$wx_config_minor_version" + WX_VERSION_MICRO="$wx_config_micro_version" + AC_SUBST(WX_VERSION_MAJOR) + AC_SUBST(WX_VERSION_MINOR) + AC_SUBST(WX_VERSION_MICRO) +]) + +dnl --------------------------------------------------------------------------- +dnl Get information on the wxrc program for making C++, Python and xrs +dnl resource files. +dnl +dnl AC_ARG_ENABLE(...) +dnl AC_ARG_WITH(...) +dnl ... +dnl WX_CONFIG_OPTIONS +dnl ... +dnl WX_CONFIG_CHECK(2.6.0, wxWin=1) +dnl if test "$wxWin" != 1; then +dnl AC_MSG_ERROR([ +dnl wxWidgets must be installed on your system +dnl but wx-config script couldn't be found. +dnl +dnl Please check that wx-config is in path, the directory +dnl where wxWidgets libraries are installed (returned by +dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or +dnl equivalent variable and wxWidgets version is 2.6.0 or above. +dnl ]) +dnl fi +dnl +dnl WXRC_CHECK([HAVE_WXRC=1], [HAVE_WXRC=0]) +dnl if test "x$HAVE_WXRC" != x1; then +dnl AC_MSG_ERROR([ +dnl The wxrc program was not installed or not found. +dnl +dnl Please check the wxWidgets installation. +dnl ]) +dnl fi +dnl +dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +dnl +dnl LDFLAGS="$LDFLAGS $WX_LIBS" +dnl --------------------------------------------------------------------------- + +dnl --------------------------------------------------------------------------- +dnl WXRC_CHECK([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +dnl Test for wxWidgets' wxrc program for creating either C++, Python or XRS +dnl resources. The variable WXRC will be set and substituted in the configure +dnl script and Makefiles. +dnl +dnl Example use: +dnl WXRC_CHECK([wxrc=1], [wxrc=0]) +dnl --------------------------------------------------------------------------- + +dnl +dnl wxrc program from the wx-config script +dnl +AC_DEFUN([WXRC_CHECK], +[ + AC_ARG_VAR([WXRC], [Path to wxWidget's wxrc resource compiler]) + + if test "x$WX_CONFIG_NAME" = x; then + AC_MSG_ERROR([The wxrc tests must run after wxWidgets test.]) + else + + AC_MSG_CHECKING([for wxrc]) + + if test "x$WXRC" = x ; then + dnl wx-config --utility is a new addition to wxWidgets: + _WX_PRIVATE_CHECK_VERSION(2,5,3) + if test -n "$wx_ver_ok"; then + WXRC=`$WX_CONFIG_WITH_ARGS --utility=wxrc` + fi + fi + + if test "x$WXRC" = x ; then + AC_MSG_RESULT([not found]) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT([$WXRC]) + ifelse([$1], , :, [$1]) + fi + + AC_SUBST(WXRC) + fi +]) + +dnl --------------------------------------------------------------------------- +dnl WX_LIKE_LIBNAME([output-var] [prefix], [name]) +dnl +dnl Sets the "output-var" variable to the name of a library named with same +dnl wxWidgets rule. +dnl E.g. for output-var=='lib', name=='test', prefix='mine', sets +dnl the $lib variable to: +dnl 'mine_gtk2ud_test-2.8' +dnl if WX_PORT=gtk2, WX_UNICODE=1, WX_DEBUG=1 and WX_RELEASE=28 +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_LIKE_LIBNAME], + [ + wx_temp="$2""_""$WX_PORT" + + dnl add the [u][d] string + if test "$WX_UNICODE" = "1"; then + wx_temp="$wx_temp""u" + fi + if test "$WX_DEBUG" = "1"; then + wx_temp="$wx_temp""d" + fi + + dnl complete the name of the lib + wx_temp="$wx_temp""_""$3""-$WX_VERSION_MAJOR.$WX_VERSION_MINOR" + + dnl save it in the user's variable + $1=$wx_temp + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_ARG_ENABLE_YESNOAUTO/WX_ARG_WITH_YESNOAUTO +dnl +dnl Two little custom macros which define the ENABLE/WITH configure arguments. +dnl Macro arguments: +dnl $1 = the name of the --enable / --with feature +dnl $2 = the name of the variable associated +dnl $3 = the description of that feature +dnl $4 = the default value for that feature +dnl $5 = additional action to do in case option is given with "yes" value +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_ARG_ENABLE_YESNOAUTO], + [AC_ARG_ENABLE($1, + AC_HELP_STRING([--enable-$1], [$3 (default is $4)]), + [], [enableval="$4"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --enable-$1 option]) + if test "$enableval" = "yes" ; then + AC_MSG_RESULT([yes]) + $2=1 + $5 + elif test "$enableval" = "no" ; then + AC_MSG_RESULT([no]) + $2=0 + elif test "$enableval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + $2="auto" + else + AC_MSG_ERROR([ + Unrecognized option value (allowed values: yes, no, auto) + ]) + fi + ]) + +AC_DEFUN([WX_ARG_WITH_YESNOAUTO], + [AC_ARG_WITH($1, + AC_HELP_STRING([--with-$1], [$3 (default is $4)]), + [], [withval="$4"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-$1 option]) + if test "$withval" = "yes" ; then + AC_MSG_RESULT([yes]) + $2=1 + $5 + dnl NB: by default we don't allow --with-$1=no option + dnl since it does not make much sense ! + elif test "$6" = "1" -a "$withval" = "no" ; then + AC_MSG_RESULT([no]) + $2=0 + elif test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + $2="auto" + else + AC_MSG_ERROR([ + Unrecognized option value (allowed values: yes, auto) + ]) + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS([options-to-add]) +dnl +dnl Adds to the configure script one or more of the following options: +dnl --enable-[debug|unicode|shared|wxshared|wxdebug] +dnl --with-[gtk|msw|motif|x11|mac|mgl|dfb] +dnl --with-wxversion +dnl Then checks for their presence and eventually set the DEBUG, UNICODE, SHARED, +dnl PORT, WX_SHARED, WX_DEBUG, variables to one of the "yes", "no", "auto" values. +dnl +dnl Note that e.g. UNICODE != WX_UNICODE; the first is the value of the +dnl --enable-unicode option (in boolean format) while the second indicates +dnl if wxWidgets was built in Unicode mode (and still is in boolean format). +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS], + [ + + dnl the following lines will expand to WX_ARG_ENABLE_YESNOAUTO calls if and only if + dnl the $1 argument contains respectively the debug,unicode or shared options. + + dnl be careful here not to set debug flag if only "wxdebug" was specified + ifelse(regexp([$1], [\bdebug]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([debug], [DEBUG], [Build in debug mode], [auto])]) + + ifelse(index([$1], [unicode]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([unicode], [UNICODE], [Build in Unicode mode], [auto])]) + + ifelse(regexp([$1], [\bshared]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([shared], [SHARED], [Build as shared library], [auto])]) + + dnl WX_ARG_WITH_YESNOAUTO cannot be used for --with-toolkit since it's an option + dnl which must be able to accept the auto|gtk1|gtk2|msw|... values + ifelse(index([$1], [toolkit]), [-1],, + [ + AC_ARG_WITH([toolkit], + AC_HELP_STRING([--with-toolkit], + [Build against a specific wxWidgets toolkit (default is auto)]), + [], [withval="auto"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-toolkit option]) + if test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + TOOLKIT="auto" + else + TOOLKIT="$withval" + + dnl PORT must be one of the allowed values + if test "$TOOLKIT" != "gtk1" -a "$TOOLKIT" != "gtk2" -a \ + "$TOOLKIT" != "msw" -a "$TOOLKIT" != "motif" -a \ + "$TOOLKIT" != "x11" -a "$TOOLKIT" != "mac" -a \ + "$TOOLKIT" != "mgl" -a "$TOOLKIT" != "dfb" ; then + AC_MSG_ERROR([ + Unrecognized option value (allowed values: auto, gtk1, gtk2, msw, motif, x11, mac, mgl, dfb) + ]) + fi + + AC_MSG_RESULT([$TOOLKIT]) + fi + ]) + + dnl ****** IMPORTANT ******* + dnl Unlike for the UNICODE setting, you can build your program in + dnl shared mode against a static build of wxWidgets. Thus we have the + dnl following option which allows these mixtures. E.g. + dnl + dnl ./configure --disable-shared --with-wxshared + dnl + dnl will build your library in static mode against the first available + dnl shared build of wxWidgets. + dnl + dnl Note that's not possible to do the viceversa: + dnl + dnl ./configure --enable-shared --without-wxshared + dnl + dnl Doing so you would try to build your library in shared mode against a static + dnl build of wxWidgets. This is not possible (you would mix PIC and non PIC code) ! + dnl A check for this combination of options is in WX_DETECT_STANDARD_OPTION_VALUES + dnl (where we know what 'auto' should be expanded to). + dnl + dnl If you try to build something in ANSI mode against a UNICODE build + dnl of wxWidgets or in RELEASE mode against a DEBUG build of wxWidgets, + dnl then at best you'll get ton of linking errors ! + dnl ************************ + + ifelse(index([$1], [wxshared]), [-1],, + [ + WX_ARG_WITH_YESNOAUTO( + [wxshared], [WX_SHARED], + [Force building against a shared build of wxWidgets, even if --disable-shared is given], + [auto], [], [1]) + ]) + + dnl Just like for SHARED and WX_SHARED it may happen that some adventurous + dnl peoples will want to mix a wxWidgets release build with a debug build of + dnl his app/lib. So, we have both DEBUG and WX_DEBUG variables. + ifelse(index([$1], [wxdebug]), [-1],, + [ + WX_ARG_WITH_YESNOAUTO( + [wxdebug], [WX_DEBUG], + [Force building against a debug build of wxWidgets, even if --disable-debug is given], + [auto], [], [1]) + ]) + + dnl WX_ARG_WITH_YESNOAUTO cannot be used for --with-wxversion since it's an option + dnl which accepts the "auto|2.6|2.7|2.8|2.9|3.0" etc etc values + ifelse(index([$1], [wxversion]), [-1],, + [ + AC_ARG_WITH([wxversion], + AC_HELP_STRING([--with-wxversion], + [Build against a specific version of wxWidgets (default is auto)]), + [], [withval="auto"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-wxversion option]) + if test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + WX_RELEASE="auto" + else + + wx_requested_major_version=`echo $withval | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).*/\1/'` + wx_requested_minor_version=`echo $withval | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).*/\2/'` + + dnl both vars above must be exactly 1 digit + if test "${#wx_requested_major_version}" != "1" -o \ + "${#wx_requested_minor_version}" != "1" ; then + AC_MSG_ERROR([ + Unrecognized option value (allowed values: auto, 2.6, 2.7, 2.8, 2.9, 3.0) + ]) + fi + + WX_RELEASE="$wx_requested_major_version"".""$wx_requested_minor_version" + AC_MSG_RESULT([$WX_RELEASE]) + fi + ]) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] DEBUG: $DEBUG, WX_DEBUG: $WX_DEBUG" + echo "[[dbg]] UNICODE: $UNICODE, WX_UNICODE: $WX_UNICODE" + echo "[[dbg]] SHARED: $SHARED, WX_SHARED: $WX_SHARED" + echo "[[dbg]] TOOLKIT: $TOOLKIT, WX_TOOLKIT: $WX_TOOLKIT" + echo "[[dbg]] VERSION: $VERSION, WX_RELEASE: $WX_RELEASE" + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl +dnl Sets the WXCONFIG_FLAGS string using the SHARED,DEBUG,UNICODE variable values +dnl which are different from "auto". +dnl Thus this macro needs to be called only once all options have been set. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS], + [ + if test "$WX_SHARED" = "1" ; then + WXCONFIG_FLAGS="--static=no " + elif test "$WX_SHARED" = "0" ; then + WXCONFIG_FLAGS="--static=yes " + fi + + if test "$WX_DEBUG" = "1" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--debug=yes " + elif test "$WX_DEBUG" = "0" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--debug=no " + fi + + dnl The user should have set WX_UNICODE=UNICODE + if test "$WX_UNICODE" = "1" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--unicode=yes " + elif test "$WX_UNICODE" = "0" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--unicode=no " + fi + + if test "$TOOLKIT" != "auto" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--toolkit=$TOOLKIT " + fi + + if test "$WX_RELEASE" != "auto" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--version=$WX_RELEASE " + fi + + dnl strip out the last space of the string + WXCONFIG_FLAGS=${WXCONFIG_FLAGS% } + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] WXCONFIG_FLAGS: $WXCONFIG_FLAGS" + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl _WX_SELECTEDCONFIG_CHECKFOR([RESULTVAR], [STRING], [MSG] +dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +dnl Outputs the given MSG. Then searches the given STRING in the wxWidgets +dnl additional CPP flags and put the result of the search in WX_$RESULTVAR +dnl also adding the "yes" or "no" message result to MSG. +dnl --------------------------------------------------------------------------- +AC_DEFUN([_WX_SELECTEDCONFIG_CHECKFOR], + [ + if test "$$1" = "auto" ; then + + dnl The user does not have particular preferences for this option; + dnl so we will detect the wxWidgets relative build setting and use it + AC_MSG_CHECKING([$3]) + + dnl set WX_$1 variable to 1 if the $WX_SELECTEDCONFIG contains the $2 + dnl string or to 0 otherwise. + dnl NOTE: 'expr match STRING REGEXP' cannot be used since on Mac it + dnl doesn't work; we use 'expr STRING : REGEXP' instead + WX_$1=$(expr "$WX_SELECTEDCONFIG" : ".*$2.*") + + if test "$WX_$1" != "0"; then + WX_$1=1 + AC_MSG_RESULT([yes]) + ifelse([$4], , :, [$4]) + else + WX_$1=0 + AC_MSG_RESULT([no]) + ifelse([$5], , :, [$5]) + fi + else + + dnl Use the setting given by the user + WX_$1=$$1 + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl Detects the values of the following variables: +dnl 1) WX_RELEASE +dnl 2) WX_UNICODE +dnl 3) WX_DEBUG +dnl 4) WX_SHARED (and also WX_STATIC) +dnl 5) WX_PORT +dnl from the previously selected wxWidgets build; this macro in fact must be +dnl called *after* calling the WX_CONFIG_CHECK macro. +dnl +dnl Note that the WX_VERSION_MAJOR, WX_VERSION_MINOR symbols are already set +dnl by WX_CONFIG_CHECK macro +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], + [ + dnl IMPORTANT: WX_VERSION contains all three major.minor.micro digits, + dnl while WX_RELEASE only the major.minor ones. + WX_RELEASE="$WX_VERSION_MAJOR""$WX_VERSION_MINOR" + if test $WX_RELEASE -lt 26 ; then + + AC_MSG_ERROR([ + Cannot detect the wxWidgets configuration for the selected wxWidgets build + since its version is $WX_VERSION < 2.6.0; please install a newer + version of wxWidgets. + ]) + fi + + dnl The wx-config we are using understands the "--selected_config" + dnl option which returns an easy-parseable string ! + WX_SELECTEDCONFIG=$($WX_CONFIG_WITH_ARGS --selected_config) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] Using wx-config --selected-config" + echo "[[dbg]] WX_SELECTEDCONFIG: $WX_SELECTEDCONFIG" + fi + + + dnl we could test directly for WX_SHARED with a line like: + dnl _WX_SELECTEDCONFIG_CHECKFOR([SHARED], [shared], + dnl [if wxWidgets was built in SHARED mode]) + dnl but wx-config --selected-config DOES NOT outputs the 'shared' + dnl word when wx was built in shared mode; it rather outputs the + dnl 'static' word when built in static mode. + if test $WX_SHARED = "1"; then + STATIC=0 + elif test $WX_SHARED = "0"; then + STATIC=1 + elif test $WX_SHARED = "auto"; then + STATIC="auto" + fi + + dnl Now set the WX_UNICODE, WX_DEBUG, WX_STATIC variables + _WX_SELECTEDCONFIG_CHECKFOR([UNICODE], [unicode], + [if wxWidgets was built with UNICODE enabled]) + _WX_SELECTEDCONFIG_CHECKFOR([DEBUG], [debug], + [if wxWidgets was built in DEBUG mode]) + _WX_SELECTEDCONFIG_CHECKFOR([STATIC], [static], + [if wxWidgets was built in STATIC mode]) + + dnl init WX_SHARED from WX_STATIC + if test "$WX_STATIC" != "0"; then + WX_SHARED=0 + else + WX_SHARED=1 + fi + + AC_SUBST(WX_UNICODE) + AC_SUBST(WX_DEBUG) + AC_SUBST(WX_SHARED) + + dnl detect the WX_PORT to use + if test "$TOOLKIT" = "auto" ; then + + dnl The user does not have particular preferences for this option; + dnl so we will detect the wxWidgets relative build setting and use it + AC_MSG_CHECKING([which wxWidgets toolkit was selected]) + + WX_GTKPORT1=$(expr "$WX_SELECTEDCONFIG" : ".*gtk1.*") + WX_GTKPORT2=$(expr "$WX_SELECTEDCONFIG" : ".*gtk2.*") + WX_MSWPORT=$(expr "$WX_SELECTEDCONFIG" : ".*msw.*") + WX_MOTIFPORT=$(expr "$WX_SELECTEDCONFIG" : ".*motif.*") + WX_OSXCOCOAPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_cocoa.*") + WX_OSXCARBONPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_carbon.*") + WX_X11PORT=$(expr "$WX_SELECTEDCONFIG" : ".*x11.*") + WX_MGLPORT=$(expr "$WX_SELECTEDCONFIG" : ".*mgl.*") + WX_DFBPORT=$(expr "$WX_SELECTEDCONFIG" : ".*dfb.*") + + WX_PORT="unknown" + if test "$WX_GTKPORT1" != "0"; then WX_PORT="gtk1"; fi + if test "$WX_GTKPORT2" != "0"; then WX_PORT="gtk2"; fi + if test "$WX_MSWPORT" != "0"; then WX_PORT="msw"; fi + if test "$WX_MOTIFPORT" != "0"; then WX_PORT="motif"; fi + if test "$WX_OSXCOCOAPORT" != "0"; then WX_PORT="osx_cocoa"; fi + if test "$WX_OSXCARBONPORT" != "0"; then WX_PORT="osx_carbon"; fi + if test "$WX_X11PORT" != "0"; then WX_PORT="x11"; fi + if test "$WX_MGLPORT" != "0"; then WX_PORT="mgl"; fi + if test "$WX_DFBPORT" != "0"; then WX_PORT="dfb"; fi + + dnl NOTE: backward-compatible check for wx2.8; in wx2.9 the mac + dnl ports are called 'osx_cocoa' and 'osx_carbon' (see above) + WX_MACPORT=$(expr "$WX_SELECTEDCONFIG" : ".*mac.*") + if test "$WX_MACPORT" != "0"; then WX_PORT="mac"; fi + + dnl check at least one of the WX_*PORT has been set ! + + if test "$WX_PORT" = "unknown" ; then + AC_MSG_ERROR([ + Cannot detect the currently installed wxWidgets port ! + Please check your 'wx-config --cxxflags'... + ]) + fi + + AC_MSG_RESULT([$WX_PORT]) + else + + dnl Use the setting given by the user + if test -z "$TOOLKIT" ; then + WX_PORT=$TOOLKIT + else + dnl try with PORT + WX_PORT=$PORT + fi + fi + + AC_SUBST(WX_PORT) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] Values of all WX_* options after final detection:" + echo "[[dbg]] WX_DEBUG: $WX_DEBUG" + echo "[[dbg]] WX_UNICODE: $WX_UNICODE" + echo "[[dbg]] WX_SHARED: $WX_SHARED" + echo "[[dbg]] WX_RELEASE: $WX_RELEASE" + echo "[[dbg]] WX_PORT: $WX_PORT" + fi + + dnl Avoid problem described in the WX_STANDARD_OPTIONS which happens when + dnl the user gives the options: + dnl ./configure --enable-shared --without-wxshared + dnl or just do + dnl ./configure --enable-shared + dnl but there is only a static build of wxWidgets available. + if test "$WX_SHARED" = "0" -a "$SHARED" = "1"; then + AC_MSG_ERROR([ + Cannot build shared library against a static build of wxWidgets ! + This error happens because the wxWidgets build which was selected + has been detected as static while you asked to build $PACKAGE_NAME + as shared library and this is not possible. + Use the '--disable-shared' option to build $PACKAGE_NAME + as static library or '--with-wxshared' to use wxWidgets as shared library. + ]) + fi + + dnl now we can finally update the DEBUG,UNICODE,SHARED options + dnl to their final values if they were set to 'auto' + if test "$DEBUG" = "auto"; then + DEBUG=$WX_DEBUG + fi + if test "$UNICODE" = "auto"; then + UNICODE=$WX_UNICODE + fi + if test "$SHARED" = "auto"; then + SHARED=$WX_SHARED + fi + if test "$TOOLKIT" = "auto"; then + TOOLKIT=$WX_PORT + fi + + dnl in case the user needs a BUILD=debug/release var... + if test "$DEBUG" = "1"; then + BUILD="debug" + elif test "$DEBUG" = "0" -o "$DEBUG" = ""; then + BUILD="release" + fi + + dnl respect the DEBUG variable adding the optimize/debug flags + dnl NOTE: the CXXFLAGS are merged together with the CPPFLAGS so we + dnl don't need to set them, too + if test "$DEBUG" = "1"; then + CXXFLAGS="$CXXFLAGS -g -O0" + CFLAGS="$CFLAGS -g -O0" + else + CXXFLAGS="$CXXFLAGS -O2" + CFLAGS="$CFLAGS -O2" + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_BOOLOPT_SUMMARY([name of the boolean variable to show summary for], +dnl [what to print when var is 1], +dnl [what to print when var is 0]) +dnl +dnl Prints $2 when variable $1 == 1 and prints $3 when variable $1 == 0. +dnl This macro mainly exists just to make configure.ac scripts more readable. +dnl +dnl NOTE: you need to use the [" my message"] syntax for 2nd and 3rd arguments +dnl if you want that m4 avoid to throw away the spaces prefixed to the +dnl argument value. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_BOOLOPT_SUMMARY], + [ + if test "x$$1" = "x1" ; then + echo $2 + elif test "x$$1" = "x0" ; then + echo $3 + else + echo "$1 is $$1" + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl +dnl Shows a summary message to the user about the WX_* variable contents. +dnl This macro is used typically at the end of the configure script. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG], + [ + echo + echo " The wxWidgets build which will be used by $PACKAGE_NAME $PACKAGE_VERSION" + echo " has the following settings:" + WX_BOOLOPT_SUMMARY([WX_DEBUG], [" - DEBUG build"], [" - RELEASE build"]) + WX_BOOLOPT_SUMMARY([WX_UNICODE], [" - UNICODE mode"], [" - ANSI mode"]) + WX_BOOLOPT_SUMMARY([WX_SHARED], [" - SHARED mode"], [" - STATIC mode"]) + echo " - VERSION: $WX_VERSION" + echo " - PORT: $WX_PORT" + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN, WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl +dnl Like WX_STANDARD_OPTIONS_SUMMARY_MSG macro but these two macros also gives info +dnl about the configuration of the package which used the wxpresets. +dnl +dnl Typical usage: +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN +dnl echo " - Package setting 1: $SETTING1" +dnl echo " - Package setting 2: $SETTING1" +dnl ... +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN], + [ + echo + echo " ----------------------------------------------------------------" + echo " Configuration for $PACKAGE_NAME $PACKAGE_VERSION successfully completed." + echo " Summary of main configuration settings for $PACKAGE_NAME:" + WX_BOOLOPT_SUMMARY([DEBUG], [" - DEBUG build"], [" - RELEASE build"]) + WX_BOOLOPT_SUMMARY([UNICODE], [" - UNICODE mode"], [" - ANSI mode"]) + WX_BOOLOPT_SUMMARY([SHARED], [" - SHARED mode"], [" - STATIC mode"]) + ]) + +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG_END], + [ + WX_STANDARD_OPTIONS_SUMMARY_MSG + echo + echo " Now, just run make." + echo " ----------------------------------------------------------------" + echo + ]) + + +dnl --------------------------------------------------------------------------- +dnl Deprecated macro wrappers +dnl --------------------------------------------------------------------------- + +AC_DEFUN([AM_OPTIONS_WXCONFIG], [WX_CONFIG_OPTIONS]) +AC_DEFUN([AM_PATH_WXCONFIG], [ + WX_CONFIG_CHECK([$1],[$2],[$3],[$4],[$5]) +]) +AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 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. + +# serial 1 + +# 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. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.2], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.2])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 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. + +# serial 1 + +# 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. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# 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. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +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])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 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. + +# serial 12 + +# 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], UPC, [depcc="$UPC" am_compiler_list=], + [$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'. + rm -rf conftest.dir + 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 + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + 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 + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # 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. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # 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. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + 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 + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + 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], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# 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. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + 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. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. 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 " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# 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. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 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. + +# serial 16 + +# 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. + +# 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_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +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 +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])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) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# 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 +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_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 +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# 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], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 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. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 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. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 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. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +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 +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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. + +# serial 6 + +# 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 +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# 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 +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 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. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 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. + +# serial 5 + +# _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], +[m4_foreach_w([_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. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# 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. + +# serial 5 + +# 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 +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# 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)]) + +# Copyright (C) 2001, 2003, 2005, 2011 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. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# 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="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 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. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 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. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..8152efd --- /dev/null +++ b/config.guess @@ -0,0 +1,1522 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-11-11' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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 (context +# diff format) to and include a 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. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +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, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + 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 ; set_cc_for_build= ;' + +# 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 ;; + sh5el) machine=sh5le-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 -q __ELF__ + 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 + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # 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 ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # 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. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + 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 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + 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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + 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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # 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 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + 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 -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + 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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + 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 ;; + *: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 + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + 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 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 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 -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 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 -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + 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 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + 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 i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + 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 -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo hexagon-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + 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 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + 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 ;; + 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 ;; + 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 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + 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 ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + 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 ;; + 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 ;; + 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 i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*: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 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + 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 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *: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 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *: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 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +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\n"); 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 -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# 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 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + 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/config.h.in b/config.h.in new file mode 100644 index 0000000..dd3b02c --- /dev/null +++ b/config.h.in @@ -0,0 +1,25 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* 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 home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..e76eaf4 --- /dev/null +++ b/config.sub @@ -0,0 +1,1771 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-11-11' + +# 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, 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 GNU 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. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# 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, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # 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 ;; + + * ) + 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* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | 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 | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -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 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # 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-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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 + ;; + abacus) + basic_machine=abacus-unknown + ;; + 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 + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + 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 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + 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 + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + 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 + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + 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 + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + 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 + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-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-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + 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 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + 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 + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + 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 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + 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 + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + 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 + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-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 + ;; + mmix) + basic_machine=mmix-knuth + ;; + 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 + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + 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. + -auroraux) + os=-auroraux + ;; + -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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -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* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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 + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -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 + ;; + -tpf*) + os=-tpf + ;; + -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 + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # 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 + ;; + mep-*) + os=-elf + ;; + 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 + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-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 + ;; + -cnk*|-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 + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -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 + +# 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/configure b/configure new file mode 100644 index 0000000..8e16e5e --- /dev/null +++ b/configure @@ -0,0 +1,6665 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for ShapeFusion 0.5. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +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 +IFS=$as_save_IFS + + ;; +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 + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: http://sourceforge.net/bugs/?group_id=1997 about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; 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 + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# 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 + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval 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="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ShapeFusion' +PACKAGE_TARNAME='ShapeFusion' +PACKAGE_VERSION='0.5' +PACKAGE_STRING='ShapeFusion 0.5' +PACKAGE_BUGREPORT='http://sourceforge.net/bugs/?group_id=1997' +PACKAGE_URL='' + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +MAKE_WINDOWS_FALSE +MAKE_WINDOWS_TRUE +SNDFILE_LIBS +SNDFILE_CFLAGS +PKG_CONFIG +WX_VERSION_MICRO +WX_VERSION_MINOR +WX_VERSION_MAJOR +WX_RESCOMP +WX_VERSION +WX_LIBS_STATIC +WX_LIBS +WX_CXXFLAGS_ONLY +WX_CFLAGS_ONLY +WX_CXXFLAGS +WX_CFLAGS +WX_CPPFLAGS +WX_CONFIG_PATH +WINDRES +RANLIB +CXXCPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +with_wxdir +with_wx_config +with_wx_prefix +with_wx_exec_prefix +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +CXXCPP +PKG_CONFIG +SNDFILE_CFLAGS +SNDFILE_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# 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. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +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 + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -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) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$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 ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$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 ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + 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 ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=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 ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_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'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +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 + $as_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 + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# 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 the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + 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 + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# 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 ShapeFusion 0.5 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 \`..'] + +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] + --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] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ShapeFusion] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_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 + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ShapeFusion 0.5:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-wxdir=PATH Use uninstalled version of wxWidgets in PATH + --with-wx-config=CONFIG wx-config script to use (optional) + --with-wx-prefix=PREFIX Prefix where wxWidgets is installed (optional) + --with-wx-exec-prefix=PREFIX + Exec prefix where wxWidgets is installed (optional) + +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 + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + PKG_CONFIG path to pkg-config utility + SNDFILE_CFLAGS + C compiler flags for SNDFILE, overriding pkg-config + SNDFILE_LIBS + linker flags for SNDFILE, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested 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 + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ShapeFusion configure 0.5 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 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 +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ShapeFusion $as_me 0.5, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +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` +/usr/bin/hostinfo = `(/usr/bin/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=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&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. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# 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: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > 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 + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + 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. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_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 $ac_precious_vars; 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,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_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 + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_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. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +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 "$srcdir" "$srcdir/.." "$srcdir/../.."; 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 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +am__api_version='1.11' + +# 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" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&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/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +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. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$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' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# 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". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "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 $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +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='ShapeFusion' + VERSION='0.5' + + +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"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_config_headers="$ac_config_headers config.h" + + +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# 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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; 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 | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end 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; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +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 +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +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 +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-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='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&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'. + rm -rf conftest.dir + 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 + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + 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 + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # 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. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # 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. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + 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 + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&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. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$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. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +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_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +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 + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&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'. + rm -rf conftest.dir + 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 + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # 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. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # 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. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + 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 + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +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 + + +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +case $target in +*-*-mingw32*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WINDRES"; then + ac_cv_prog_WINDRES="$WINDRES" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_WINDRES="${ac_tool_prefix}windres" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +WINDRES=$ac_cv_prog_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_WINDRES"; then + ac_ct_WINDRES=$WINDRES + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_WINDRES"; then + ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_WINDRES="windres" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES +if test -n "$ac_ct_WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 +$as_echo "$ac_ct_WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_WINDRES" = x; then + WINDRES=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + WINDRES=$ac_ct_WINDRES + fi +else + WINDRES="$ac_cv_prog_WINDRES" +fi + + ;; +*-*-netbsd*) + CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + ;; +*) + ;; +esac + + + +# Check whether --with-wxdir was given. +if test "${with_wxdir+set}" = set; then : + withval=$with_wxdir; wx_config_name="$withval/wx-config" + wx_config_args="--inplace" +fi + + +# Check whether --with-wx-config was given. +if test "${with_wx_config+set}" = set; then : + withval=$with_wx_config; wx_config_name="$withval" +fi + + +# Check whether --with-wx-prefix was given. +if test "${with_wx_prefix+set}" = set; then : + withval=$with_wx_prefix; wx_config_prefix="$withval" +else + wx_config_prefix="" +fi + + +# Check whether --with-wx-exec-prefix was given. +if test "${with_wx_exec_prefix+set}" = set; then : + withval=$with_wx_exec_prefix; wx_config_exec_prefix="$withval" +else + wx_config_exec_prefix="" +fi + + +reqwx=2.8.0 +case $target in +*-*-mingw32*) + + + if test x${WX_CONFIG_NAME+set} != xset ; then + WX_CONFIG_NAME=wx-config + fi + + if test "x$wx_config_name" != x ; then + WX_CONFIG_NAME="$wx_config_name" + fi + + if test x$wx_config_exec_prefix != x ; then + wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix" + WX_LOOKUP_PATH="$wx_config_exec_prefix/bin" + fi + if test x$wx_config_prefix != x ; then + wx_config_args="$wx_config_args --prefix=$wx_config_prefix" + WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin" + fi + if test "$cross_compiling" = "yes"; then + wx_config_args="$wx_config_args --host=$host_alias" + fi + + if test -x "$WX_CONFIG_NAME" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wx-config" >&5 +$as_echo_n "checking for wx-config... " >&6; } + WX_CONFIG_PATH="$WX_CONFIG_NAME" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } + else + # Extract the first word of "$WX_CONFIG_NAME", so it can be a program name with args. +set dummy $WX_CONFIG_NAME; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WX_CONFIG_PATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WX_CONFIG_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_WX_CONFIG_PATH="$WX_CONFIG_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy=""$WX_LOOKUP_PATH:$PATH"" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_WX_CONFIG_PATH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WX_CONFIG_PATH" && ac_cv_path_WX_CONFIG_PATH="no" + ;; +esac +fi +WX_CONFIG_PATH=$ac_cv_path_WX_CONFIG_PATH +if test -n "$WX_CONFIG_PATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "$WX_CONFIG_PATH" != "no" ; then + WX_VERSION="" + + min_wx_version=$reqwx + if test -z "--unicode=no" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version... " >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version (--unicode=no)" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version (--unicode=no)... " >&6; } + fi + + WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args --unicode=no" + + WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` + wx_config_major_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_config_minor_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_config_micro_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + wx_requested_major_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_requested_minor_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_requested_micro_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt $wx_requested_major_version; then + wx_ver_ok=yes + else + if test $wx_config_major_version -eq $wx_requested_major_version; then + if test $wx_config_minor_version -gt $wx_requested_minor_version; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq $wx_requested_minor_version; then + if test $wx_config_micro_version -ge $wx_requested_micro_version; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi + + + if test -n "$wx_ver_ok"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $WX_VERSION)" >&5 +$as_echo "yes (version $WX_VERSION)" >&6; } + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs ` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets static library" >&5 +$as_echo_n "checking for wxWidgets static library... " >&6; } + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + + wx_has_cppflags="" + if test $wx_config_major_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_minor_version -eq 2; then + if test $wx_config_micro_version -ge 6; then + wx_has_cppflags=yes + fi + fi + fi + fi + fi + + wx_has_rescomp="" + if test $wx_config_major_version -gt 2; then + wx_has_rescomp=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -ge 7; then + wx_has_rescomp=yes + fi + fi + fi + if test "x$wx_has_rescomp" = x ; then + WX_RESCOMP= + else + WX_RESCOMP=`$WX_CONFIG_WITH_ARGS --rescomp` + fi + + if test "x$wx_has_cppflags" = x ; then + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + WX_CPPFLAGS=$WX_CFLAGS + WX_CXXFLAGS=$WX_CFLAGS + + WX_CFLAGS_ONLY=$WX_CFLAGS + WX_CXXFLAGS_ONLY=$WX_CFLAGS + else + WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags ` + WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags ` + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + + WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"` + WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"` + fi + + wxWidgets=1 + + else + + if test "x$WX_VERSION" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (version $WX_VERSION is not new enough)" >&5 +$as_echo "no (version $WX_VERSION is not new enough)" >&6; } + fi + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + if test ! -z "--unicode=no"; then + + wx_error_message=" + The configuration you asked for $PACKAGE_NAME requires a wxWidgets + build with the following settings: + --unicode=no + but such build is not available. + + To see the wxWidgets builds available on this system, please use + 'wx-config --list' command. To use the default build, returned by + 'wx-config --selected-config', use the options with their 'auto' + default values." + + fi + + wx_error_message=" + The requested wxWidgets build couldn't be found. + $wx_error_message + + If you still get this error, then check that 'wx-config' is + in path, the directory where wxWidgets libraries are installed + (returned by 'wx-config --libs' command) is in LD_LIBRARY_PATH + or equivalent variable and wxWidgets version is $reqwx or above." + + as_fn_error $? "$wx_error_message" "$LINENO" 5 + + fi + else + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + : + + fi + + + + + + + + + + + + WX_VERSION_MAJOR="$wx_config_major_version" + WX_VERSION_MINOR="$wx_config_minor_version" + WX_VERSION_MICRO="$wx_config_micro_version" + + + + + + ;; +*) + + + if test x${WX_CONFIG_NAME+set} != xset ; then + WX_CONFIG_NAME=wx-config + fi + + if test "x$wx_config_name" != x ; then + WX_CONFIG_NAME="$wx_config_name" + fi + + if test x$wx_config_exec_prefix != x ; then + wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix" + WX_LOOKUP_PATH="$wx_config_exec_prefix/bin" + fi + if test x$wx_config_prefix != x ; then + wx_config_args="$wx_config_args --prefix=$wx_config_prefix" + WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin" + fi + if test "$cross_compiling" = "yes"; then + wx_config_args="$wx_config_args --host=$host_alias" + fi + + if test -x "$WX_CONFIG_NAME" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wx-config" >&5 +$as_echo_n "checking for wx-config... " >&6; } + WX_CONFIG_PATH="$WX_CONFIG_NAME" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } + else + # Extract the first word of "$WX_CONFIG_NAME", so it can be a program name with args. +set dummy $WX_CONFIG_NAME; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WX_CONFIG_PATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WX_CONFIG_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_WX_CONFIG_PATH="$WX_CONFIG_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy=""$WX_LOOKUP_PATH:$PATH"" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_WX_CONFIG_PATH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WX_CONFIG_PATH" && ac_cv_path_WX_CONFIG_PATH="no" + ;; +esac +fi +WX_CONFIG_PATH=$ac_cv_path_WX_CONFIG_PATH +if test -n "$WX_CONFIG_PATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "$WX_CONFIG_PATH" != "no" ; then + WX_VERSION="" + + min_wx_version=$reqwx + if test -z "" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version... " >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version ()" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version ()... " >&6; } + fi + + WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args " + + WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` + wx_config_major_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_config_minor_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_config_micro_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + wx_requested_major_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_requested_minor_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_requested_micro_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt $wx_requested_major_version; then + wx_ver_ok=yes + else + if test $wx_config_major_version -eq $wx_requested_major_version; then + if test $wx_config_minor_version -gt $wx_requested_minor_version; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq $wx_requested_minor_version; then + if test $wx_config_micro_version -ge $wx_requested_micro_version; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi + + + if test -n "$wx_ver_ok"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $WX_VERSION)" >&5 +$as_echo "yes (version $WX_VERSION)" >&6; } + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs ` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets static library" >&5 +$as_echo_n "checking for wxWidgets static library... " >&6; } + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + + wx_has_cppflags="" + if test $wx_config_major_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_minor_version -eq 2; then + if test $wx_config_micro_version -ge 6; then + wx_has_cppflags=yes + fi + fi + fi + fi + fi + + wx_has_rescomp="" + if test $wx_config_major_version -gt 2; then + wx_has_rescomp=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -ge 7; then + wx_has_rescomp=yes + fi + fi + fi + if test "x$wx_has_rescomp" = x ; then + WX_RESCOMP= + else + WX_RESCOMP=`$WX_CONFIG_WITH_ARGS --rescomp` + fi + + if test "x$wx_has_cppflags" = x ; then + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + WX_CPPFLAGS=$WX_CFLAGS + WX_CXXFLAGS=$WX_CFLAGS + + WX_CFLAGS_ONLY=$WX_CFLAGS + WX_CXXFLAGS_ONLY=$WX_CFLAGS + else + WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags ` + WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags ` + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + + WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"` + WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"` + fi + + wxWidgets=1 + + else + + if test "x$WX_VERSION" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (version $WX_VERSION is not new enough)" >&5 +$as_echo "no (version $WX_VERSION is not new enough)" >&6; } + fi + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + if test ! -z ""; then + + wx_error_message=" + The configuration you asked for $PACKAGE_NAME requires a wxWidgets + build with the following settings: + + but such build is not available. + + To see the wxWidgets builds available on this system, please use + 'wx-config --list' command. To use the default build, returned by + 'wx-config --selected-config', use the options with their 'auto' + default values." + + fi + + wx_error_message=" + The requested wxWidgets build couldn't be found. + $wx_error_message + + If you still get this error, then check that 'wx-config' is + in path, the directory where wxWidgets libraries are installed + (returned by 'wx-config --libs' command) is in LD_LIBRARY_PATH + or equivalent variable and wxWidgets version is $reqwx or above." + + as_fn_error $? "$wx_error_message" "$LINENO" 5 + + fi + else + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + : + + fi + + + + + + + + + + + + WX_VERSION_MAJOR="$wx_config_major_version" + WX_VERSION_MINOR="$wx_config_minor_version" + WX_VERSION_MICRO="$wx_config_micro_version" + + + + + + ;; +esac +if test "$wxWidgets" != 1; then + as_fn_error $? " + wxWidgets must be installed on your system. + + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + " "$LINENO" 5 +fi + +CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +LIBS="$LIBS $WX_LIBS" + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SNDFILE" >&5 +$as_echo_n "checking for SNDFILE... " >&6; } + +if test -n "$PKG_CONFIG"; then + if test -n "$SNDFILE_CFLAGS"; then + pkg_cv_SNDFILE_CFLAGS="$SNDFILE_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sndfile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SNDFILE_CFLAGS=`$PKG_CONFIG --cflags "sndfile" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$SNDFILE_LIBS"; then + pkg_cv_SNDFILE_LIBS="$SNDFILE_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sndfile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SNDFILE_LIBS=`$PKG_CONFIG --libs "sndfile" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SNDFILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "sndfile"` + else + SNDFILE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "sndfile"` + fi + # Put the nasty error message in config.log where it belongs + echo "$SNDFILE_PKG_ERRORS" >&5 + + as_fn_error $? "ShapeFusion requires libsndfile" "$LINENO" 5 +elif test $pkg_failed = untried; then + as_fn_error $? "ShapeFusion requires libsndfile" "$LINENO" 5 +else + SNDFILE_CFLAGS=$pkg_cv_SNDFILE_CFLAGS + SNDFILE_LIBS=$pkg_cv_SNDFILE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + CPPFLAGS="$SNDFILE_CFLAGS $CPPFLAGS" + LIBS="$SNDFILE_LIBS $LIBS" +fi + + +case $target in +*-*-mingw32*) + make_windows=true + ;; +*) + make_windows=false ;; +esac + if test x$make_windows = xtrue; then + MAKE_WINDOWS_TRUE= + MAKE_WINDOWS_FALSE='#' +else + MAKE_WINDOWS_TRUE='#' + MAKE_WINDOWS_FALSE= +fi + + +ac_config_files="$ac_config_files Makefile Physics/Makefile Shapes/Makefile Sounds/Makefile" + +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, we kill variables containing newlines. +# 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. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}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 "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + 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}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAKE_WINDOWS_TRUE}" && test -z "${MAKE_WINDOWS_FALSE}"; then + as_fn_error $? "conditional \"MAKE_WINDOWS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $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 +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +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 +IFS=$as_save_IFS + + ;; +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 + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; 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 + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# 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 + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval 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="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ShapeFusion $as_me 0.5, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -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_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ShapeFusion config.status 0.5 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +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=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "Physics/Makefile") CONFIG_FILES="$CONFIG_FILES Physics/Makefile" ;; + "Shapes/Makefile") CONFIG_FILES="$CONFIG_FILES Shapes/Makefile" ;; + "Sounds/Makefile") CONFIG_FILES="$CONFIG_FILES Sounds/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + 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 + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #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. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # 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. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;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&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + 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. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_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 + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. 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 " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# 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=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || 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 || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo "Configuration done. Now type \"make\"." diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..a827f3b --- /dev/null +++ b/configure.ac @@ -0,0 +1,91 @@ +dnl Process this file with autoconf to produce a configure script. +dnl Written in 2000 by Christian Bauer + +AC_INIT([ShapeFusion], [0.5], [http://sourceforge.net/bugs/?group_id=1997], [ShapeFusion]) +AC_PREREQ(2.52) + +dnl Detect the canonical host and target build environment. +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +dnl Init automake. +AM_INIT_AUTOMAKE +AM_CONFIG_HEADER(config.h) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AC_PROG_CXX +AC_PROG_CXXCPP +AC_PROG_INSTALL +AC_PROG_RANLIB + +dnl some platform specific stuff +case $target in +*-*-mingw32*) + AC_CHECK_TOOL(WINDRES, windres, :) + ;; +*-*-netbsd*) + CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + ;; +*) + ;; +esac + +dnl wxWidgets +AM_OPTIONS_WXCONFIG +reqwx=2.8.0 +case $target in +*-*-mingw32*) + AM_PATH_WXCONFIG($reqwx, wxWidgets=1, , , [--unicode=no]) + ;; +*) + AM_PATH_WXCONFIG($reqwx, wxWidgets=1) + ;; +esac +if test "$wxWidgets" != 1; then + AC_MSG_ERROR([ + wxWidgets must be installed on your system. + + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + ]) +fi + +CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +LIBS="$LIBS $WX_LIBS" + +PKG_CHECK_MODULES([SNDFILE], [sndfile], [ + CPPFLAGS="$SNDFILE_CFLAGS $CPPFLAGS" + LIBS="$SNDFILE_LIBS $LIBS"], AC_ERROR([ShapeFusion requires libsndfile])) + +dnl Check for libsndfile +dnl AC_CHECK_HEADER(sndfile.h, , AC_ERROR([ShapeFusion requires libsndfile])) +dnl AC_CHECK_LIB(sndfile, sf_open, [LIBS="-lvorbis -lvorbisenc -lvorbisfile -logg -lsndfile $LIBS"], AC_ERROR([ShapeFusion requires libsndfile]), [-lvorbis -lvorbisenc -lvorbisfile -logg -lFLAC -lsndfile]) + +dnl add some windows goodies +case $target in +*-*-mingw32*) + make_windows=true + ;; +*) + make_windows=false ;; +esac +AM_CONDITIONAL(MAKE_WINDOWS, test x$make_windows = xtrue) + +dnl Generate Makefiles. +AC_CONFIG_FILES([ +Makefile +Physics/Makefile +Shapes/Makefile +Sounds/Makefile +]) +AC_OUTPUT + +dnl Print summary. +echo "Configuration done. Now type \"make\"." diff --git a/depcomp b/depcomp new file mode 100644 index 0000000..bd0ac08 --- /dev/null +++ b/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 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, see . + +# 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 . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +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 + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +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 + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +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. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + 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. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## 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 "s|.*$object$||" -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. In older versions, 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. + # Version 6 uses the directory in both cases. + 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$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + 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,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$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" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + 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$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +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 + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # 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 + ;; + +#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 preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--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 + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $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 $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$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 preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--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 -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [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 preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # 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 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/install-sh b/install-sh new file mode 100644 index 0000000..a9244eb --- /dev/null +++ b/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# 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 +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/missing b/missing new file mode 100644 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 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, see . + +# 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=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# 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 + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -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' + autom4te touch the output file, or create a stub one + 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] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + 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' $msg. 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 test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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 test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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 "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. 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." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # 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 is $msg. + 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 prerequisites 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 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: -- 2.11.0